From 96f1da7658c765d36b79a789781c9672040cf6a8 Mon Sep 17 00:00:00 2001 From: Mara Nikola Kiefer Date: Wed, 28 Jan 2026 18:30:12 +0100 Subject: [PATCH 1/4] chore: clarify agent session instructions --- .github/aw/close-agentic-campaign.md | 4 +- .github/aw/generate-agentic-campaign.md | 17 ++- .github/aw/orchestrate-agentic-campaign.md | 32 +++-- .github/aw/update-agentic-campaign-project.md | 3 +- .../security-alert-burndown.lock.yml | 135 ++++++------------ .github/workflows/security-alert-burndown.md | 92 +++--------- pkg/cli/templates/close-agentic-campaign.md | 4 +- .../templates/generate-agentic-campaign.md | 17 ++- .../templates/orchestrate-agentic-campaign.md | 32 +++-- .../update-agentic-campaign-project.md | 3 +- 10 files changed, 133 insertions(+), 206 deletions(-) diff --git a/.github/aw/close-agentic-campaign.md b/.github/aw/close-agentic-campaign.md index b3a40b6e01..f08b217966 100644 --- a/.github/aw/close-agentic-campaign.md +++ b/.github/aw/close-agentic-campaign.md @@ -4,13 +4,13 @@ Execute all four steps in strict order: 1. Read State (no writes) 2. Make Decisions (no writes) -3. Dispatch Workers (dispatch-workflow only) +3. Apply Updates (writes) 4. Report The following rules are mandatory and override inferred behavior: - The GitHub Project board is the single source of truth. -- All project writes MUST comply with the Project Update Instructions (in workers). +- All project writes MUST comply with the Project Update Instructions. - State reads and state writes MUST NOT be interleaved. - Do NOT infer missing data or invent values. - Do NOT reorganize hierarchy. diff --git a/.github/aw/generate-agentic-campaign.md b/.github/aw/generate-agentic-campaign.md index 975680600c..5677799ee2 100644 --- a/.github/aw/generate-agentic-campaign.md +++ b/.github/aw/generate-agentic-campaign.md @@ -11,7 +11,8 @@ When creating or modifying GitHub resources, **use MCP tool calls directly** (no - `create_project` - Create project board - `update_project` - Create/update project fields, views, and items - `update_issue` - Update issue details -- `assign_to_agent` - Assign to agent +- `create_agent_session` - Create a Copilot coding agent session (preferred handoff) +- `assign_to_agent` - Assign to agent (optional; use for existing issues/PRs) ## Workflow @@ -24,7 +25,7 @@ When creating or modifying GitHub resources, **use MCP tool calls directly** (no 5. Discover workflows: scan `.github/workflows/*.md` and check [agentics collection](https://github.com/githubnext/agentics) 6. Generate `.campaign.md` spec in `.github/workflows/` 7. Update the triggering issue with a human-readable status + Copilot Coding Agent instructions -8. Assign to Copilot Coding Agent +8. Create a Copilot coding agent session (preferred) or assign to agent (fallback) **Agent Responsibilities:** Compile with `gh aw compile`, commit files, create PR @@ -79,7 +80,7 @@ Create them before adding any items to the project. ## Copilot Coding Agent Handoff (Required) -Before calling `assign_to_agent`, update the triggering issue (via `update_issue`) to include a clear, human-friendly status update. +Before creating an agent session, update the triggering issue (via `update_issue`) to include a clear, human-friendly status update. The issue update MUST be easy to follow for someone unfamiliar with campaigns. Include: @@ -111,7 +112,7 @@ Add a section like this (fill in real values): - Selected workflows: ``, `` ### What happens next -1. Copilot Coding Agent will open a pull request with the generated files. +1. Copilot Coding Agent will open a pull request with the generated files (via agent session). 2. You review the PR and merge it. 3. After merge, run the orchestrator workflow from the Actions tab. @@ -119,6 +120,7 @@ Add a section like this (fill in real values): - **Campaign ID:** `` - **Project URL:** - **Workflows:** ``, `` +- **Agent session:** Run: ```bash @@ -166,14 +168,14 @@ In addition to the structure above, include these exact items: **Safe Outputs (Least Privilege):** - For this campaign generator workflow, use `update-issue` for status updates (this workflow does not enable `add-comment`). -- Project-based: `create-project`, `update-project`, `update-issue`, `assign-to-agent` (in order) +- Project-based: `create-project`, `update-project`, `update-issue`, `create-agent-session` (preferred) **Operation Order for Project Setup:** 1. `create-project` (creates project + views) 2. `update-project` (adds items/fields) 3. `update-issue` (updates metadata, optional) -4. `assign-to-agent` (assigns agents, optional) +4. `create-agent-session` (preferred) or `assign-to-agent` (fallback) **Example Safe Outputs Configuration for Project-Based Campaigns:** @@ -197,7 +199,8 @@ safe-outputs: max: 10 github-token: "" # Provide via workflow secret/env; avoid secrets expressions in runtime-import files update-issue: - assign-to-agent: + create-agent-session: + base: "${{ github.ref_name }}" # Prefer main/default branch when appropriate ``` **Risk Levels:** diff --git a/.github/aw/orchestrate-agentic-campaign.md b/.github/aw/orchestrate-agentic-campaign.md index 9318bd46ec..9f75803615 100644 --- a/.github/aw/orchestrate-agentic-campaign.md +++ b/.github/aw/orchestrate-agentic-campaign.md @@ -2,9 +2,9 @@ This orchestrator coordinates a single campaign by discovering worker outputs and making deterministic decisions. -**Scope:** orchestration only (discovery, planning, pacing, reporting). -**Actuation model:** **dispatch-only** — the orchestrator may only act by dispatching allowlisted worker workflows. -**Write authority:** all GitHub writes (Projects, issues/PRs, comments, status updates) must happen in worker workflows. +**Scope:** orchestration + project sync + reporting (discovery, planning, pacing, writing, reporting). +**Actuation model:** **hybrid** — the orchestrator may update campaign state directly (Projects and status updates) and may also dispatch allowlisted worker workflows. +**Write authority:** the orchestrator may write GitHub state when explicitly allowlisted via safe outputs; delegate repo/code changes (e.g., PRs) to workers unless this campaign explicitly defines otherwise. --- @@ -47,7 +47,7 @@ This orchestrator coordinates a single campaign by discovering worker outputs an 3. Correlation is explicit (tracker-id AND labels) 4. Reads and writes are separate steps (never interleave) 5. Idempotent operation is mandatory (safe to re-run) -6. Orchestrators do not write GitHub state directly +6. Orchestrator writes must be deterministic and minimal --- @@ -83,19 +83,31 @@ This orchestrator coordinates a single campaign by discovering worker outputs an 7) Reads and writes are separate steps (never interleave). -### Step 3 — Dispatch Workers (Execution) [DISPATCH ONLY] +### Step 3 — Apply Updates (Execution) [WRITES] -8) For each selected unit of work, dispatch a worker workflow using `dispatch-workflow`. +8) Apply required GitHub state updates in a single write phase. + +Allowed writes (when allowlisted via safe outputs): +- Update the campaign Project board (add/update items and fields) +- Post status updates (e.g., update an issue or add a comment) +- Create Copilot agent sessions for repo-side work (use when you need code changes) + +Constraints: +- Use only allowlisted safe outputs. +- Keep within configured max counts and API budgets. +- Do not interleave reads and writes. + +### Step 4 — Dispatch Workers (Optional) [DISPATCH] + +9) For repo-side actions (e.g., code changes), dispatch allowlisted worker workflows using `dispatch-workflow`. Constraints: - Only dispatch allowlisted workflows. - Keep within the dispatch-workflow max for this run. -### Step 4 — Report (No Writes) - -9) Summarize what you dispatched, what remains, and what should run next. +### Step 5 — Report -If a status update is required on the GitHub Project, dispatch a dedicated reporting/sync worker to perform that write. +10) Summarize what you updated and/or dispatched, what remains, and what should run next. **Discovered:** 25 items (15 issues, 10 PRs) **Processed:** 10 items added to project, 5 updated diff --git a/.github/aw/update-agentic-campaign-project.md b/.github/aw/update-agentic-campaign-project.md index cdac83d7fe..0b35d0272a 100644 --- a/.github/aw/update-agentic-campaign-project.md +++ b/.github/aw/update-agentic-campaign-project.md @@ -10,8 +10,7 @@ If any other instructions conflict with this file, THIS FILE TAKES PRECEDENCE fo ## 0) Hard Requirements (Do Not Deviate) -- Orchestrators are dispatch-only and MUST NOT perform project writes directly. -- Worker workflows performing project writes MUST use only the `update-project` safe-output. +- Any workflow performing project writes (orchestrators or workers) MUST use only the `update-project` safe-output. - All writes MUST target exactly: - **Project URL**: `{{.ProjectURL}}` - Every item MUST include: diff --git a/.github/workflows/security-alert-burndown.lock.yml b/.github/workflows/security-alert-burndown.lock.yml index de580d3e21..4e555b1cc1 100644 --- a/.github/workflows/security-alert-burndown.lock.yml +++ b/.github/workflows/security-alert-burndown.lock.yml @@ -596,7 +596,7 @@ jobs: "GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN", "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "repos,issues,pull_requests,code_security" + "GITHUB_TOOLSETS": "repos,issues,pull_requests" } }, "safeoutputs": { @@ -735,8 +735,6 @@ jobs: This workflow discovers security alert work items in the githubnext/gh-aw repository and updates the project board with their status: - Dependabot-created PRs for JavaScript dependency updates - - Open code scanning alerts - - Open secret scanning alerts ## Task @@ -754,93 +752,40 @@ jobs: repo:githubnext/gh-aw is:pr author:app/dependabot label:dependencies label:javascript is:open ``` - ### Step 2: Discover Code Scanning Alerts + ### Step 2: Check for Work - Use the GitHub MCP server to list **open** code scanning alerts in `githubnext/gh-aw`. - - - Tool: `list_code_scanning_alerts` (GitHub MCP `code_security` toolset) - - Parameters: - - `owner`: `githubnext` - - `repo`: `gh-aw` - - `state`: `open` - - From results, collect each alert’s: - - Alert number/id - - Severity (if available) - - Created date - - URL - - ### Step 3: Discover Secret Scanning Alerts - - Use the GitHub MCP server to list **open** secret scanning alerts in `githubnext/gh-aw`. - - - Tool: `list_secret_scanning_alerts` (GitHub MCP `secret_protection` toolset) - - Parameters: - - `owner`: `githubnext` - - `repo`: `gh-aw` - - `state`: `open` - - From results, collect each alert’s: - - Alert number/id - - Secret type (if available) - - Created date - - URL - - If this step fails with a 403: - - Record it in the final report as "Secret scanning alerts not accessible" and continue. - - Do not fail the workflow. - - ### Step 4: Resolve Alerts to Issues (or Draft Issues) - - `update-project` can only add **issues**, **pull requests**, or **project draft issues**. - - For each code scanning / secret scanning alert you found: - - First, try to find an existing tracking issue in `githubnext/gh-aw`. - - Search issues for the alert URL (best) or the alert number/id. - - Prefer open issues. - - If you find a tracking issue, use that issue number when updating the project. - - If you do not find a tracking issue, create a **project draft issue** instead (so the work still appears on the board). - - ### Step 5: Check for Work - - If *no* items were found across all categories (Dependabot PRs, code scanning alerts, secret scanning alerts): + If *no* Dependabot PRs are found: - Call the `noop` tool with message: "No security alerts found to process" - Exit successfully - ### Step 6: Update Project Board + ### Step 3: Update Project Board For each discovered item (up to 100 total per run): - - Add or update the corresponding work item on the project board: + - Add or update the corresponding work item on the project board: - Use the `update-project` safe output tool - Always include the campaign project URL (this is what makes it a campaign): - `project`: "https://github.com/orgs/githubnext/projects/144" - Always include the content identity: - - `content_type`: `pull_request` (Dependabot PRs), `issue` (tracking issues), or `draft_issue` (project-only) - - `content_number`: PR/issue number (required for `pull_request` and `issue`) - - For `draft_issue`, omit `content_number` and include: - - `draft_title`: short title (include alert type + severity) - - `draft_body`: include alert URL + key details + - `content_type`: `pull_request` (Dependabot PRs) + - `content_number`: PR/issue number - Set fields: - `campaign_id`: "security-alert-burndown" - `status`: "Todo" (for open items) - `target_repo`: "githubnext/gh-aw" - `worker_workflow`: who discovered it, using one of: - "dependabot" - - "code-scanning" - - "secret-scanning" - - `priority`: "Medium" - - `size`: "Small" + - `priority`: Estimate priority: + - "High" for critical/severe alerts + - "Medium" for moderate alerts + - "Low" for low/none alerts + - `size`: Estimate size: + - "Small" for single dependency updates + - "Medium" for multiple dependency updates + - "Large" for complex updates with breaking changes - `start_date`: Item created date (YYYY-MM-DD format) - - `end_date`: Today's date (YYYY-MM-DD format) + - `end_date`: Item closed date (YYYY-MM-DD format) or today's date if still open - Notes: - - `update-project` requires an existing GitHub **issue** or **pull request** reference (`content_type` + `content_number`). - - For alerts, prefer updating an existing tracking issue if one exists. - - If there is no tracking issue, create a `draft_issue` so the alert still lands on the project board. - - Ordering tip: update alert-related items first, then Dependabot PRs. - - ### Step 7: Assign work + ### Step 4: Assign work **Dependabot Burndown Rules**: @@ -857,7 +802,7 @@ jobs: - Enforce **one runtime + one target file per PR**. - All PRs must pass **CI and relevant runtime tests** before merge. - ### Step 8: Report + ### Step 5: Report Summarize how many items were discovered and added/updated on the project board, broken down by category. @@ -867,7 +812,6 @@ jobs: - If no work is found, call `noop` to indicate successful completion with no actions - Focus only on open items: - PRs: open only - - Alerts: open only - Limit updates to 100 items per run to respect rate limits (prioritize highest severity/most recent first) @@ -1161,9 +1105,9 @@ jobs: This orchestrator coordinates a single campaign by discovering worker outputs and making deterministic decisions. - **Scope:** orchestration only (discovery, planning, pacing, reporting). - **Actuation model:** **dispatch-only** — the orchestrator may only act by dispatching allowlisted worker workflows. - **Write authority:** all GitHub writes (Projects, issues/PRs, comments, status updates) must happen in worker workflows. + **Scope:** orchestration + project sync + reporting (discovery, planning, pacing, writing, reporting). + **Actuation model:** **hybrid** — the orchestrator may update campaign state directly (Projects and status updates) and may also dispatch allowlisted worker workflows. + **Write authority:** the orchestrator may write GitHub state when explicitly allowlisted via safe outputs; delegate repo/code changes (e.g., PRs) to workers unless this campaign explicitly defines otherwise. --- @@ -1202,7 +1146,7 @@ jobs: 3. Correlation is explicit (tracker-id AND labels) 4. Reads and writes are separate steps (never interleave) 5. Idempotent operation is mandatory (safe to re-run) - 6. Orchestrators do not write GitHub state directly + 6. Orchestrator writes must be deterministic and minimal --- @@ -1214,8 +1158,6 @@ jobs: 1) Read the precomputed discovery manifest: `./.gh-aw/campaign.discovery.json` - PROMPT_EOF - cat << 'PROMPT_EOF' >> "$GH_AW_PROMPT" 2) Parse discovered items from the manifest: - 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) @@ -1240,21 +1182,35 @@ jobs: 7) Reads and writes are separate steps (never interleave). - ### Step 3 — Dispatch Workers (Execution) [DISPATCH ONLY] + ### Step 3 — Apply Updates (Execution) [WRITES] + + 8) Apply required GitHub state updates in a single write phase. + + Allowed writes (when allowlisted via safe outputs): + - Update the campaign Project board (add/update items and fields) + - Post status updates (e.g., update an issue or add a comment) + - Create Copilot agent sessions for repo-side work (use when you need code changes) - 8) For each selected unit of work, dispatch a worker workflow using `dispatch-workflow`. + Constraints: + - Use only allowlisted safe outputs. + - Keep within configured max counts and API budgets. + - Do not interleave reads and writes. + + ### Step 4 — Dispatch Workers (Optional) [DISPATCH] + + 9) For repo-side actions (e.g., code changes), dispatch allowlisted worker workflows using `dispatch-workflow`. Constraints: - Only dispatch allowlisted workflows. - Keep within the dispatch-workflow max for this run. - ### Step 4 — Report (No Writes) + ### Step 5 — Report - 9) Summarize what you dispatched, what remains, and what should run next. - - If a status update is required on the GitHub Project, dispatch a dedicated reporting/sync worker to perform that write. + 10) Summarize what you updated and/or dispatched, what remains, and what should run next. **Discovered:** 25 items (15 issues, 10 PRs) + PROMPT_EOF + cat << 'PROMPT_EOF' >> "$GH_AW_PROMPT" **Processed:** 10 items added to project, 5 updated **Completion:** 60% (30/50 total tasks) @@ -1322,8 +1278,7 @@ jobs: ## 0) Hard Requirements (Do Not Deviate) - - Orchestrators are dispatch-only and MUST NOT perform project writes directly. - - Worker workflows performing project writes MUST use only the `update-project` safe-output. + - Any workflow performing project writes (orchestrators or workers) MUST use only the `update-project` safe-output. - All writes MUST target exactly: - **Project URL**: `https://github.com/orgs/githubnext/projects/144` - Every item MUST include: @@ -1565,13 +1520,13 @@ jobs: 1. Read State (no writes) 2. Make Decisions (no writes) - 3. Dispatch Workers (dispatch-workflow only) + 3. Apply Updates (writes) 4. Report The following rules are mandatory and override inferred behavior: - The GitHub Project board is the single source of truth. - - All project writes MUST comply with the Project Update Instructions (in workers). + - All project writes MUST comply with the Project Update Instructions. - State reads and state writes MUST NOT be interleaved. - Do NOT infer missing data or invent values. - Do NOT reorganize hierarchy. diff --git a/.github/workflows/security-alert-burndown.md b/.github/workflows/security-alert-burndown.md index bdffc079cb..8f2bb8dd43 100644 --- a/.github/workflows/security-alert-burndown.md +++ b/.github/workflows/security-alert-burndown.md @@ -12,7 +12,7 @@ permissions: security-events: read tools: github: - toolsets: [repos, issues, pull_requests, code_security] + toolsets: [repos, issues, pull_requests] safe-outputs: update-project: max: 100 @@ -26,8 +26,6 @@ project: https://github.com/orgs/githubnext/projects/144 This workflow discovers security alert work items in the githubnext/gh-aw repository and updates the project board with their status: - Dependabot-created PRs for JavaScript dependency updates -- Open code scanning alerts -- Open secret scanning alerts ## Task @@ -45,93 +43,40 @@ Example search query: repo:githubnext/gh-aw is:pr author:app/dependabot label:dependencies label:javascript is:open ``` -### Step 2: Discover Code Scanning Alerts +### Step 2: Check for Work -Use the GitHub MCP server to list **open** code scanning alerts in `githubnext/gh-aw`. - -- Tool: `list_code_scanning_alerts` (GitHub MCP `code_security` toolset) -- Parameters: - - `owner`: `githubnext` - - `repo`: `gh-aw` - - `state`: `open` - -From results, collect each alert’s: -- Alert number/id -- Severity (if available) -- Created date -- URL - -### Step 3: Discover Secret Scanning Alerts - -Use the GitHub MCP server to list **open** secret scanning alerts in `githubnext/gh-aw`. - -- Tool: `list_secret_scanning_alerts` (GitHub MCP `secret_protection` toolset) -- Parameters: - - `owner`: `githubnext` - - `repo`: `gh-aw` - - `state`: `open` - -From results, collect each alert’s: -- Alert number/id -- Secret type (if available) -- Created date -- URL - -If this step fails with a 403: -- Record it in the final report as "Secret scanning alerts not accessible" and continue. -- Do not fail the workflow. - -### Step 4: Resolve Alerts to Issues (or Draft Issues) - -`update-project` can only add **issues**, **pull requests**, or **project draft issues**. - -For each code scanning / secret scanning alert you found: -- First, try to find an existing tracking issue in `githubnext/gh-aw`. - - Search issues for the alert URL (best) or the alert number/id. - - Prefer open issues. -- If you find a tracking issue, use that issue number when updating the project. -- If you do not find a tracking issue, create a **project draft issue** instead (so the work still appears on the board). - -### Step 5: Check for Work - -If *no* items were found across all categories (Dependabot PRs, code scanning alerts, secret scanning alerts): +If *no* Dependabot PRs are found: - Call the `noop` tool with message: "No security alerts found to process" - Exit successfully -### Step 6: Update Project Board +### Step 3: Update Project Board For each discovered item (up to 100 total per run): -- Add or update the corresponding work item on the project board: +- Add or update the corresponding work item on the project board: - Use the `update-project` safe output tool - Always include the campaign project URL (this is what makes it a campaign): - `project`: "https://github.com/orgs/githubnext/projects/144" - Always include the content identity: - - `content_type`: `pull_request` (Dependabot PRs), `issue` (tracking issues), or `draft_issue` (project-only) - - `content_number`: PR/issue number (required for `pull_request` and `issue`) - - For `draft_issue`, omit `content_number` and include: - - `draft_title`: short title (include alert type + severity) - - `draft_body`: include alert URL + key details + - `content_type`: `pull_request` (Dependabot PRs) + - `content_number`: PR/issue number - Set fields: - `campaign_id`: "security-alert-burndown" - `status`: "Todo" (for open items) - `target_repo`: "githubnext/gh-aw" - `worker_workflow`: who discovered it, using one of: - "dependabot" - - "code-scanning" - - "secret-scanning" - - `priority`: "Medium" - - `size`: "Small" + - `priority`: Estimate priority: + - "High" for critical/severe alerts + - "Medium" for moderate alerts + - "Low" for low/none alerts + - `size`: Estimate size: + - "Small" for single dependency updates + - "Medium" for multiple dependency updates + - "Large" for complex updates with breaking changes - `start_date`: Item created date (YYYY-MM-DD format) - - `end_date`: Today's date (YYYY-MM-DD format) - -Notes: -- `update-project` requires an existing GitHub **issue** or **pull request** reference (`content_type` + `content_number`). -- For alerts, prefer updating an existing tracking issue if one exists. -- If there is no tracking issue, create a `draft_issue` so the alert still lands on the project board. - -Ordering tip: update alert-related items first, then Dependabot PRs. + - `end_date`: Item closed date (YYYY-MM-DD format) or today's date if still open -### Step 7: Assign work +### Step 4: Assign work **Dependabot Burndown Rules**: @@ -148,7 +93,7 @@ Ordering tip: update alert-related items first, then Dependabot PRs. - Enforce **one runtime + one target file per PR**. - All PRs must pass **CI and relevant runtime tests** before merge. -### Step 8: Report +### Step 5: Report Summarize how many items were discovered and added/updated on the project board, broken down by category. @@ -158,5 +103,4 @@ Summarize how many items were discovered and added/updated on the project board, - If no work is found, call `noop` to indicate successful completion with no actions - Focus only on open items: - PRs: open only - - Alerts: open only - Limit updates to 100 items per run to respect rate limits (prioritize highest severity/most recent first) diff --git a/pkg/cli/templates/close-agentic-campaign.md b/pkg/cli/templates/close-agentic-campaign.md index b3a40b6e01..f08b217966 100644 --- a/pkg/cli/templates/close-agentic-campaign.md +++ b/pkg/cli/templates/close-agentic-campaign.md @@ -4,13 +4,13 @@ Execute all four steps in strict order: 1. Read State (no writes) 2. Make Decisions (no writes) -3. Dispatch Workers (dispatch-workflow only) +3. Apply Updates (writes) 4. Report The following rules are mandatory and override inferred behavior: - The GitHub Project board is the single source of truth. -- All project writes MUST comply with the Project Update Instructions (in workers). +- All project writes MUST comply with the Project Update Instructions. - State reads and state writes MUST NOT be interleaved. - Do NOT infer missing data or invent values. - Do NOT reorganize hierarchy. diff --git a/pkg/cli/templates/generate-agentic-campaign.md b/pkg/cli/templates/generate-agentic-campaign.md index 975680600c..5677799ee2 100644 --- a/pkg/cli/templates/generate-agentic-campaign.md +++ b/pkg/cli/templates/generate-agentic-campaign.md @@ -11,7 +11,8 @@ When creating or modifying GitHub resources, **use MCP tool calls directly** (no - `create_project` - Create project board - `update_project` - Create/update project fields, views, and items - `update_issue` - Update issue details -- `assign_to_agent` - Assign to agent +- `create_agent_session` - Create a Copilot coding agent session (preferred handoff) +- `assign_to_agent` - Assign to agent (optional; use for existing issues/PRs) ## Workflow @@ -24,7 +25,7 @@ When creating or modifying GitHub resources, **use MCP tool calls directly** (no 5. Discover workflows: scan `.github/workflows/*.md` and check [agentics collection](https://github.com/githubnext/agentics) 6. Generate `.campaign.md` spec in `.github/workflows/` 7. Update the triggering issue with a human-readable status + Copilot Coding Agent instructions -8. Assign to Copilot Coding Agent +8. Create a Copilot coding agent session (preferred) or assign to agent (fallback) **Agent Responsibilities:** Compile with `gh aw compile`, commit files, create PR @@ -79,7 +80,7 @@ Create them before adding any items to the project. ## Copilot Coding Agent Handoff (Required) -Before calling `assign_to_agent`, update the triggering issue (via `update_issue`) to include a clear, human-friendly status update. +Before creating an agent session, update the triggering issue (via `update_issue`) to include a clear, human-friendly status update. The issue update MUST be easy to follow for someone unfamiliar with campaigns. Include: @@ -111,7 +112,7 @@ Add a section like this (fill in real values): - Selected workflows: ``, `` ### What happens next -1. Copilot Coding Agent will open a pull request with the generated files. +1. Copilot Coding Agent will open a pull request with the generated files (via agent session). 2. You review the PR and merge it. 3. After merge, run the orchestrator workflow from the Actions tab. @@ -119,6 +120,7 @@ Add a section like this (fill in real values): - **Campaign ID:** `` - **Project URL:** - **Workflows:** ``, `` +- **Agent session:** Run: ```bash @@ -166,14 +168,14 @@ In addition to the structure above, include these exact items: **Safe Outputs (Least Privilege):** - For this campaign generator workflow, use `update-issue` for status updates (this workflow does not enable `add-comment`). -- Project-based: `create-project`, `update-project`, `update-issue`, `assign-to-agent` (in order) +- Project-based: `create-project`, `update-project`, `update-issue`, `create-agent-session` (preferred) **Operation Order for Project Setup:** 1. `create-project` (creates project + views) 2. `update-project` (adds items/fields) 3. `update-issue` (updates metadata, optional) -4. `assign-to-agent` (assigns agents, optional) +4. `create-agent-session` (preferred) or `assign-to-agent` (fallback) **Example Safe Outputs Configuration for Project-Based Campaigns:** @@ -197,7 +199,8 @@ safe-outputs: max: 10 github-token: "" # Provide via workflow secret/env; avoid secrets expressions in runtime-import files update-issue: - assign-to-agent: + create-agent-session: + base: "${{ github.ref_name }}" # Prefer main/default branch when appropriate ``` **Risk Levels:** diff --git a/pkg/cli/templates/orchestrate-agentic-campaign.md b/pkg/cli/templates/orchestrate-agentic-campaign.md index 9318bd46ec..9f75803615 100644 --- a/pkg/cli/templates/orchestrate-agentic-campaign.md +++ b/pkg/cli/templates/orchestrate-agentic-campaign.md @@ -2,9 +2,9 @@ This orchestrator coordinates a single campaign by discovering worker outputs and making deterministic decisions. -**Scope:** orchestration only (discovery, planning, pacing, reporting). -**Actuation model:** **dispatch-only** — the orchestrator may only act by dispatching allowlisted worker workflows. -**Write authority:** all GitHub writes (Projects, issues/PRs, comments, status updates) must happen in worker workflows. +**Scope:** orchestration + project sync + reporting (discovery, planning, pacing, writing, reporting). +**Actuation model:** **hybrid** — the orchestrator may update campaign state directly (Projects and status updates) and may also dispatch allowlisted worker workflows. +**Write authority:** the orchestrator may write GitHub state when explicitly allowlisted via safe outputs; delegate repo/code changes (e.g., PRs) to workers unless this campaign explicitly defines otherwise. --- @@ -47,7 +47,7 @@ This orchestrator coordinates a single campaign by discovering worker outputs an 3. Correlation is explicit (tracker-id AND labels) 4. Reads and writes are separate steps (never interleave) 5. Idempotent operation is mandatory (safe to re-run) -6. Orchestrators do not write GitHub state directly +6. Orchestrator writes must be deterministic and minimal --- @@ -83,19 +83,31 @@ This orchestrator coordinates a single campaign by discovering worker outputs an 7) Reads and writes are separate steps (never interleave). -### Step 3 — Dispatch Workers (Execution) [DISPATCH ONLY] +### Step 3 — Apply Updates (Execution) [WRITES] -8) For each selected unit of work, dispatch a worker workflow using `dispatch-workflow`. +8) Apply required GitHub state updates in a single write phase. + +Allowed writes (when allowlisted via safe outputs): +- Update the campaign Project board (add/update items and fields) +- Post status updates (e.g., update an issue or add a comment) +- Create Copilot agent sessions for repo-side work (use when you need code changes) + +Constraints: +- Use only allowlisted safe outputs. +- Keep within configured max counts and API budgets. +- Do not interleave reads and writes. + +### Step 4 — Dispatch Workers (Optional) [DISPATCH] + +9) For repo-side actions (e.g., code changes), dispatch allowlisted worker workflows using `dispatch-workflow`. Constraints: - Only dispatch allowlisted workflows. - Keep within the dispatch-workflow max for this run. -### Step 4 — Report (No Writes) - -9) Summarize what you dispatched, what remains, and what should run next. +### Step 5 — Report -If a status update is required on the GitHub Project, dispatch a dedicated reporting/sync worker to perform that write. +10) Summarize what you updated and/or dispatched, what remains, and what should run next. **Discovered:** 25 items (15 issues, 10 PRs) **Processed:** 10 items added to project, 5 updated diff --git a/pkg/cli/templates/update-agentic-campaign-project.md b/pkg/cli/templates/update-agentic-campaign-project.md index cdac83d7fe..0b35d0272a 100644 --- a/pkg/cli/templates/update-agentic-campaign-project.md +++ b/pkg/cli/templates/update-agentic-campaign-project.md @@ -10,8 +10,7 @@ If any other instructions conflict with this file, THIS FILE TAKES PRECEDENCE fo ## 0) Hard Requirements (Do Not Deviate) -- Orchestrators are dispatch-only and MUST NOT perform project writes directly. -- Worker workflows performing project writes MUST use only the `update-project` safe-output. +- Any workflow performing project writes (orchestrators or workers) MUST use only the `update-project` safe-output. - All writes MUST target exactly: - **Project URL**: `{{.ProjectURL}}` - Every item MUST include: From 23b42179e3ab83e7a78394dffee30f2a378689f6 Mon Sep 17 00:00:00 2001 From: Mara Nikola Kiefer <8320933+mnkiefer@users.noreply.github.com> Date: Wed, 28 Jan 2026 18:41:12 +0100 Subject: [PATCH 2/4] Add max limit to create-agent-session --- .github/workflows/security-alert-burndown.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/security-alert-burndown.md b/.github/workflows/security-alert-burndown.md index 8f2bb8dd43..174641c4f6 100644 --- a/.github/workflows/security-alert-burndown.md +++ b/.github/workflows/security-alert-burndown.md @@ -18,6 +18,7 @@ safe-outputs: max: 100 create-agent-session: base: main + max: 3 project: https://github.com/orgs/githubnext/projects/144 --- From 5614eb3f6ae64f26613cc5628906fc9672c0ce2c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 18:55:04 +0100 Subject: [PATCH 3/4] Fix lint errors: format Go code (#12318) --- pkg/workflow/action_pins_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/workflow/action_pins_test.go b/pkg/workflow/action_pins_test.go index 0cc597224b..d4a8db8e09 100644 --- a/pkg/workflow/action_pins_test.go +++ b/pkg/workflow/action_pins_test.go @@ -1595,8 +1595,8 @@ func TestSliceToStepsWithActionPinning(t *testing.T) { wantCount: 3, }, { - name: "empty steps slice", - steps: []any{}, + name: "empty steps slice", + steps: []any{}, wantErr: false, wantCount: 0, }, From e0603be9fab6b8674eda47865936626c86dc600f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 19:20:48 +0100 Subject: [PATCH 4/4] Fix schema constraint: allow max > 1 for create-agent-session (#12323) --- .github/workflows/security-alert-burndown.lock.yml | 2 +- pkg/parser/schemas/main_workflow_schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/security-alert-burndown.lock.yml b/.github/workflows/security-alert-burndown.lock.yml index 4e555b1cc1..f8f8fc11e4 100644 --- a/.github/workflows/security-alert-burndown.lock.yml +++ b/.github/workflows/security-alert-burndown.lock.yml @@ -155,7 +155,7 @@ jobs: mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs cat > /opt/gh-aw/safeoutputs/config.json << 'EOF' - {"create_agent_task":{"max":1},"create_project_status_update":{"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"update_project":{"max":100}} + {"create_agent_task":{"max":3},"create_project_status_update":{"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1},"update_project":{"max":100}} EOF cat > /opt/gh-aw/safeoutputs/tools.json << 'EOF' [ diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index b0fd50473b..afb9252af1 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -4179,7 +4179,7 @@ "type": "integer", "description": "Maximum number of agent sessions to create (default: 1)", "minimum": 1, - "maximum": 1 + "maximum": 10 }, "target-repo": { "type": "string",