Add .gitlab/duo/agent-config.yml for DAP

What does this MR do and why?

Implements Add `.gitlab/duo/agent-config.yml` for Duo Agen... (#593976)

Re-lands the .gitlab/duo/agent-config.yml that was reverted in !230068 (merged). The previous MR failed production flows with shallow roots are not allowed to be updated because it cross-fetched the CI branch from $CI_PROJECT_DIR (a shallow clone) into the image's own shallow GDK clone, but git refuses to graft shallow boundaries onto each other.

This version fetches directly from $CI_REPOSITORY_URL (a full remote) instead, avoiding the cross-shallow graft entirely.

A HEAD-matches-workload-ref assertion is kept FATAL because silent wrong-ref was the exact failure shape that caused the revert. Every other step (gdk start, bundle, yarn, db:schema:load/migrate, post-install tooling) warns on failure rather than blocking as this script is assist for the agent, not the gate. The MR's real CI pipeline is the quality gate.

Feature Flag This MR adds the new proposed Duo agent config as a candidate file, .gitlab/duo/agent-config-candidate.yml, behind a feature flag named dap_agent_config_candidate. The existing .gitlab/duo/agent-config.yml stays unchanged, so behaviour does not change on merge. A follow-up MR will make the candidate file the default after verification.

References

How to set up and validate locally

This section has two parts: a happy-path validation (does the script work end-to-end on a normal agent flow?) and a regression validation (does this MR specifically fix the shallow-graft error from !230068 (merged)).

  • A local GDK instance configured for Duo Agent Platform flows. Follow doc/howto/ai/duo_agent_platform.md in the GDK repository.
  • A clone of your GDK's gitlab-org/gitlab project at /tmp/gitlab (or equivalent) with its origin set to http://gdk.test:3000/gitlab-org/gitlab.
  • This MR's .gitlab/duo/agent-config.yml present on your GDK's master. The agent platform reads the setup script from the default branch only, so any change under test has to land on master before triggering a flow.
Happy Path
  • Create an issue on your GDK test project (see sample issues below) and use the Generate MR with Duo option
  • Observe the setup phase in the job logs: look for GDK services starting, sync hooks: ✔️, then the agent running your task
Verification that shallow root error removed

Verification

Build a divergent workload branch

cd /tmp/
git clone http://gdk.test:3000/gitlab-org/gitlab
cd /tmp/gitlab

git checkout -b divergence-test

MARKER="$(date +%s)-$(uuidgen | head -c 8)"
echo "$MARKER" > marker.txt
git add marker.txt
rm app/controllers/whats_new_controller.rb

git add -A

git commit -m "add marker $MARKER, delete whats_new_controller"

git push origin divergence-test

Create an MR for the branch on gdk.test

Open http://gdk.test:3000/gitlab-org/gitlab and create an MR from divergence-test into master. The MR does not need to be mergeable — only the branch needs to exist as an addressable workload.

Trigger a Duo flow against the MR

From the MR page trigger one of the flows that operates on an existing MR's branch e.g. Code review/v1 by assigning @GitLabDuo as a reviewer.

Results

Run twice - once with the reverted setup script on master, once with this MR's - and compare:

Reverted script (reproduces the failure from Revert "Merge branch 'jmd/add-duo-agent-config'... (!230068 - merged)):

warning: rejected refs/ci-head because shallow roots are not allowed to be updated                                                       
fatal: ambiguous argument 'refs/ci-head': unknown revision or path not in the working tree.                                              

This MR's script: Code Review completes; published review on the MR references marker.txt and the deletion, confirming the agent ran against the divergent branch's content rather than master's.

Updates to gems/migrations
  • Create branch on gdk.test:3000
  • Add a simple gem (e.g. gem 'colorize') to Gemfile + Gemfile.lock
  • Add a trivial migration file db/migrate/YYYYMMDDHHMMSS_add_test_column.rb
  • Trigger Code review/v1 by assigning @GitLabDuo as a reviewer

Result: Should observe gem being installed, migration running.

NB: If a branch has a genuinely broken Gemfile.lock (e.g. a gem with unsatisfied transitive deps), I have observed that it as expected will emit a loud error in the logs, but the agent operates in a degraded environment, giving it chance to do useful work. The MR's real CI pipeline is the backstop for the underlying gem issue.

Sample issues for validation

Issue 1 — RSpec (fast_spec_helper, no DB)

Title: Add darken(percent) method to Gitlab::Color

Add a darken(percent) method to Gitlab::Color (lib/gitlab/color.rb) that returns a new Gitlab::Color instance representing a darker shade. The method should reduce each RGB component by the given percentage (e.g., darken(20) reduces each component by 20%). Clamp values to 0.

Update spec/lib/gitlab/color_spec.rb with tests covering:

  • darken(0) returns the same color
  • darken(50) on #FF8800 returns #804400
  • darken(100) returns #000000
  • darken on an already-black color stays #000000

This spec uses fast_spec_helper (no database needed).

Definition of Done: Run bundle exec rspec spec/lib/gitlab/color_spec.rb 2>&1 | tail -30 — all examples must pass. Include the rspec summary line in your final message.

Issue 2 — Jest (yarn + node)

Title: Add uniqueByKey function to array_utility.js

Add a uniqueByKey(array, key) function to app/assets/javascripts/lib/utils/array_utility.js that deduplicates an array of objects by a given property name, keeping the first occurrence.

Example: uniqueByKey([{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 1, name: 'c'}], 'id') returns [{id: 1, name: 'a'}, {id: 2, name: 'b'}].

Update spec/frontend/lib/utils/array_utility_spec.js with tests covering:

  • Empty array returns empty array
  • Array with no duplicates returns same array
  • Array with duplicates keeps first occurrence
  • Works with string keys

Definition of Done: Run yarn jest spec/frontend/lib/utils/array_utility_spec.js 2>&1 | tail -30 — all tests must pass. Include the jest summary line in your final message.

Issue 3 — lefthook pre-push hooks

Title: Add lighten(percent) method to Gitlab::Color

Add a lighten(percent) method to Gitlab::Color (lib/gitlab/color.rb) that returns a new Gitlab::Color instance representing a lighter shade. The method should increase each RGB component toward 255 by the given percentage (e.g., lighten(50) moves each component halfway to 255).

Update spec/lib/gitlab/color_spec.rb with tests:

  • lighten(0) returns the same color
  • lighten(100) returns #FFFFFF
  • lighten(50) on #000000 returns #808080

This spec uses fast_spec_helper (no database needed).

Definition of Done:

  1. Run bundle exec rspec spec/lib/gitlab/color_spec.rb 2>&1 | tail -30 — all examples must pass
  2. Commit the change — lefthook pre-commit hooks must pass. Do NOT use --no-verify or LEFTHOOK=0. If the commit fails due to hooks, fix the issue and retry. Include the full commit output in your final message so hook results are visible.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by John McDonnell

Merge request reports

Loading
Loading