Turn on the Duo flows

Takes about 15 minutes

Three GitLab Duo Agent Platform flows do the agent work. They propose; a person decides the merge: the tester's Verify for a UI fix, or a developer merging the store and size fixes.

The three flows

FlowStarts onWhat it does
Bugoro QA Fix
flows/qa-fix.yml
Assign and MentionTriages a tester's report and fixes it in an MR, asks one question, marks a duplicate or an already fixed bug, or hands it to a developer.
Bugoro Release Readiness
flows/release-readiness.yml
Merge request: Marked ready, and MentionOn a release MR, explains the store-check findings in plain language and opens a separate MR with only the safe fixes.
Bugoro Size Fix
flows/size-fix.yml
MentionUnder the size note, opens a separate MR that deletes resources it can prove are unused and turns on R8 and resource shrinking.

Create and enable each flow

You need the Maintainer or Owner role. Repeat for each flow.

  1. In your project, go to AI > Flows > New flow. Set the display name from the table, visibility Public, configuration Flow, and paste the flow's YAML from the default branch exactly.

  2. Go to Explore > AI Catalog > Flows, open the flow, click Enable and pick your project. Add only the triggers in the table. Release readiness leaves out Created on purpose: a new MR has no pipeline result yet.

  3. GitLab adds a service account, ai-<flow>-<group>, as Developer. Find its username and ID under Manage > Members.

  4. Tell the Hub the qa-fix account, in the Hub's container. The Hub knows the agent's merge requests by this account: without it, every fix counts as a developer's and never merges automatically.

    GITLAB_PROJECT_ID=<project-id> FLOW_ACCOUNT_USERNAME=<qa-fix-service-account> FLOW_ACCOUNT_ID=<its-user-id> \
      bin/rails bugoro:connect_project
  5. Give store-check the release-readiness account, so its note says whom to mention:

    include:
      - component: $CI_SERVER_FQDN/<group>/<project>/store-check@<version>
        inputs:
          readiness_account: <release-readiness-service-account>
  6. Create the labels bugoro-store and bugoro-size for the fix MRs, and keep .gitlab/duo/agent-config.yml on the default branch: GitLab reads it only there.

Why issues are filed as the tester

Bots, service accounts and flows can't fire flow triggers. So the Hub files each report as a GitLab issue as the tester, with their own GitLab token, and assigns it to the qa-fix account. That is a person's action, so the Assign trigger starts the flow.

Under composite identity, a flow can do only what both its account and the person who triggered it may do. Testers who start fixes need the Developer role.

A developer's fix comes back too

When the flow hands a report to a developer, the loop still ends on the tester's phone. Any open merge request from a branch of the project (not a fork) that closes the report's issue (Closes #<iid> in its description or title) links to the report, whoever wrote it.

  • Its build comes back to the tester as Fix ready, like the agent's.
  • Verify approves it as the tester, if they may, pinned to the commit of the build they installed. Bugoro never turns on auto merge for a developer's merge request: its author and reviewers merge it.
  • Still broken comments on the merge request, mentioning its author, with the tester's note. It never restarts the flow and uses none of the agent's attempts.

Guardrails

  • Path allowlist. The qa-fix agent changes only the reported screen's UI code under sample-app/src/. The Hub checks every agent MR's diff against the project's fix_paths setting (default sample-app/src/), also rejects manifests and build files, and never merges such an MR automatically.
  • Only the agent's fix merges itself. The Hub knows the agent's MR by its author, the flow's service account, never by a label or a branch name. It turns on auto merge only after the tester's Verify, only for that MR, and pinned to the commit the tester ran.
  • Attempt cap. 2 agent attempts and 2 questions per issue, and 2 fix runs per MR for the store and size flows.
  • Daily budget. By default the Hub starts the flow for at most 20 new reports per project a day (UTC). The rest wait as qa::queued and start, oldest first, when there is room.
  • Handoff. When a fix isn't safe or the caps are reached, the flow writes a note a developer can act on (what, where, the probable cause, why it stopped, the next step) and sets qa::needs-dev.
  • Untrusted text. Issue text, notes and file contents are treated as data, never as instructions.
  • A watchdog. The Hub marks a flow that errors or stalls for 20 minutes as failed.