Spike: Project Context Init Flow
Create a new flow for new projects to add context for use by Duo Agent Platform.
- Creates a basic AGENTS.md and potential sub AGENTS.md (same as init command of CLIs) in a new MR
- Subfolders created for skills, rules, etc. and adds README files
| Screenshots |
|---|
![]() |
![]() |
![]() |
![]() |
Implementation Plan
AI Gateway (ai-assist repo)
Related MR: gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!4851 (closed)
- Add
duo_workflow_service/agent_platform/v1/flows/configs/project_context_init/1.0.0.ymlto the flow registry with two components:context_analyzer(AgentComponent) — reads the repo tree, detects languages, existing agent context files (AGENTS.md, CLAUDE.md, CURSOR.md, .cursorrules, etc.), and tooling configs. Retrieves the current user ID viaget_current_userfor MR assignment. Toolset:list_dir,find_files,read_file,get_project,get_current_userinit_writer(AgentComponent) — generates a minimal, evidence-groundedAGENTS.md(no boilerplate; noskills//rules/stubs), optional sub-AGENTS.mdonly for subdirs with distinct tooling, then opens a draft MR assigned to the initiating user. Toolset:create_file_with_contents,mkdir,create_branch,run_git_command,create_merge_request
- Add prompts for both components under
ai_gateway/prompts/definitions/ - Add model selection entries for both components in
ai_gateway/model_selection/unit_primitives.yml(unit_primitive: duo_agent_platform, default model:claude_sonnet_4_6)
GitLab Monolith (gitlab repo)
All monolith changes are gated behind the duo_project_context_init feature flag (type: beta, group: group::ai coding, default: disabled). The flag must be checked at every entry point: the controller, the service, the sidebar, and the frontend route.
Feature Flag Definition
Create ee/config/feature_flags/beta/duo_project_context_init.yml:
name: duo_project_context_init
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/226355
rollout_issue_url: # add rollout issue URL
milestone: '17.11'
group: group::ai coding
type: beta
default_enabled: falseRun bin/feature-flag duo_project_context_init --type beta to generate this file.
1. Backend: ExecuteWorkflowService validation enhancement
File: ee/app/services/ai/catalog/execute_workflow_service.rb
Modify validate to accept flow_name_reference? as a bypass for the json_config requirement:
def validate
return error('You have insufficient permissions') unless allowed?
return error('JSON config is required') unless json_config.present? || foundational_flow? || flow_name_reference?
return error('Goal is required') unless goal.present?
ServiceResponse.success
end
def flow_name_reference?
@flow_definition.present? && !foundational_flow?
endWhen json_config is nil, StartWorkflowService#serialized_duo_flow_config already returns nil, so DUO_WORKFLOW_FLOW_CONFIG is not set. The AI Gateway executor then resolves the flow YAML from the registry by name automatically via FlowConfig.from_yaml_config.
2. Backend: InitProjectContextService
File: ee/app/services/ai/duo_workflows/init_project_context_service.rb
New service that calls ExecuteWorkflowService with:
flow_definition: "project_context_init/v1"container: projectgoal: "Initialize project context for Duo Agent Platform"- No
json_configneeded
Guard the service with the feature flag:
def execute
return ServiceResponse.error(message: 'Feature not available') unless Feature.enabled?(:duo_project_context_init, project)
# ... call ExecuteWorkflowService
end3. Backend: Controller
File: ee/app/controllers/projects/duo_agents_platform_controller.rb
- Add
'onboarding'toDUO_AGENT_PLATFORM_ROUTESfor correctfeature_category - Add
'onboarding'tospecific_vueroute?andauthorized_for_route?(accessible to any user who can:duo_workflowon the project) - Add
set_has_agents_mdbefore_action scoped to the onboarding route only, gated by the feature flag:
before_action :set_has_agents_md, only: [:show]
def set_has_agents_md
return unless params[:vueroute] == 'onboarding'
return unless Feature.enabled?(:duo_project_context_init, @project)
gon.push(has_agents_md: agents_md_exists?)
endWhere agents_md_exists? checks for AGENTS.md in both the project root and .ai/AGENTS.md.
4. Backend: Rails routes
File: ee/config/routes/project.rb
Add a named route helper for the sidebar:
scope :automate do
get '/(*vueroute)' => 'duo_agents_platform#show', as: :automate, format: false
get 'onboarding', to: 'duo_agents_platform#show', as: :automate_onboarding, format: false
end5. Backend: Sidebar
File: ee/lib/sidebars/projects/super_sidebar_menus/duo_agents_menu.rb
Add an "Onboarding" menu item, rendered only when the feature flag is enabled:
override :configure_menu_items
def configure_menu_items
add_item(duo_agents_runs_menu_item)
add_item(duo_agents_onboarding_menu_item) if Feature.enabled?(:duo_project_context_init, context.project)
true
end
def duo_agents_onboarding_menu_item
::Sidebars::MenuItem.new(
title: s_('DuoAgentsPlatform|Onboarding'),
link: project_automate_onboarding_path(context.project),
active_routes: { controller: :duo_agents_platform },
item_id: :agents_onboarding
)
end6. Frontend: Router constants
File: ee/app/assets/javascripts/ai/duo_agents_platform/router/constants.js
export const AGENTS_PLATFORM_ONBOARDING_ROUTE = 'onboarding_index';7. Frontend: Router
File: ee/app/assets/javascripts/ai/duo_agents_platform/router/index.js
Add a new top-level route tree, conditionally included when glFeatures.duoProjectContextInit is enabled:
...(glFeatures.duoProjectContextInit ? [{
component: NestedRouteApp,
path: '/onboarding',
meta: { text: s__('DuoAgentsPlatform|Onboarding') },
children: [
{
name: AGENTS_PLATFORM_ONBOARDING_ROUTE,
path: '',
component: ProjectContextOnboardingPage,
},
],
}] : []),This gives the URL /automate/onboarding and the breadcrumb "Automate > Onboarding" automatically via the existing router-driven breadcrumb system.
8. Frontend: Onboarding page component
File: ee/app/assets/javascripts/ai/duo_agents_platform/pages/onboarding/project_context_onboarding_page.vue
A full page component with:
PageHeadingwith title "Set up your project for Duo Agent Platform"- Description explaining what the init flow does (creates
AGENTS.md, sub-files, skill/rule stubs) - AGENTS.md absent state: primary "Initialize project context"
GlButtonthat callsInitProjectContextService; button is disabled with a spinner while the flow session is in progress - AGENTS.md present state: a
GlAlert(variant: success) informing the user that context has already been initialized, with a link to the resulting MR - Reads
hasAgentsMdfromwindow.gon?.has_agents_md(injected by the controller) to determine which state to render - On success, shows the success state in-page (no full redirect needed)
What is explicitly NOT needed
- No new API endpoint
- No AI Catalog registration or
ItemConsumer - No foundational flow registration (avoids appearing in the group settings UI)
- No full YAML bundled in the monolith
- No new DB column to track init state (file presence is the guard)
- No
skills/orrules/directory stubs (removed from scope)



