Add per-flow coding_environment declaration for Duo Agent Platform flows
What does this MR do and why?
Introduces an optional coding_environment property that a Duo Agent Platform flow can declare to control what kind of coding environment GitLab prepares before the workload starts.
Background: dap_full_clone applies a full blobless clone to all DAP flows. API-only flows pay that cost for nothing. Each flow can now declare what it needs; the safe default is the full environment.
Allowed values
| Value | Behaviour |
|---|---|
full |
Default when absent. Repository clone, setup scripts, Git hooks, and dependency cache. |
none |
No clone (GIT_STRATEGY=none). Setup scripts, Git hooks, and dependency cache are all skipped. |
A value other than full or none is rejected by flow_v2.json at save time, so a typo never reaches the resolver. An absent declaration resolves to full, so a missing declaration can never silently remove a flow's repository access.
Resolution order
Ai::Catalog::CodingEnvironment.resolve consults, in order:
- The
coding_environmentkey of a catalog/custom flow'sflow_config - The
coding_environmentattribute of theAi::Catalog::FoundationalFlowregistry entry :full
Fall-through is driven by the absence of a value, not the absence of a flow_config Hash. A config that declares nothing (or declares it under a Symbol key) still reaches the registry, so one source cannot silently mask the other.
Relationship to dap_full_clone
None — deliberately. dap_full_clone selects how to clone; coding_environment selects whether to clone. Under GIT_STRATEGY=none the depth, filter and LFS variables are inert, so the legacy clone path needs no protection and the declaration behaves identically on both sides of that flag.
Gating this behind dap_full_clone would have made a documented, schema-validated YAML property a silent no-op wherever the flag is off (it is default_enabled: false), and tied two unrelated rollouts to one kill switch.
Files changed
ee/app/models/ai/catalog/coding_environment.rb— new value object owning resolutionee/app/models/ai/catalog/foundational_flow/attributes.rb—coding_environmentattribute, default'full'app/validators/json_schemas/ai_catalog/flow_v2.json— optional string property, enumfull/noneee/app/services/ai/duo_workflows/start_workflow_service.rb— apply the resolved environment to the workload definition- Specs for all three layers, plus a guardrail lint on
Items.fixed_items - Docs:
custom_flows_schema.md
References
Related to #606480 (closed)
The lightweight value is reserved for a future mechanism being decided in !247414 (closed).
Screenshots or screen recordings
N/A — backend only, no UI.
How to set up and validate locally
The signal is in the Git phase of the workload job log, before the duo CLI starts. The flow does not need to succeed for the test to be valid.
1. Custom flow (the flow_config branch)
Create a flow at <project>/-/automate/flows/new with this definition:
version: "v1"
environment: ambient
# Declares that this flow needs no coding environment.
coding_environment: none
components:
- name: "api_agent"
type: AgentComponent
prompt_id: "api_prompt"
inputs:
- "context:goal"
toolset: []
ui_log_events:
- "on_agent_final_answer"
prompts:
- prompt_id: "api_prompt"
name: "API Only Test Prompt"
prompt_template:
system: |
You are a test agent. You verify that a GitLab Duo flow can run
without a repository checkout. Answer in one short sentence.
user: |
{{goal}}
placeholder: history
unit_primitives: []
params:
timeout: 180
routers:
- from: "api_agent"
to: "end"
flow:
entry_point: "api_agent"Do not add yaml_definition — the server injects it.
Enable the flow on the project and trigger it (for example, mention the flow's service account in an issue comment). Then open the newest workload job.
Expect:
- Log contains
Skipping Git repository setupandSkipping Git checkout - Log does not contain
Fetching changesorChecking out ... as detached HEAD - Script contains no
git remote set-url origin,git checkout -B, orgit fetch --no-tags
Remove the coding_environment: none line, re-run, and confirm the clone returns.
2. Foundational flow (the registry branch)
Temporarily add coding_environment: "none" to any entry in ee/app/models/ai/catalog/foundational_flow/items.rb, then restart so the class-level fixed_items cache is rebuilt:
gdk restart rails-web rails-background-jobsTrigger that flow and check the same markers.
Note: flows holding USE_GIT or READ_WRITE_FILES will fail the guardrail spec in foundational_flow_spec.rb while this edit is applied. That is the spec doing its job.
3. Independence from dap_full_clone
Repeat either test with the flag off. The result must be identical:
bin/rails runner 'Feature.disable(:dap_full_clone)'4. Inspecting a job without reading the log
bin/rails runner '
b = Ci::Build.find(<JOB_ID>)
vars = (b.yaml_variables || []).to_h { |v| [v[:key], v[:value]] }
%w[GIT_STRATEGY GIT_DEPTH GIT_FETCH_EXTRA_FLAGS GIT_LFS_SKIP_SMUDGE].each do |k|
puts format("%-22s %s", k, vars.key?(k) ? vars[k].inspect : "(absent)")
end
puts "script_lines: #{Array(b.options.dig(:script)).size}"
'5. Schema validation
Saving a flow with coding_environment: lightweight must fail with:
value at `/coding_environment` is not one of: ["full", "none"]Validation results
Verified on GDK across five workload jobs. All five completed successfully.
| Source | Declared | dap_full_clone |
GIT_STRATEGY |
Clone vars | Script lines | Runner |
|---|---|---|---|---|---|---|
| foundational | absent | on | absent | DEPTH=0, blob:none, LFS=1 |
58 | Checking out |
| foundational | none |
on | none |
absent | 50 | Skipping Git repository setup |
| foundational | none |
off | none |
absent | 50 | Skipping Git repository setup |
| custom flow | none |
on | none |
absent | 50 | Skipping Git repository setup |
| custom flow | absent | on | absent | DEPTH=0, blob:none, LFS=1 |
58 | Checking out |
The 58 → 50 script delta is exactly coding_environment_commands: four Git-hook lines, one OAuth remote, three workspace fixups.
Not covered by these runs: the dependency cache skip. The test project configures no cache, so d.cache was nil throughout. That branch is covered by specs only.
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.