diff --git a/.github/aw/execute-agentic-campaign-workflow.md b/.github/aw/execute-agentic-campaign-workflow.md index 5fedd4c85e..4a4247ce44 100644 --- a/.github/aw/execute-agentic-campaign-workflow.md +++ b/.github/aw/execute-agentic-campaign-workflow.md @@ -1,8 +1,8 @@ # Workflow Execution -This campaign is configured to **actively execute workflows**. Your role is to run the workflows listed in sequence, collect their outputs, and use those outputs to drive the campaign forward. +This campaign orchestrator can execute workflows as needed. Your role is to run the workflows listed in sequence, collect their outputs, and use those outputs to drive the campaign forward. -**IMPORTANT: Active execution is an advanced feature. Exercise caution and follow all guidelines carefully.** +**IMPORTANT: Workflow execution is an advanced capability. Exercise caution and follow all guidelines carefully.** --- @@ -49,7 +49,7 @@ The following workflows should be executed in order: For each workflow: -1. **Check if workflow exists** - Look for `.github/workflows/.md` or `.github/workflows/.lock.yml` +1. **Check if workflow exists** - Look for `.github/workflows/.md` 2. **Create workflow if needed** - Only if ALL guardrails above are satisfied: @@ -68,6 +68,20 @@ For each workflow: on: workflow_dispatch: # Required for execution + inputs: + priority: + description: 'Priority level for this execution' + required: false + type: choice + options: + - low + - medium + - high + default: medium + target: + description: 'Specific target or scope for this run' + required: false + type: string tools: github: @@ -85,6 +99,9 @@ For each workflow: You are a focused workflow that . + Priority: \$\{\{ github.event.inputs.priority \}\} + Target: \$\{\{ github.event.inputs.target \}\} + ## Task @@ -94,6 +111,8 @@ For each workflow: ``` + **Note**: Define `inputs` under `workflow_dispatch` to accept parameters from the orchestrator. Use `\$\{\{ github.event.inputs.INPUT_NAME \}\}` to reference input values in your workflow markdown. See [DispatchOps documentation](https://githubnext.github.io/gh-aw/guides/dispatchops/#with-input-parameters) for input types and examples. + - Compile it with `gh aw compile .md` - **CRITICAL: Test before use** (see testing requirements below) @@ -118,15 +137,19 @@ For each workflow: 4. **Execute the workflow** (skip if just tested successfully): - Trigger: `mcp__github__run_workflow(workflow_id: "", ref: "main")` + - **Pass input parameters based on decisions**: If the workflow accepts inputs, provide them to guide execution (e.g., `inputs: {priority: "high", target: "security"}`) - Wait for completion: Poll `mcp__github__get_workflow_run(run_id)` until status is "completed" - Collect outputs: Check `mcp__github__download_workflow_run_artifact()` for any artifacts - **Handle failures gracefully**: If execution fails, note it in status update but continue campaign 5. **Use outputs for next steps** - Use information from workflow runs to: - Inform subsequent workflow executions (e.g., scanner results → upgrader inputs) + - Pass contextual inputs to worker workflows based on campaign state and decisions - Update project board items with relevant information - Make decisions about campaign progress and next actions +**Note**: Workflows that accept `workflow_dispatch` inputs can receive parameters from the orchestrator. This enables the orchestrator to provide context, priorities, or targets based on its decisions. See [DispatchOps documentation](https://githubnext.github.io/gh-aw/guides/dispatchops/#with-input-parameters) for input parameter examples. + --- ## Guidelines diff --git a/.github/workflows/security-alert-burndown.campaign.lock.yml b/.github/workflows/security-alert-burndown.campaign.lock.yml index 42371fd131..7ac9e2fe6b 100644 --- a/.github/workflows/security-alert-burndown.campaign.lock.yml +++ b/.github/workflows/security-alert-burndown.campaign.lock.yml @@ -906,6 +906,213 @@ jobs: - Governance: max project updates per run: 10 - Governance: max comments per run: 3 + --- + # WORKFLOW EXECUTION (PHASE 0) + --- + # Workflow Execution + + This campaign orchestrator can execute workflows as needed. Your role is to run the workflows listed in sequence, collect their outputs, and use those outputs to drive the campaign forward. + + **IMPORTANT: Workflow execution is an advanced capability. Exercise caution and follow all guidelines carefully.** + + --- + + ## Workflows to Execute + + + The following workflows should be executed in order: + + 1. `code-scanning-fixer` + + 2. `security-fix-pr` + + 3. `security-review` + + + + --- + + ## Workflow Creation Guardrails + + ### Before Creating Any Workflow, Ask: + + 1. **Does this workflow already exist?** - Check `.github/workflows/` thoroughly + 2. **Can an existing workflow be used?** - Even if not perfect, existing is safer + 3. **Is the requirement clear?** - Can you articulate exactly what it should do? + 4. **Is it testable?** - Can you verify it works before using it in the campaign? + 5. **Is it reusable?** - Could other campaigns benefit from this workflow? + + ### Only Create New Workflows When: + + ✅ **All these conditions are met:** + - No existing workflow does the required task + - The campaign objective explicitly requires this capability + - You have a clear, specific design for the workflow + - The workflow has a focused, single-purpose scope + - You can test it independently before campaign use + + ❌ **Never create workflows when:** + - You're unsure about requirements + - An existing workflow "mostly" works + - The workflow would be complex or multi-purpose + - You haven't verified it doesn't already exist + - You can't clearly explain what it does in one sentence + + --- + + ## Execution Process + + For each workflow: + + 1. **Check if workflow exists** - Look for `.github/workflows/.md` + + 2. **Create workflow if needed** - Only if ALL guardrails above are satisfied: + + **Design requirements:** + - **Single purpose**: One clear task (e.g., "scan for outdated dependencies", not "scan and update") + - **Explicit trigger**: Must include `workflow_dispatch` for manual/programmatic execution + - **Minimal tools**: Only include tools actually needed (principle of least privilege) + - **Safe outputs only**: Use appropriate safe-output limits (max: 5 for first version) + - **Clear prompt**: Describe exactly what the workflow should do and return + + **Create the workflow file at `.github/workflows/.md`:** + ```yaml + --- + name: + description: + + on: + workflow_dispatch: # Required for execution + inputs: + priority: + description: 'Priority level for this execution' + required: false + type: choice + options: + - low + - medium + - high + default: medium + target: + description: 'Specific target or scope for this run' + required: false + type: string + + tools: + github: + toolsets: [default] # Adjust based on needs + # Only add other tools if absolutely necessary + + safe-outputs: + create-issue: + max: 3 # Start conservative + add-comment: + max: 2 + --- + + # + + You are a focused workflow that . + + Priority: \$\{\{ github.event.inputs.priority \}\} + Target: \$\{\{ github.event.inputs.target \}\} + + ## Task + + + + ## Output + + + ``` + + **Note**: Define `inputs` under `workflow_dispatch` to accept parameters from the orchestrator. Use `\$\{\{ github.event.inputs.INPUT_NAME \}\}` to reference input values in your workflow markdown. See [DispatchOps documentation](https://githubnext.github.io/gh-aw/guides/dispatchops/#with-input-parameters) for input types and examples. + + - Compile it with `gh aw compile .md` + - **CRITICAL: Test before use** (see testing requirements below) + + 3. **Test newly created workflows** (MANDATORY): + + **Why test?** - Untested workflows may fail during campaign execution, blocking progress. Test first to catch issues early. + + **Testing steps:** + - Trigger test run: `mcp__github__run_workflow(workflow_id: "", ref: "main")` + - Wait for completion: Poll until status is "completed" + - **Verify success**: Check that workflow succeeded and produced expected outputs + - **Review outputs**: Ensure results match expectations (check artifacts, issues created, etc.) + - **If test fails**: Revise the workflow, recompile, and test again + - **Only proceed** after successful test run + + **Test failure actions:** + - DO NOT use the workflow in the campaign if testing fails + - Analyze the failure logs to understand what went wrong + - Make necessary corrections to the workflow + - Recompile and retest + - If you can't fix it after 2 attempts, report in status update and skip this workflow + + 4. **Execute the workflow** (skip if just tested successfully): + - Trigger: `mcp__github__run_workflow(workflow_id: "", ref: "main")` + - **Pass input parameters based on decisions**: If the workflow accepts inputs, provide them to guide execution (e.g., `inputs: {priority: "high", target: "security"}`) + - Wait for completion: Poll `mcp__github__get_workflow_run(run_id)` until status is "completed" + - Collect outputs: Check `mcp__github__download_workflow_run_artifact()` for any artifacts + - **Handle failures gracefully**: If execution fails, note it in status update but continue campaign + + 5. **Use outputs for next steps** - Use information from workflow runs to: + - Inform subsequent workflow executions (e.g., scanner results → upgrader inputs) + - Pass contextual inputs to worker workflows based on campaign state and decisions + - Update project board items with relevant information + - Make decisions about campaign progress and next actions + + **Note**: Workflows that accept `workflow_dispatch` inputs can receive parameters from the orchestrator. This enables the orchestrator to provide context, priorities, or targets based on its decisions. See [DispatchOps documentation](https://githubnext.github.io/gh-aw/guides/dispatchops/#with-input-parameters) for input parameter examples. + + --- + + ## Guidelines + + **Execution order:** + - Execute workflows **sequentially** (one at a time) + - Wait for each workflow to complete before starting the next + - **Why sequential?** - Ensures dependencies between workflows are respected and reduces API load + + **Workflow creation:** + - **Always test newly created workflows** before using them in the campaign + - **Why test first?** - Prevents campaign disruption from broken workflows + - Start with minimal, focused workflows (easier to test and debug) + - **Why minimal?** - Reduces complexity and points of failure + - Keep designs simple and aligned with campaign objective + - **Why simple?** - Easier to understand, test, and maintain + + **Failure handling:** + - If a workflow test fails, revise and retest before proceeding + - **Why retry?** - Initial failures often due to minor issues easily fixed + - If a workflow fails during campaign execution, note the failure and continue + - **Why continue?** - One workflow failure shouldn't block entire campaign progress + - Report all failures in the status update with context + - **Why report?** - Transparency helps humans intervene if needed + + **Workflow reusability:** + - Workflows you create should be reusable for future campaign runs + - **Why reusable?** - Reduces need to create workflows repeatedly, builds library of capabilities + - Avoid campaign-specific logic in workflows (keep them generic) + - **Why generic?** - Enables reuse across different campaigns + + **Permissions and safety:** + - Keep workflow permissions minimal (only what's needed) + - **Why minimal?** - Reduces risk and follows principle of least privilege + - Prefer draft PRs over direct merges for code changes + - **Why drafts?** - Requires human review before merging changes + - Escalate to humans when uncertain about decisions + - **Why escalate?** - Human oversight prevents risky autonomous actions + + --- + + ## After Workflow Execution + + Once all workflows have been executed (or created and executed), proceed with the normal orchestrator steps: + - Step 1: Discovery (read state from manifest and project board) + - Step 2: Planning (determine what needs updating) + - Step 3: Project Updates (write state to project board) + - Step 4: Status Reporting (report progress, failures, and next steps) --- # ORCHESTRATOR INSTRUCTIONS --- @@ -1093,6 +1300,8 @@ jobs: 2) Read current GitHub Project board state (items + required fields). 3) Parse discovered items from the manifest: + PROMPT_EOF + cat << 'PROMPT_EOF' >> "$GH_AW_PROMPT" - Each item has: url, content_type (issue/pull_request/discussion), number, repo, created_at, updated_at, state - Closed items have: closed_at (for issues) or merged_at (for PRs) - Items are pre-sorted by updated_at for deterministic processing @@ -1295,8 +1504,6 @@ jobs: - `worker_workflow`: workflow ID if known, else `"unknown"` - `repository`: extract `owner/repo` from the issue/PR URL - `priority`: default `Medium` unless explicitly known - PROMPT_EOF - cat << 'PROMPT_EOF' >> "$GH_AW_PROMPT" - `size`: default `Medium` unless explicitly known - `start_date`: issue/PR `created_at` formatted `YYYY-MM-DD` - `end_date`: diff --git a/pkg/campaign/orchestrator.go b/pkg/campaign/orchestrator.go index 194f5aa9e4..212223511b 100644 --- a/pkg/campaign/orchestrator.go +++ b/pkg/campaign/orchestrator.go @@ -325,15 +325,14 @@ func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.W promptData.MaxProjectCommentsPerRun = spec.Governance.MaxCommentsPerRun } - // Add workflow execution instructions when workflows are configured - if len(spec.Workflows) > 0 { - workflowExecution := RenderWorkflowExecution(promptData) - if workflowExecution == "" { - orchestratorLog.Print("Warning: Failed to render workflow execution instructions, template may be missing") - } else { - appendPromptSection(markdownBuilder, "WORKFLOW EXECUTION (PHASE 0)", workflowExecution) - orchestratorLog.Printf("Campaign '%s' orchestrator includes workflow execution", spec.ID) - } + // All campaigns include workflow execution capabilities + // The orchestrator can dispatch workflows and make decisions regardless of initial configuration + workflowExecution := RenderWorkflowExecution(promptData) + if workflowExecution == "" { + orchestratorLog.Print("Warning: Failed to render workflow execution instructions, template may be missing") + } else { + appendPromptSection(markdownBuilder, "WORKFLOW EXECUTION (PHASE 0)", workflowExecution) + orchestratorLog.Printf("Campaign '%s' orchestrator includes workflow execution", spec.ID) } orchestratorInstructions := RenderOrchestratorInstructions(promptData) diff --git a/pkg/campaign/template.go b/pkg/campaign/template.go index a68be650b3..1bfba4c6ac 100644 --- a/pkg/campaign/template.go +++ b/pkg/campaign/template.go @@ -88,6 +88,9 @@ func renderTemplate(tmplStr string, data CampaignPromptData) (string, error) { "if": func(condition bool) bool { return condition }, + "add1": func(i int) int { + return i + 1 + }, } // Parse template with custom delimiters to match Handlebars style diff --git a/pkg/cli/templates/execute-agentic-campaign-workflow.md b/pkg/cli/templates/execute-agentic-campaign-workflow.md index 5fedd4c85e..4a4247ce44 100644 --- a/pkg/cli/templates/execute-agentic-campaign-workflow.md +++ b/pkg/cli/templates/execute-agentic-campaign-workflow.md @@ -1,8 +1,8 @@ # Workflow Execution -This campaign is configured to **actively execute workflows**. Your role is to run the workflows listed in sequence, collect their outputs, and use those outputs to drive the campaign forward. +This campaign orchestrator can execute workflows as needed. Your role is to run the workflows listed in sequence, collect their outputs, and use those outputs to drive the campaign forward. -**IMPORTANT: Active execution is an advanced feature. Exercise caution and follow all guidelines carefully.** +**IMPORTANT: Workflow execution is an advanced capability. Exercise caution and follow all guidelines carefully.** --- @@ -49,7 +49,7 @@ The following workflows should be executed in order: For each workflow: -1. **Check if workflow exists** - Look for `.github/workflows/.md` or `.github/workflows/.lock.yml` +1. **Check if workflow exists** - Look for `.github/workflows/.md` 2. **Create workflow if needed** - Only if ALL guardrails above are satisfied: @@ -68,6 +68,20 @@ For each workflow: on: workflow_dispatch: # Required for execution + inputs: + priority: + description: 'Priority level for this execution' + required: false + type: choice + options: + - low + - medium + - high + default: medium + target: + description: 'Specific target or scope for this run' + required: false + type: string tools: github: @@ -85,6 +99,9 @@ For each workflow: You are a focused workflow that . + Priority: \$\{\{ github.event.inputs.priority \}\} + Target: \$\{\{ github.event.inputs.target \}\} + ## Task @@ -94,6 +111,8 @@ For each workflow: ``` + **Note**: Define `inputs` under `workflow_dispatch` to accept parameters from the orchestrator. Use `\$\{\{ github.event.inputs.INPUT_NAME \}\}` to reference input values in your workflow markdown. See [DispatchOps documentation](https://githubnext.github.io/gh-aw/guides/dispatchops/#with-input-parameters) for input types and examples. + - Compile it with `gh aw compile .md` - **CRITICAL: Test before use** (see testing requirements below) @@ -118,15 +137,19 @@ For each workflow: 4. **Execute the workflow** (skip if just tested successfully): - Trigger: `mcp__github__run_workflow(workflow_id: "", ref: "main")` + - **Pass input parameters based on decisions**: If the workflow accepts inputs, provide them to guide execution (e.g., `inputs: {priority: "high", target: "security"}`) - Wait for completion: Poll `mcp__github__get_workflow_run(run_id)` until status is "completed" - Collect outputs: Check `mcp__github__download_workflow_run_artifact()` for any artifacts - **Handle failures gracefully**: If execution fails, note it in status update but continue campaign 5. **Use outputs for next steps** - Use information from workflow runs to: - Inform subsequent workflow executions (e.g., scanner results → upgrader inputs) + - Pass contextual inputs to worker workflows based on campaign state and decisions - Update project board items with relevant information - Make decisions about campaign progress and next actions +**Note**: Workflows that accept `workflow_dispatch` inputs can receive parameters from the orchestrator. This enables the orchestrator to provide context, priorities, or targets based on its decisions. See [DispatchOps documentation](https://githubnext.github.io/gh-aw/guides/dispatchops/#with-input-parameters) for input parameter examples. + --- ## Guidelines