This is the full developer documentation for GitHub Agentic Workflows
# GitHub Agentic Workflows
> Repository automation, running the coding agents you know and love, with strong guardrails in GitHub Actions.
Imagine a world where improvements to your repositories are automatically delivered each morning, ready for you to review. Issues are automatically triaged, CI failures analyzed, documentation maintained and tests improved. All defined via simple markdown files.
GitHub Agentic Workflows deliver this: repository automation, running the coding agents you know and love, in GitHub Actions, with strong guardrails and security-first design principles.
Use GitHub Copilot, Claude by Anthropic or OpenAI Codex for event-triggered and scheduled jobs to improve your repository. GitHub Agentic Workflows [augment](https://github.github.com/gh-aw/reference/faq/#determinism) your existing, deterministic CI/CD with [Continuous AI](https://githubnext.com/projects/continuous-ai) capabilities.
Developed by GitHub Next and Microsoft Research, workflows run with added guardrails, using safe outputs and sandboxed execution to help keep your repository safe.
> ⓘ Note: GitHub Agentic Workflows is in early development and may change significantly. Using agentic workflows requires careful attention to security considerations and careful human supervision, and even then things can still go wrong. Use it with caution, and at your own risk.
## Key Features
[Section titled “Key Features”](#key-features)
### [Automated Markdown Workflows](/gh-aw/introduction/overview/#natural-language-to-github-actions)
[Write automation in markdown instead of complex YAML](/gh-aw/introduction/overview/#natural-language-to-github-actions)
### [AI-Powered Decision Making](/gh-aw/introduction/how-they-work/)
[Workflows that understand context and adapt to situations](/gh-aw/introduction/how-they-work/)
### [GitHub Integration](/gh-aw/reference/github-tools/)
[Deep integration with Actions, Issues, PRs, Discussions, and repository management](/gh-aw/reference/github-tools/)
### [Safety First](/gh-aw/introduction/architecture/)
[Sandboxed execution with minimal permissions and safe output processing](/gh-aw/introduction/architecture/)
### [Multiple AI Engines](/gh-aw/reference/engines/)
[Support for Copilot, Claude, Codex, and custom AI processors](/gh-aw/reference/engines/)
### [Continuous AI](/gh-aw/introduction/how-they-work/)
[Systematic, automated application of AI to software collaboration](/gh-aw/introduction/how-they-work/)
## Guardrails Built-In
[Section titled “Guardrails Built-In”](#guardrails-built-in)
AI agents can be manipulated into taking unintended actions—through malicious repository content, compromised tools, or prompt injection. GitHub Agentic Workflows addresses this with five security layers that work together to contain the impact of a confused or compromised agent.
### Read-only tokens
[Section titled “Read-only tokens”](#read-only-tokens)
The AI agent receives a GitHub token scoped to read-only permissions. Even if the agent attempts to create a pull request, push code, or delete a file, the underlying token simply doesn’t allow it. The agent can observe your repository; it cannot change it.
### Zero secrets in the agent
[Section titled “Zero secrets in the agent”](#zero-secrets-in-the-agent)
The agent process never receives write tokens, API keys, or other sensitive credentials. Those secrets exist only in separate, isolated jobs that run *after* the agent has finished and its output has passed review. A compromised agent has nothing to steal and no credentials to misuse.
### Containerized with a network firewall
[Section titled “Containerized with a network firewall”](#containerized-with-a-network-firewall)
The agent runs inside an isolated container. A built-in network firewall—the [Agent Workflow Firewall](/gh-aw/introduction/architecture/#agent-workflow-firewall-awf)—routes all outbound traffic through a Squid proxy enforcing an explicit domain allowlist. Traffic to any other destination is dropped at the kernel level, so a compromised agent cannot exfiltrate data or call out to unexpected servers.
### Safe outputs with strong guardrails
[Section titled “Safe outputs with strong guardrails”](#safe-outputs-with-strong-guardrails)
The agent cannot write to GitHub directly. Instead, it produces a structured artifact describing its intended actions—for example, “create an issue with this title and body.” A separate job with [scoped write permissions](/gh-aw/reference/safe-outputs/) reads that artifact and applies only what your workflow explicitly permits: hard limits per operation (such as a maximum of one issue per run), required title prefixes, and label constraints. The agent requests; a gated job decides.
### Agentic threat detection
[Section titled “Agentic threat detection”](#agentic-threat-detection)
Before any output is applied, a dedicated [threat detection job](/gh-aw/reference/threat-detection/) runs an AI-powered scan of the agent’s proposed changes. It checks for prompt injection attacks, leaked credentials, and malicious code patterns. If anything looks suspicious, the workflow fails immediately and nothing is written to your repository.
```
flowchart LR
Event[" GitHub Event"] --> Agent
subgraph Sandbox[" Isolated Container · Read-only Token · Firewall-Protected"]
Agent[" AI Agent"]
end
Agent --> Output[" Proposed Output (artifact)"]
Output --> Detect[" Threat Detection (AI-powered scan)"]
Detect -->|"✓ safe"| Write[" Write Job (scoped write token)"]
Detect -->|"✗ suspicious"| Fail[" Blocked"]
Write --> GitHub[" GitHub API"]
```
See the [Security Architecture](/gh-aw/introduction/architecture/) for a full breakdown of the layered defense-in-depth model.
## Example: Daily Issues Report
[Section titled “Example: Daily Issues Report”](#example-daily-issues-report)
Here’s a simple workflow that runs daily to create an upbeat status report:
```markdown
---
on:
schedule: daily
permissions:
contents: read
issues: read
pull-requests: read
safe-outputs:
create-issue:
title-prefix: "[team-status] "
labels: [report, daily-status]
close-older-issues: true
---
## Daily Issues Report
Create an upbeat daily status report for the team as a GitHub issue.
## What to include
- Recent repository activity (issues, PRs, discussions, releases, code changes)
- Progress tracking, goal reminders and highlights
- Project status and recommendations
- Actionable next steps for maintainers
```
The `gh aw` cli augments this with a [lock file](/gh-aw/reference/faq/#what-is-a-workflow-lock-file) for a GitHub Actions Workflow (.lock.yml) that runs an AI agent (Copilot, Claude, Codex, …) in a containerized environment on a schedule or manually.
The AI coding agent reads your repository context, analyzes issues, generates visualizations, and creates reports. All defined in natural language rather than complex code.
[📖](https://github.blog/ai-and-ml/automate-repository-tasks-with-github-agentic-workflows/)
[**Learn More on the GitHub Blog** Automate repository tasks with GitHub Agentic Workflows](https://github.blog/ai-and-ml/automate-repository-tasks-with-github-agentic-workflows/)
[→](https://github.blog/ai-and-ml/automate-repository-tasks-with-github-agentic-workflows/)
## Gallery
[Section titled “Gallery”](#gallery)
### [Issue & PR Management](/gh-aw/blog/2026-01-13-meet-the-workflows-issue-management/)
[Automated triage, labeling, and project coordination](/gh-aw/blog/2026-01-13-meet-the-workflows-issue-management/)
### [Continuous Documentation](/gh-aw/blog/2026-01-13-meet-the-workflows-documentation/)
[Continuous documentation maintenance and consistency](/gh-aw/blog/2026-01-13-meet-the-workflows-documentation/)
### [Continuous Improvement](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/)
[Daily code simplification, refactoring, and style improvements](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/)
### [Metrics & Analytics](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/)
[Daily reports, trend analysis, and workflow health monitoring](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/)
### [Quality & Testing](/gh-aw/blog/2026-01-13-meet-the-workflows-quality-hygiene/)
[CI failure diagnosis, test improvements, and quality checks](/gh-aw/blog/2026-01-13-meet-the-workflows-quality-hygiene/)
### [Multi-Repository](/gh-aw/examples/multi-repo/)
[Feature sync and cross-repo tracking workflows](/gh-aw/examples/multi-repo/)
## Getting Started
[Section titled “Getting Started”](#getting-started)
Install the extension, add a sample workflow, and trigger your first run - all from the command line in minutes.
Your browser doesn't support HTML5 video. Download the video [here](/gh-aw/videos/install-and-add-workflow-in-cli.mp4).
## Creating Workflows
[Section titled “Creating Workflows”](#creating-workflows)
Create custom agentic workflows directly from the GitHub web interface using natural language.
Your browser doesn't support HTML5 video. Download the video [here](/gh-aw/videos/create-workflow-on-github.mp4).
# Agent Factory
> Experimental agentic workflows used by the team to learn and build.
These are experimental agentic workflows used by the GitHub Next team to learn, build, and use agentic workflows. [Browse source files](https://github.com/github/gh-aw/tree/main/.github/workflows).
| Workflow | Agent | Status | Schedule | Command |
| :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :-----: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------: | :----------: |
| [/cloclo](https://github.com/github/gh-aw/blob/main/.github/workflows/cloclo.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/cloclo.lock.yml) | - | `/cloclo` |
| [ACE Editor Session](https://github.com/github/gh-aw/blob/main/.github/workflows/ace-editor.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/ace-editor.lock.yml) | - | `/ace` |
| [Agent Container Smoke Test](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-test-tools.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-test-tools.lock.yml) | - | - |
| [Agent Performance Analyzer - Meta-Orchestrator](https://github.com/github/gh-aw/blob/main/.github/workflows/agent-performance-analyzer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/agent-performance-analyzer.lock.yml) | - | - |
| [Agent Persona Explorer](https://github.com/github/gh-aw/blob/main/.github/workflows/agent-persona-explorer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/agent-persona-explorer.lock.yml) | - | - |
| [Agentic Observability Kit](https://github.com/github/gh-aw/blob/main/.github/workflows/agentic-observability-kit.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/agentic-observability-kit.lock.yml) | - | - |
| [Agentic Workflow Audit Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/audit-workflows.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/audit-workflows.lock.yml) | - | - |
| [AI Moderator](https://github.com/github/gh-aw/blob/main/.github/workflows/ai-moderator.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/ai-moderator.lock.yml) | - | - |
| [Archie](https://github.com/github/gh-aw/blob/main/.github/workflows/archie.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/archie.lock.yml) | - | `/archie` |
| [Architecture Diagram Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-architecture-diagram.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-architecture-diagram.lock.yml) | - | - |
| [Artifacts Summary](https://github.com/github/gh-aw/blob/main/.github/workflows/artifacts-summary.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/artifacts-summary.lock.yml) | - | - |
| [Auto-Assign Issue](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-assign-issue-to-user.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-assign-issue-to-user.lock.yml) | - | - |
| [Auto-Triage Issues](https://github.com/github/gh-aw/blob/main/.github/workflows/auto-triage-issues.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/auto-triage-issues.lock.yml) | - | - |
| [Automated Portfolio Analyst](https://github.com/github/gh-aw/blob/main/.github/workflows/portfolio-analyst.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/portfolio-analyst.lock.yml) | - | - |
| [Basic Research Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/research.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/research.lock.yml) | - | - |
| [Blog Auditor](https://github.com/github/gh-aw/blob/main/.github/workflows/blog-auditor.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/blog-auditor.lock.yml) | - | - |
| [Bot Detection](https://github.com/github/gh-aw/blob/main/.github/workflows/bot-detection.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/bot-detection.lock.yml) | `every 6h` | - |
| [Brave Web Search Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/brave.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/brave.lock.yml) | - | `/brave` |
| [Breaking Change Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/breaking-change-checker.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/breaking-change-checker.lock.yml) | - | - |
| [Changeset Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/changeset.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/changeset.lock.yml) | - | - |
| [CI Cleaner](https://github.com/github/gh-aw/blob/main/.github/workflows/hourly-ci-cleaner.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/hourly-ci-cleaner.lock.yml) | `15 6,18 * * *` | - |
| [CI Failure Doctor](https://github.com/github/gh-aw/blob/main/.github/workflows/ci-doctor.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/ci-doctor.lock.yml) | - | - |
| [CI Optimization Coach](https://github.com/github/gh-aw/blob/main/.github/workflows/ci-coach.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/ci-coach.lock.yml) | `daily around 13:00 on weekdays` | - |
| [Claude Code User Documentation Review](https://github.com/github/gh-aw/blob/main/.github/workflows/claude-code-user-docs-review.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/claude-code-user-docs-review.lock.yml) | - | - |
| [CLI Consistency Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/cli-consistency-checker.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/cli-consistency-checker.lock.yml) | `daily around 13:00 on weekdays` | - |
| [CLI Version Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/cli-version-checker.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/cli-version-checker.lock.yml) | - | - |
| [Code Refiner](https://github.com/github/gh-aw/blob/main/.github/workflows/refiner.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/refiner.lock.yml) | - | - |
| [Code Scanning Fixer](https://github.com/github/gh-aw/blob/main/.github/workflows/code-scanning-fixer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/code-scanning-fixer.lock.yml) | - | - |
| [Code Simplifier](https://github.com/github/gh-aw/blob/main/.github/workflows/code-simplifier.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/code-simplifier.lock.yml) | - | - |
| [Codex GitHub Remote MCP Test](https://github.com/github/gh-aw/blob/main/.github/workflows/codex-github-remote-mcp-test.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/codex-github-remote-mcp-test.lock.yml) | - | - |
| [Commit Changes Analyzer](https://github.com/github/gh-aw/blob/main/.github/workflows/commit-changes-analyzer.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/commit-changes-analyzer.lock.yml) | - | - |
| [Constraint Solving — Problem of the Day](https://github.com/github/gh-aw/blob/main/.github/workflows/constraint-solving-potd.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/constraint-solving-potd.lock.yml) | - | - |
| [Contribution Check](https://github.com/github/gh-aw/blob/main/.github/workflows/contribution-check.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/contribution-check.lock.yml) | - | - |
| [Copilot Agent PR Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-agent-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/copilot-agent-analysis.lock.yml) | - | - |
| [Copilot Agent Prompt Clustering Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/prompt-clustering-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/prompt-clustering-analysis.lock.yml) | - | - |
| [Copilot CLI Deep Research Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-cli-deep-research.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-cli-deep-research.lock.yml) | - | - |
| [Copilot PR Conversation NLP Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-nlp-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-nlp-analysis.lock.yml) | `daily around 10:00 on weekdays` | - |
| [Copilot PR Prompt Pattern Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-prompt-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-prompt-analysis.lock.yml) | - | - |
| [Copilot Session Insights](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-session-insights.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/copilot-session-insights.lock.yml) | - | - |
| [Copilot Token Usage Optimizer](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-token-optimizer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-token-optimizer.lock.yml) | `daily around 14:00 on weekdays` | - |
| [Daily Choice Type Test](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-choice-test.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-choice-test.lock.yml) | `daily around 12:00 on weekdays` | - |
| [Daily CLI Performance Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-cli-performance.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-cli-performance.lock.yml) | - | - |
| [Daily CLI Tools Exploratory Tester](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-cli-tools-tester.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-cli-tools-tester.lock.yml) | - | - |
| [Daily Code Metrics and Trend Tracking Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-code-metrics.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-code-metrics.lock.yml) | - | - |
| [Daily Community Attribution Updater](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-community-attribution.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-community-attribution.lock.yml) | - | - |
| [Daily Compiler Quality Check](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-compiler-quality.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-compiler-quality.lock.yml) | - | - |
| [Daily Copilot PR Merged Report](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-pr-merged-report.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-pr-merged-report.lock.yml) | `daily around 15:00 on weekdays` | - |
| [Daily Copilot Token Usage Audit](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-token-audit.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/copilot-token-audit.lock.yml) | `daily around 12:00 on weekdays` | - |
| [Daily DIFC Integrity-Filtered Events Analyzer](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-integrity-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-integrity-analysis.lock.yml) | - | - |
| [Daily Documentation Healer](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-doc-healer.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-doc-healer.lock.yml) | - | - |
| [Daily Documentation Updater](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-doc-updater.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-doc-updater.lock.yml) | - | - |
| [Daily Fact About gh-aw](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-fact.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/daily-fact.lock.yml) | `daily around 11:00 on weekdays` | - |
| [Daily File Diet](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-file-diet.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-file-diet.lock.yml) | `daily around 13:00 on weekdays` | - |
| [Daily Firewall Logs Collector and Reporter](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-firewall-report.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-firewall-report.lock.yml) | - | - |
| [Daily Go Function Namer](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-function-namer.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-function-namer.lock.yml) | - | - |
| [Daily Issues Report Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-issues-report.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-issues-report.lock.yml) | - | - |
| [Daily Malicious Code Scan Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-malicious-code-scan.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-malicious-code-scan.lock.yml) | - | - |
| [Daily MCP Tool Concurrency Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-mcp-concurrency-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-mcp-concurrency-analysis.lock.yml) | `daily around 9:00 on weekdays` | - |
| [Daily News](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-news.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-news.lock.yml) | `daily around 9:00 on weekdays` | - |
| [Daily Observability Report for AWF Firewall and MCP Gateway](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-observability-report.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/daily-observability-report.lock.yml) | - | - |
| [Daily OTel Instrumentation Advisor](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-otel-instrumentation-advisor.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-otel-instrumentation-advisor.lock.yml) | - | - |
| [Daily Project Performance Summary Generator (Using MCP Scripts)](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-performance-summary.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-performance-summary.lock.yml) | - | - |
| [Daily Regulatory Report Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-regulatory.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-regulatory.lock.yml) | - | - |
| [Daily Rendering Scripts Verifier](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-rendering-scripts-verifier.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-rendering-scripts-verifier.lock.yml) | - | - |
| [Daily Safe Output Integrator](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-safe-output-integrator.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-safe-output-integrator.lock.yml) | - | - |
| [Daily Safe Output Tool Optimizer](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-safe-output-optimizer.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-safe-output-optimizer.lock.yml) | - | - |
| [Daily Safe Outputs Conformance Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-safe-outputs-conformance.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-safe-outputs-conformance.lock.yml) | - | - |
| [Daily Secrets Analysis Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-secrets-analysis.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-secrets-analysis.lock.yml) | - | - |
| [Daily Security Red Team Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-security-red-team.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-security-red-team.lock.yml) | - | - |
| [Daily Semgrep Scan](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-semgrep-scan.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-semgrep-scan.lock.yml) | - | - |
| [Daily Syntax Error Quality Check](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-syntax-error-quality.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-syntax-error-quality.lock.yml) | - | - |
| [Daily Team Evolution Insights](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-team-evolution-insights.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-team-evolution-insights.lock.yml) | - | - |
| [Daily Team Status](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-team-status.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-team-status.lock.yml) | `daily around 9:00 on weekdays` | - |
| [Daily Testify Uber Super Expert](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-testify-uber-super-expert.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-testify-uber-super-expert.lock.yml) | - | - |
| [Daily Workflow Updater](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-workflow-updater.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-workflow-updater.lock.yml) | - | - |
| [Dead Code Removal Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/dead-code-remover.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/dead-code-remover.lock.yml) | - | - |
| [DeepReport - Intelligence Gathering Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/deep-report.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/deep-report.lock.yml) | `daily around 15:00 on weekdays` | - |
| [Delight](https://github.com/github/gh-aw/blob/main/.github/workflows/delight.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/delight.lock.yml) | - | - |
| [Dependabot Burner](https://github.com/github/gh-aw/blob/main/.github/workflows/dependabot-burner.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/dependabot-burner.lock.yml) | - | - |
| [Dependabot Dependency Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/dependabot-go-checker.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/dependabot-go-checker.lock.yml) | `20 9 * * 1,3,5` | - |
| [Dev](https://github.com/github/gh-aw/blob/main/.github/workflows/dev.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/dev.lock.yml) | `daily around 9:00` | - |
| [Dev Hawk](https://github.com/github/gh-aw/blob/main/.github/workflows/dev-hawk.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/dev-hawk.lock.yml) | - | - |
| [Developer Documentation Consolidator](https://github.com/github/gh-aw/blob/main/.github/workflows/developer-docs-consolidator.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/developer-docs-consolidator.lock.yml) | - | - |
| [Dictation Prompt Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/dictation-prompt.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/dictation-prompt.lock.yml) | `weekly on sunday around 6:00` | - |
| [Discussion Task Miner - Code Quality Improvement Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/discussion-task-miner.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/discussion-task-miner.lock.yml) | - | - |
| [Documentation Noob Tester](https://github.com/github/gh-aw/blob/main/.github/workflows/docs-noob-tester.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/docs-noob-tester.lock.yml) | - | - |
| [Documentation Unbloat](https://github.com/github/gh-aw/blob/main/.github/workflows/unbloat-docs.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/unbloat-docs.lock.yml) | - | `/unbloat` |
| [Draft PR Cleanup](https://github.com/github/gh-aw/blob/main/.github/workflows/draft-pr-cleanup.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/draft-pr-cleanup.lock.yml) | - | - |
| [Duplicate Code Detector](https://github.com/github/gh-aw/blob/main/.github/workflows/duplicate-code-detector.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/duplicate-code-detector.lock.yml) | - | - |
| [Example: Properly Provisioned Permissions](https://github.com/github/gh-aw/blob/main/.github/workflows/example-permissions-warning.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/example-permissions-warning.lock.yml) | - | - |
| [Firewall Test Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/firewall.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/firewall.lock.yml) | - | - |
| [Functional Pragmatist](https://github.com/github/gh-aw/blob/main/.github/workflows/functional-pragmatist.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/functional-pragmatist.lock.yml) | `25 9 * * 2,4` | - |
| [GitHub API Consumption Report Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/api-consumption-report.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/api-consumption-report.lock.yml) | - | - |
| [GitHub MCP Remote Server Tools Report Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/github-mcp-tools-report.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/github-mcp-tools-report.lock.yml) | - | - |
| [GitHub MCP Structural Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/github-mcp-structural-analysis.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/github-mcp-structural-analysis.lock.yml) | `daily around 11:00 on weekdays` | - |
| [GitHub Remote MCP Authentication Test](https://github.com/github/gh-aw/blob/main/.github/workflows/github-remote-mcp-auth-test.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/github-remote-mcp-auth-test.lock.yml) | - | - |
| [Glossary Maintainer](https://github.com/github/gh-aw/blob/main/.github/workflows/glossary-maintainer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/glossary-maintainer.lock.yml) | `daily around 10:00 on weekdays` | - |
| [Go Fan](https://github.com/github/gh-aw/blob/main/.github/workflows/go-fan.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/go-fan.lock.yml) | `daily around 7:00 on weekdays` | - |
| [Go Logger Enhancement](https://github.com/github/gh-aw/blob/main/.github/workflows/go-logger.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/go-logger.lock.yml) | - | - |
| [Go Pattern Detector](https://github.com/github/gh-aw/blob/main/.github/workflows/go-pattern-detector.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/go-pattern-detector.lock.yml) | `daily around 14:00 on weekdays` | - |
| [GPL Dependency Cleaner (gpclean)](https://github.com/github/gh-aw/blob/main/.github/workflows/gpclean.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/gpclean.lock.yml) | - | - |
| [Grumpy Code Reviewer](https://github.com/github/gh-aw/blob/main/.github/workflows/grumpy-reviewer.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/grumpy-reviewer.lock.yml) | - | `/grumpy` |
| [Instructions Janitor](https://github.com/github/gh-aw/blob/main/.github/workflows/instructions-janitor.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/instructions-janitor.lock.yml) | - | - |
| [Issue Arborist](https://github.com/github/gh-aw/blob/main/.github/workflows/issue-arborist.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/issue-arborist.lock.yml) | - | - |
| [Issue Monster](https://github.com/github/gh-aw/blob/main/.github/workflows/issue-monster.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/issue-monster.lock.yml) | - | - |
| [Issue Summary to Notion](https://github.com/github/gh-aw/blob/main/.github/workflows/notion-issue-summary.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/notion-issue-summary.lock.yml) | - | - |
| [Issue Triage Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/issue-triage-agent.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/issue-triage-agent.lock.yml) | - | - |
| [jsweep - JavaScript Unbloater](https://github.com/github/gh-aw/blob/main/.github/workflows/jsweep.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/jsweep.lock.yml) | - | - |
| [Layout Specification Maintainer](https://github.com/github/gh-aw/blob/main/.github/workflows/layout-spec-maintainer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/layout-spec-maintainer.lock.yml) | `weekly on monday around 7:00` | - |
| [Lockfile Statistics Analysis Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/lockfile-stats.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/lockfile-stats.lock.yml) | - | - |
| [MCP Inspector Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/mcp-inspector.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/mcp-inspector.lock.yml) | - | - |
| [Mergefest](https://github.com/github/gh-aw/blob/main/.github/workflows/mergefest.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/mergefest.lock.yml) | - | `/mergefest` |
| [Metrics Collector - Infrastructure Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/metrics-collector.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/metrics-collector.lock.yml) | - | - |
| [Multi-Device Docs Tester](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-multi-device-docs-tester.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/daily-multi-device-docs-tester.lock.yml) | - | - |
| [Organization Health Report](https://github.com/github/gh-aw/blob/main/.github/workflows/org-health-report.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/org-health-report.lock.yml) | - | - |
| [Plan Command](https://github.com/github/gh-aw/blob/main/.github/workflows/plan.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/plan.lock.yml) | - | `/plan` |
| [Poem Bot - A Creative Agentic Workflow](https://github.com/github/gh-aw/blob/main/.github/workflows/poem-bot.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/poem-bot.lock.yml) | - | `/poem` |
| [PR Nitpick Reviewer](https://github.com/github/gh-aw/blob/main/.github/workflows/pr-nitpick-reviewer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/pr-nitpick-reviewer.lock.yml) | - | `/nit` |
| [PR Triage Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/pr-triage-agent.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/pr-triage-agent.lock.yml) | - | - |
| [Python Data Visualization Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/python-data-charts.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/python-data-charts.lock.yml) | - | - |
| [Q](https://github.com/github/gh-aw/blob/main/.github/workflows/q.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/q.lock.yml) | - | `/q` |
| [Rebuild the documentation after making changes](https://github.com/github/gh-aw/blob/main/.github/workflows/technical-doc-writer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/technical-doc-writer.lock.yml) | - | - |
| [Release](https://github.com/github/gh-aw/blob/main/.github/workflows/release.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/release.lock.yml) | - | - |
| [Repository Audit & Agentic Workflow Opportunity Analyzer](https://github.com/github/gh-aw/blob/main/.github/workflows/repo-audit-analyzer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/repo-audit-analyzer.lock.yml) | - | - |
| [Repository Quality Improvement Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/repository-quality-improver.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/repository-quality-improver.lock.yml) | `daily around 13:00 on weekdays` | - |
| [Repository Tree Map Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/repo-tree-map.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/repo-tree-map.lock.yml) | - | - |
| [Resource Summarizer Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/pdf-summary.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/pdf-summary.lock.yml) | - | `/summarize` |
| [Safe Output Health Monitor](https://github.com/github/gh-aw/blob/main/.github/workflows/safe-output-health.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/safe-output-health.lock.yml) | - | - |
| [Schema Consistency Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/schema-consistency-checker.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/schema-consistency-checker.lock.yml) | - | - |
| [Schema Feature Coverage Checker](https://github.com/github/gh-aw/blob/main/.github/workflows/schema-feature-coverage.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/schema-feature-coverage.lock.yml) | - | - |
| [Scout](https://github.com/github/gh-aw/blob/main/.github/workflows/scout.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/scout.lock.yml) | - | `/scout` |
| [Security Compliance Campaign](https://github.com/github/gh-aw/blob/main/.github/workflows/security-compliance.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/security-compliance.lock.yml) | - | - |
| [Security Review Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/security-review.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/security-review.lock.yml) | - | `/security` |
| [Semantic Function Refactoring](https://github.com/github/gh-aw/blob/main/.github/workflows/semantic-function-refactor.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/semantic-function-refactor.lock.yml) | - | - |
| [Sergo - Serena Go Expert](https://github.com/github/gh-aw/blob/main/.github/workflows/sergo.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/sergo.lock.yml) | - | - |
| [Slide Deck Maintainer](https://github.com/github/gh-aw/blob/main/.github/workflows/slide-deck-maintainer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/slide-deck-maintainer.lock.yml) | `daily around 16:00 on weekdays` | - |
| [Smoke Agent: all/merged](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-all-merged.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-all-merged.lock.yml) | - | - |
| [Smoke Agent: all/none](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-all-none.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-all-none.lock.yml) | - | - |
| [Smoke Agent: public/approved](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-public-approved.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-public-approved.lock.yml) | - | - |
| [Smoke Agent: public/none](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-public-none.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-public-none.lock.yml) | - | - |
| [Smoke Agent: scoped/approved](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-agent-scoped-approved.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-agent-scoped-approved.lock.yml) | - | - |
| [Smoke Call Workflow](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-call-workflow.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/smoke-call-workflow.lock.yml) | - | - |
| [Smoke Claude](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-claude.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/smoke-claude.lock.yml) | - | - |
| [Smoke Codex](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-codex.md) | codex | [](https://github.com/github/gh-aw/actions/workflows/smoke-codex.lock.yml) | - | - |
| [Smoke Copilot](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-copilot.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-copilot.lock.yml) | - | - |
| [Smoke Copilot ARM64](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-copilot-arm.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-copilot-arm.lock.yml) | - | - |
| [Smoke Create Cross-Repo PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-create-cross-repo-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-create-cross-repo-pr.lock.yml) | - | - |
| [Smoke Gemini](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-gemini.md) | gemini | [](https://github.com/github/gh-aw/actions/workflows/smoke-gemini.lock.yml) | - | - |
| [Smoke Multi PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-multi-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-multi-pr.lock.yml) | - | - |
| [Smoke Project](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-project.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-project.lock.yml) | - | - |
| [Smoke Service Ports](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-service-ports.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-service-ports.lock.yml) | - | - |
| [Smoke Temporary ID](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-temporary-id.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-temporary-id.lock.yml) | - | - |
| [Smoke Update Cross-Repo PR](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-update-cross-repo-pr.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-update-cross-repo-pr.lock.yml) | - | - |
| [Smoke Workflow Call](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-workflow-call.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-workflow-call.lock.yml) | - | - |
| [Smoke Workflow Call with Inputs](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-workflow-call-with-inputs.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/smoke-workflow-call-with-inputs.lock.yml) | - | - |
| [Stale Repository Identifier](https://github.com/github/gh-aw/blob/main/.github/workflows/stale-repo-identifier.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/stale-repo-identifier.lock.yml) | - | - |
| [Static Analysis Report](https://github.com/github/gh-aw/blob/main/.github/workflows/static-analysis-report.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/static-analysis-report.lock.yml) | - | - |
| [Step Name Alignment](https://github.com/github/gh-aw/blob/main/.github/workflows/step-name-alignment.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/step-name-alignment.lock.yml) | `daily` | - |
| [Sub-Issue Closer](https://github.com/github/gh-aw/blob/main/.github/workflows/sub-issue-closer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/sub-issue-closer.lock.yml) | - | - |
| [Super Linter Report](https://github.com/github/gh-aw/blob/main/.github/workflows/super-linter.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/super-linter.lock.yml) | `daily around 14:00 on weekdays` | - |
| [Terminal Stylist](https://github.com/github/gh-aw/blob/main/.github/workflows/terminal-stylist.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/terminal-stylist.lock.yml) | - | - |
| [Test Create PR Error Handling](https://github.com/github/gh-aw/blob/main/.github/workflows/test-create-pr-error-handling.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/test-create-pr-error-handling.lock.yml) | - | - |
| [Test Dispatcher Workflow](https://github.com/github/gh-aw/blob/main/.github/workflows/test-dispatcher.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/test-dispatcher.lock.yml) | - | - |
| [Test Project URL Explicit Requirement](https://github.com/github/gh-aw/blob/main/.github/workflows/test-project-url-default.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/test-project-url-default.lock.yml) | - | - |
| [Test Workflow](https://github.com/github/gh-aw/blob/main/.github/workflows/test-workflow.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/test-workflow.lock.yml) | - | - |
| [The Daily Repository Chronicle](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-repo-chronicle.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/daily-repo-chronicle.lock.yml) | `daily around 16:00 on weekdays` | - |
| [The Great Escapi](https://github.com/github/gh-aw/blob/main/.github/workflows/firewall-escape.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/firewall-escape.lock.yml) | - | - |
| [Tidy](https://github.com/github/gh-aw/blob/main/.github/workflows/tidy.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/tidy.lock.yml) | `daily around 7:00` | - |
| [Typist - Go Type Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/typist.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/typist.lock.yml) | `daily around 11:00 on weekdays` | - |
| [Ubuntu Actions Image Analyzer](https://github.com/github/gh-aw/blob/main/.github/workflows/ubuntu-image-analyzer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/ubuntu-image-analyzer.lock.yml) | - | - |
| [Update Astro](https://github.com/github/gh-aw/blob/main/.github/workflows/update-astro.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/update-astro.lock.yml) | - | - |
| [Video Analysis Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/video-analyzer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/video-analyzer.lock.yml) | - | - |
| [Weekly Blog Post Writer](https://github.com/github/gh-aw/blob/main/.github/workflows/weekly-blog-post-writer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/weekly-blog-post-writer.lock.yml) | - | - |
| [Weekly Editors Health Check](https://github.com/github/gh-aw/blob/main/.github/workflows/weekly-editors-health-check.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/weekly-editors-health-check.lock.yml) | - | - |
| [Weekly Issue Summary](https://github.com/github/gh-aw/blob/main/.github/workflows/weekly-issue-summary.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/weekly-issue-summary.lock.yml) | `weekly on monday around 15:00` | - |
| [Weekly Safe Outputs Specification Review](https://github.com/github/gh-aw/blob/main/.github/workflows/weekly-safe-outputs-spec-review.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/weekly-safe-outputs-spec-review.lock.yml) | `weekly on monday` | - |
| [Weekly Workflow Analysis](https://github.com/github/gh-aw/blob/main/.github/workflows/example-workflow-analyzer.md) | claude | [](https://github.com/github/gh-aw/actions/workflows/example-workflow-analyzer.lock.yml) | - | - |
| [Workflow Craft Agent](https://github.com/github/gh-aw/blob/main/.github/workflows/craft.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/craft.lock.yml) | - | `/craft` |
| [Workflow Generator](https://github.com/github/gh-aw/blob/main/.github/workflows/workflow-generator.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/workflow-generator.lock.yml) | - | - |
| [Workflow Health Manager - Meta-Orchestrator](https://github.com/github/gh-aw/blob/main/.github/workflows/workflow-health-manager.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/workflow-health-manager.lock.yml) | - | - |
| [Workflow Normalizer](https://github.com/github/gh-aw/blob/main/.github/workflows/workflow-normalizer.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/workflow-normalizer.lock.yml) | - | - |
| [Workflow Skill Extractor](https://github.com/github/gh-aw/blob/main/.github/workflows/workflow-skill-extractor.md) | copilot | [](https://github.com/github/gh-aw/actions/workflows/workflow-skill-extractor.lock.yml) | - | - |
Note
Badges update automatically. Click badges for run details or workflow names for source files.
# Welcome to Peli's Agent Factory
> It's basically a candy shop chocolate factory of agentic workflows.

Welcome, welcome, WELCOME to Peli’s Agent Factory!
Imagine a software repository where AI agents work alongside your team - not replacing developers, but handling the repetitive, time-consuming tasks that slow down collaboration and forward progress.
Peli’s Agent Factory is our exploration of what happens when you take the design philosophy of **“let’s create a new automated agentic workflow for that”** as the answer to almost every opportunity that arises! What happens when you **max out on automated agentic workflows** - when you make and use dozens of specialized, automated AI agentic workflows and use them in practice.
Software development is changing rapidly. This is our attempt to understand how automated agentic AI can make software teams more efficient, collaborative, and more enjoyable.
It’s basically a candy shop chocolate factory of agentic workflows. And we’d like to share it with you.
Let’s explore together!
## What Is Peli’s Agent Factory?
[Section titled “What Is Peli’s Agent Factory?”](#what-is-pelis-agent-factory)
Peli’s factory is a collection of [**automated agentic workflows**](https://gh.io/gh-aw) we use in practice. We have built and operated **over 100 automated agentic workflows** within the [`github/gh-aw`](https://github.com/github/gh-aw) repository. These were used mostly in the context of the [`github/gh-aw`](https://github.com/github/gh-aw) project itself, but some have also been applied at scale in GitHub internal repositories. These weren’t hypothetical demos - they were working agents that:
* [Triage incoming issues](/gh-aw/blog/2026-01-13-meet-the-workflows/)
* [Diagnose CI failures](/gh-aw/blog/2026-01-13-meet-the-workflows-quality-hygiene/)
* [Maintain documentation](/gh-aw/blog/2026-01-13-meet-the-workflows-documentation/)
* [Improve test coverage](/gh-aw/blog/2026-01-13-meet-the-workflows-testing-validation/)
* [Monitor security compliance](/gh-aw/blog/2026-01-13-meet-the-workflows-security-compliance/)
* [Optimize workflow efficiency](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/)
* [Execute multi-day projects](/gh-aw/blog/2026-01-13-meet-the-workflows-multi-phase/)
* Even [write poetry to boost team morale](/gh-aw/blog/2026-01-13-meet-the-workflows-creative-culture/)
Some workflows are [“read-only analysts”](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/). Others [proactively propose changes through pull requests](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/). Some are [meta-agents that monitor and improve the health of other workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/).
We know we’re taking things to an extreme here. Most repositories won’t need dozens of agentic workflows. No one can read all these outputs (except, of course, another workflow). But by pushing the boundaries, we learned valuable lessons about what works, what doesn’t, and how to design safe, effective agentic workflows that teams can trust and use.
## Why Build a Factory?
[Section titled “Why Build a Factory?”](#why-build-a-factory)
When we started exploring agentic workflows, we faced a fundamental question: **What should repository-level automated agentic workflows actually do?**
Rather than trying to build one “perfect” agent, we took a broad, heterogeneous approach:
1. **Embrace diversity** - Create many specialized workflows as we identified opportunities
2. **Use them continuously** - Run them in real development workflows
3. **Observe what works** - Find which patterns work and which fail
4. **Share the knowledge** - Catalog the structures that make agents safe and effective
The factory becomes both an experiment and a reference collection - a living library of patterns that others can study, adapt, and remix. Each workflow is written in natural language using Markdown, then converted into secure [GitHub Actions](https://github.com/features/actions) that run with carefully scoped permissions with guardrails. Everything is observable, auditable, and remixable.
## Meet the Workflows
[Section titled “Meet the Workflows”](#meet-the-workflows)
In our first series, [Meet the Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows/), we’ll take you on a tour of the most interesting agents in the factory. Each article is bite-sized. If you’d like to skip ahead, here’s the full list of articles in the series:
1. [Meet a Simple Triage Workflow](/gh-aw/blog/2026-01-13-meet-the-workflows/)
2. [Introducing Continuous Simplicity](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/)
3. [Introducing Continuous Refactoring](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-refactoring/)
4. [Introducing Continuous Style](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-style/)
5. [Introducing Continuous Improvement](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-improvement/)
6. [Introducing Continuous Documentation](/gh-aw/blog/2026-01-13-meet-the-workflows-documentation/)
After that we have a cornucopia of specialized workflow categories for you to dip into:
* [Meet the Issue & PR Management Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-issue-management/)
* [Meet the Fault Investigation Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-quality-hygiene/)
* [Meet the Metrics & Analytics Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/)
* [Meet the Operations & Release Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-operations-release/)
* [Meet the Security-related Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-security-compliance/)
* [Meet the Teamwork & Culture Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-creative-culture/)
* [Meet the Interactive & ChatOps Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-interactive-chatops/)
* [Meet the Testing & Validation Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-testing-validation/)
* [Meet the Tool & Infrastructure Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-tool-infrastructure/)
* [Introducing Multi-Phase Improver Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-multi-phase/)
* [Meet the Organization & Cross-Repo Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-organization/)
* [Go Deep with Advanced Analytics & ML Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-advanced-analytics/)
* [Go Deep with Project Coordination Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows-campaigns/)
Every post comes with instructions about how to add the workflow to your own repository, or cusomtize and remix it to create your own variant.
## What We’re Learning
[Section titled “What We’re Learning”](#what-were-learning)
Running this many agents in production is a learning experience! We’ve watched agents succeed spectacularly and fail in instructive ways. Over the next few weeks, we’ll also be sharing what we’ve learned through a series of detailed articles. We’ll be looking at the design and operational patterns we’ve discovered, security lessons, and practical guides for building your own workflows.
To give a taste, some key lessons are emerging:
* **Repository-level automation is powerful** - Agents embedded in the development workflow can have outsized impact
* **Specialization reveals possibilities** - Focused agents allowed us to find more useful applications of automation than a single monolithic coding agent
* **Guardrails enable innovation** - Strict constraints actually make it easier to experiment safely
* **Meta-agents are valuable** - Agents that watch other agents become incredibly valuable
* **Cost-quality tradeoffs are real** - Longer analyses aren’t always better
We’ll dive deeper into these lessons in upcoming articles.
## Try It Yourself
[Section titled “Try It Yourself”](#try-it-yourself)
Want to start with automated agentic workflows on GitHub? See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[Meet the Workflows](/gh-aw/blog/2026-01-13-meet-the-workflows/)** - The 19-part tour of the workflows
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Credits
[Section titled “Credits”](#credits)
**Peli’s Agent Factory** is by GitHub Next, Microsoft Research and collaborators, including Peli de Halleux, Don Syme, Mara Kiefer, Edward Aftandilian, Russell Horton, Jiaxiao Zhou. This is part of GitHub Next’s exploration of [Continuous AI](https://githubnext.com/projects/continuous-ai) - making AI-enriched automation as routine as CI/CD.
## Factory Status
[Section titled “Factory Status”](#factory-status)
[Current Factory Status](/gh-aw/agent-factory-status/)
# Meet the Workflows: Issue Triage
> A curated tour of triage and summarization workflows in the factory

Welcome back to [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
We’re the GitHub Next team. Over the past months, we’ve built and operated a collection of automated agentic workflows. These aren’t just demos - these are real agents doing actual work in our [`github/gh-aw`](https://github.com/github/gh-aw) repository and others.
Think of this as your guided tour through our agent factory. We’re showcasing the workflows that caught our attention. Every workflow links to its source markdown file, so you can peek under the hood and see exactly how it works.
## Starting Simple: Automated Issue Triage
[Section titled “Starting Simple: Automated Issue Triage”](#starting-simple-automated-issue-triage)
To start the tour, let’s begin with one of the simpler workflows that **handles incoming activity** - issue triage.
Issue triage represents a “hello world” of automated agentic workflows: practical, immediately useful, relatively simple, and impactful. It’s used as the starter example in other agentic automation technologies like [Claude Code in GitHub Actions](https://code.claude.com/docs/en/github-actions).
When a new issue is opened, the triage agent analyzes its content, does research in the codebase and other issues, responds with a comment, and applies appropriate labels based on predefined categories. This helps maintainers quickly understand the nature of incoming issues without manual review.
Let’s take a look at the full **[Issue Triage Agent](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/issue-triage-agent.md?plain=1)**:
```markdown
---
timeout-minutes: 5
on:
issue:
types: [opened, reopened]
permissions:
issues: read
tools:
github:
toolsets: [issues, labels]
safe-outputs:
add-labels:
allowed: [bug, feature, enhancement, documentation, question, help-wanted, good-first-issue]
add-comment: {}
---
# Issue Triage Agent
List open issues in ${{ github.repository }} that have no labels. For each
unlabeled issue, analyze the title and body, then add one of the allowed
labels: `bug`, `feature`, `enhancement`, `documentation`, `question`,
`help-wanted`, or `good-first-issue`.
Skip issues that:
- Already have any of these labels
- Have been assigned to any user (especially non-bot users)
Do research on the issue in the context of the codebase and, after
adding the label to an issue, mention the issue author in a comment, explain
why the label was added and give a brief summary of how the issue may be
addressed.
```
Note how concise this is - it’s like reading a to-do list for the agent. The workflow runs whenever a new issue is opened or reopened. It checks for unlabeled issues, analyzes their content, and applies appropriate labels based on content analysis. It even leaves a friendly comment explaining the label choice.
In the frontmatter, we define [permissions](/gh-aw/reference/frontmatter/#permissions-permissions), [tools](/gh-aw/reference/tools/), and [safe outputs](/gh-aw/reference/safe-outputs/). This ensures the agent only has access to what it needs and can’t perform any unsafe actions. The natural language instructions in the body guide the agent’s behavior in a clear, human-readable way.
Issue triage workflows in public repositories may need to process issues from all contributors. By default, `min-integrity: approved` restricts agent visibility to owners, members, and collaborators. If you are a maintainer in a public repository and need your triage agent to see and label issues from users without push access, set `min-integrity: none` in your GitHub tools configuration. See [Integrity Filtering](/gh-aw/reference/integrity/) for security considerations and best practices.
We’ve deliberately kept this workflow ultra-simple. In practice, in your own repo, **customization** is key. Triage differs in every repository. Tailoring workflows to your specific context will make them more effective. Generic agents are okay, but customized ones are often a better fit.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add this workflow to your own repository and remix it as follows:
**Issue Triage Agent:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/issue-triage-agent.md
```
Then edit and remix the workflow specification to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Next Up: Code Quality & Refactoring Workflows
[Section titled “Next Up: Code Quality & Refactoring Workflows”](#next-up-code-quality--refactoring-workflows)
Now that we’ve explored how triage workflows help us stay on top of incoming activity, let’s turn to something far more radical and powerful: agents that continuously improve code.
Continue reading: [Continuous Simplicity →](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/)
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
***
*This is part 1 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Advanced Analytics & ML
> A curated tour of workflows that use ML to extract insights from agent behavior

*Ooh!* Time to plunge into the *data wonderland* at [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! Where numbers dance and patterns sing!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-organization/), we explored organization and cross-repo workflows that operate at enterprise scale - analyzing dozens of repositories together to find patterns and outliers that single-repo analysis would miss. We learned that perspective matters: what looks normal in isolation might signal drift at scale.
Beyond tracking basic metrics (run time, cost, success rate), we wanted deeper insights into *how* our agents actually behave and *how* developers interact with them. What patterns emerge from thousands of agent prompts? What makes some PR conversations more effective than others? How do usage patterns reveal improvement opportunities? This is where we brought out the big guns: machine learning, natural language processing, sentiment analysis, and clustering algorithms. Advanced analytics workflows don’t just count things - they understand them, finding patterns and insights that direct observation would never reveal.
## Advanced Analytics & ML Workflows
[Section titled “Advanced Analytics & ML Workflows”](#advanced-analytics--ml-workflows)
These agents use sophisticated analysis techniques to extract insights:
* **[Copilot Session Insights](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/copilot-session-insights.md?plain=1)** - Analyzes Copilot coding agent usage patterns and metrics - **32 analysis discussions**
* **[Copilot PR NLP Analysis](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/copilot-pr-nlp-analysis.md?plain=1)** - Natural language processing on PR conversations
* **[Prompt Clustering Analysis](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/prompt-clustering-analysis.md?plain=1)** - Clusters and categorizes agent prompts using ML - **27 analysis discussions**
* **[Copilot Agent Analysis](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/copilot-agent-analysis.md?plain=1)** - Deep analysis of agent behavior patterns - **48 daily analysis discussions**
Prompt Clustering Analysis has created **27 analysis discussions** using ML to categorize thousands of agent prompts - for example, [#6918](https://github.com/github/gh-aw/discussions/6918) clustering agent prompts to identify patterns and optimization opportunities. It revealed patterns we never noticed (“oh, 40% of our prompts are about error handling”).
Copilot PR NLP Analysis applies natural language processing to PR conversations, performing sentiment analysis and identifying linguistic patterns across agent interactions. It found that PRs with questions in the title get faster review.
Copilot Session Insights has created **32 analysis discussions** examining Copilot coding agent usage patterns and metrics across the workflow ecosystem. It identifies common patterns and failure modes.
Copilot Coding Agent Analysis has created **48 daily analysis discussions** providing deep analysis of agent behavior patterns - for example, [#6913](https://github.com/github/gh-aw/discussions/6913) with the daily Copilot coding agent analysis.
What we learned: **meta-analysis is powerful** - using AI to analyze AI systems reveals insights that direct observation misses. These workflows helped us understand not just what our agents do, but *how* they behave and how users interact with them.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix it as follows:
**Copilot Session Insights:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/copilot-agent-analysis.md
```
**Copilot PR NLP Analysis:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/copilot-pr-nlp-analysis
```
**Prompt Clustering Analysis:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/prompt-clustering-analysis.md
```
**Copilot Agent Analysis:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/copilot-agent-analysis.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Project Coordination Workflows
[Section titled “Next Up: Project Coordination Workflows”](#next-up-project-coordination-workflows)
We’ve reached the final stop: coordinating multiple agents toward shared, complex goals across extended timelines.
Continue reading: [Project Coordination Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-campaigns/)
***
*This is part 18 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Project Coordination
> A curated tour of workflows that coordinate multi-agent projects

My dear friends, we’ve arrived at the *grand finale* - the most spectacular room of all in [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
We’ve journeyed through 18 categories of workflows - from triage bots to code quality improvers, from security guards to creative poets, culminating in [advanced analytics](/gh-aw/blog/2026-01-13-meet-the-workflows-advanced-analytics/) that use machine learning to understand agent behavior patterns. Each workflow handles its individual task admirably.
But here’s the ultimate challenge: how do you coordinate *multiple* agents working toward a shared goal? How do you break down a large initiative like “migrate all workflows to a new engine” into trackable sub-tasks that different agents can tackle? How do you monitor progress, alert on delays, and ensure the whole is greater than the sum of its parts? This final post explores planning, task-decomposition and project coordination workflows - the orchestration layer that proves AI agents can handle not just individual tasks, but entire structured projects requiring careful coordination and progress tracking.
## Planning & Project Coordination Workflows
[Section titled “Planning & Project Coordination Workflows”](#planning--project-coordination-workflows)
These agents coordinate multi-agent plans and projects:
* **[Plan Command](https://github.com/github/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/plan.md?plain=1)** - Breaks down issues into actionable sub-tasks via `/plan` command - **514 merged PRs out of 761 proposed (67% merge rate)**
* **[Discussion Task Miner](https://github.com/github/gh-aw/tree/2c1f68a721ae7b3b67d0c2d93decf1fa5bcf7ee3/.github/workflows/discussion-task-miner.md?plain=1)** - Extracts actionable tasks from discussion threads - **60 merged PRs out of 105 proposed (57% merge rate)**
Plan Command has contributed **514 merged PRs out of 761 proposed (67% merge rate)**, providing on-demand task decomposition that breaks complex issues into actionable sub-tasks. This is the **highest-volume workflow by attribution** in the entire factory. Developers can comment `/plan` on any issue to get an AI-generated breakdown into actionable sub-issues that agents can work on. A verified example causal chain: [Discussion #7631](https://github.com/github/gh-aw/discussions/7631) → [Issue #8058](https://github.com/github/gh-aw/issues/8058) → [PR #8110](https://github.com/github/gh-aw/pull/8110).
Discussion Task Miner has contributed **60 merged PRs out of 105 proposed (57% merge rate)**, continuously scanning discussions to extract actionable tasks that might otherwise be lost. The workflow demonstrates perfect causal chain attribution: when it creates an issue from a discussion, and Copilot Coding Assistant later fixes that issue, the resulting PR is correctly attributed to Discussion Task Miner. A verified example: [Discussion #13934](https://github.com/github/gh-aw/discussions/13934) → [Issue #14084](https://github.com/github/gh-aw/issues/14084) → [PR #14129](https://github.com/github/gh-aw/pull/14129). Recent merged examples include [fixing firewall SSL-bump field extraction](https://github.com/github/gh-aw/pull/13920) and [adding security rationale to permissions documentation](https://github.com/github/gh-aw/pull/13918).
We learned that individual agents are great at focused tasks, but orchestrating multiple agents toward a shared goal requires careful architecture. Project coordination isn’t just about breaking down work - it’s about discovering work (Task Miner), planning work (Plan Command), and tracking work (Workflow Health Manager).
These workflows implement patterns like epic issues, progress tracking, and deadline management. They prove that AI agents can handle not just individual tasks, but entire projects when given proper coordination infrastructure.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Plan Command:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/plan.md
```
**Discussion Task Miner:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/discussion-task-miner.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
***
## What We’ve Learned
[Section titled “What We’ve Learned”](#what-weve-learned)
Throughout this 19-part journey, we’ve explored workflows spanning from simple triage bots to sophisticated multi-phase improvers, from security guards to creative poets, from individual task automation to organization-wide orchestration.
The key insight? **AI agents are most powerful when they’re specialized, well-coordinated, and designed for their specific context.** No single agent does everything - instead, we have an ecosystem where each agent excels at its particular job, and they work together through careful orchestration.
We’ve learned that observability is essential, that incremental progress beats heroic efforts, that security needs careful boundaries, and that even “fun” workflows can drive meaningful engagement. We’ve discovered that AI agents can maintain documentation, manage campaigns, analyze their own behavior, and continuously improve codebases - when given the right architecture and guardrails.
As you build your own agentic workflows, remember: start small, measure everything, iterate based on real usage, and don’t be afraid to experiment. The workflows we’ve shown you evolved through experimentation and real-world use. Yours will too.
*This is part 19 (final) of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Continuous Improvement
> Agents that take a holistic view of repository health

Welcome back to [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous posts](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/), we’ve explored autonomous cleanup agents. Now we complete the picture with agents that analyze dependencies, type safety, and overall repository quality.
## Continuous Improvement Workflows
[Section titled “Continuous Improvement Workflows”](#continuous-improvement-workflows)
* **[Go Module Usage Expert (aka Go Fan)](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/go-fan.md?plain=1)** - Daily Go module usage reviewer
* **[Typist](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/typist.md?plain=1)** - Analyzes type usage patterns for improved safety
* **[Functional Pragmatist](https://github.com/github/gh-aw/blob/main/.github/workflows/functional-programming-enhancer.md?plain=1)** - Applies functional techniques pragmatically
* **[Repository Quality Improver](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/repository-quality-improver.md?plain=1)** - Holistic code quality analysis
### Go Module Usage Expert: The Dependency Enthusiast
[Section titled “Go Module Usage Expert: The Dependency Enthusiast ”](#go-module-usage-expert-the-dependency-enthusiast-)
The **Go Module Usage Expert** is perhaps the most uniquely characterized workflow in the factory - an “enthusiastic Go module expert” who performs daily deep-dive reviews of the project’s Go dependencies. This isn’t just dependency scanning - it’s thoughtful analysis of **how well we’re using the tools we’ve chosen**.
Most dependency tools focus on vulnerabilities or outdated versions. Go Module Usage Expert asks deeper and more positive questions: Are we using this module’s best features? Have recent updates introduced better patterns we should adopt? Could we use a more appropriate module for this use case? Are we following the module’s recommended practices?
Go Module Usage Expert uses an intelligent selection algorithm. It extracts direct dependencies from `go.mod`, fetches GitHub metadata for each dependency including last update time, sorts by recency to prioritize recently updated modules, uses round-robin selection to cycle through modules ensuring comprehensive coverage, and maintains persistent memory through cache-memory to track which modules were recently reviewed.
This ensures recently updated modules get reviewed first since new features might be relevant, all modules eventually get reviewed so nothing is forgotten, and reviews don’t repeat unnecessarily thanks to cache tracking.
For each module, Go Module Usage Expert researches the repository (releases, docs, best practices), analyzes actual usage patterns using Serena, and generates actionable recommendations. It saves summaries under `scratchpad/mods/` and opens GitHub Discussions.
The output of Go Module Usage Expert is a discussion, which is then often “task mined” for actionable tasks using the [TaskOps](https://github.github.com/gh-aw/patterns/task-ops/) design pattern.
Let’s take a look at an example of how this works:
1. Go Module Usage Expert created the [Go Module Review: actionlint](https://github.com/github/gh-aw/discussions/7472) discussion after noticing the `actionlint` module was updated.
2. Peli [requested the Plan agent](https://github.com/github/gh-aw/discussions/7472#discussioncomment-15342254) mine for actionable tasks.
3. This created [a parent issue](https://github.com/github/gh-aw/issues/7648) and 5 sub-tasks.
4. The subtasks were then solved by further workflow runs. An example PR is [Implement parallel multi-file actionlint execution](https://github.com/github/gh-aw/issues/7649).
Through this multi-agent causal chain pattern, Go Module Usage Expert has generated **58 merged PRs out of 74 proposed (78% merge rate)** across 67 module reviews. Notable chains include: spinner improvements (4 PRs from [briandowns/spinner review](https://github.com/github/gh-aw/discussions/5094)), MCP SDK v1.2.0 upgrade (5 PRs from [go-sdk review](https://github.com/github/gh-aw/discussions/7710)), and terminal styling overhaul (3 PRs from [lipgloss review](https://github.com/github/gh-aw/discussions/5158)).
### Typist: The Type Safety Advocate
[Section titled “Typist: The Type Safety Advocate”](#typist-the-type-safety-advocate)
The **Typist** analyzes Go type usage patterns with a singular focus: improving type safety. It hunts for untyped code that should be strongly typed, and identifies duplicated type definitions that create confusion.
Typist looks for untyped usages: `interface{}` or `any` where specific types would be better, untyped constants that should have explicit types, and type assertions that could be eliminated with better design. It also hunts for duplicated type definitions - the same types defined in multiple packages, similar types with different names, and type aliases that could be unified.
Using grep patterns and Serena’s semantic analysis, it discovers type definitions, identifies semantic duplicates, analyzes untyped usage patterns, and generates refactoring recommendations.
Typist also uses the [TaskOps](https://github.github.com/gh-aw/patterns/task-ops/) pattern. This means the job of Typist is not to fix code, but to analyze code and recommend possible improvements.
Let’s take a look at an example of this in practice:
* Typist created the [Typist - Go Type Consistency Analysis Report](https://github.com/github/gh-aw/discussions/4082). This used grep and other tools to perform acomprehensive analysis examining 208 non-test Go files.
* The report found 477 instances of `map[string]any` usage, 36 untyped constants and 30+ uses `any` in function signatures.
* [Peli requested `/plan` on that issue](https://github.com/github/gh-aw/discussions/4082#discussioncomment-14983559), causing the Plan agent to do further research and create 5 issues for work to be done such as [Create unified ToolsConfig struct in tools\_types.go](https://github.com/github/gh-aw/issues/4155).
* 4/5 of these issues were then solved by Copilot. For example [Add unified ToolsConfig struct to replace map\[string\]any pattern](https://github.com/github/gh-aw/pull/4158).
Through this multi-agent causal chain, Typist has produced **19 merged PRs out of 25 proposed (76% merge rate)** from 57 discussions → 22 issues → 25 PRs. The blog example (Discussion #4082 → Issue #4155 → PR #4158) is a verified causal chain.
The static v. dynamic typing debate has raged for decades. Today’s hybrid languages like Go, C#, TypeScript and F# support both strong and dynamic typing. Continuous typing improvement offers **a new and refreshing perspective on this old debate**: rather than enforcing strict typing upfront, we can develop quickly with flexibility, then let autonomous agents like Typist trail behind, strengthening type safety over time. This allows us to get the best of both worlds: rapid development without getting bogged down in type design, while still achieving strong typing and safety as the codebase matures.
### Functional Pragmatist: The Pragmatic Purist
[Section titled “Functional Pragmatist: The Pragmatic Purist ”](#functional-pragmatist-the-pragmatic-purist-)
**Functional Pragmatist** applies moderate functional programming techniques to improve code clarity and safety, balancing pragmatism with functional principles.
The workflow focuses on seven patterns: immutability, functional initialization, transformative operations (map/filter/reduce), functional options pattern, avoiding shared mutable state, pure functions, and reusable logic wrappers.
It searches for opportunities (mutable variables, imperative loops, initialization anti-patterns, global state), scores by safety/clarity/testability improvements, uses Serena for deep analysis, and implements changes like converting to composite literals, using functional options, eliminating globals, extracting pure functions, and creating reusable wrappers (Retry, WithTiming, Memoize).
The workflow is pragmatic: Go’s simple style is respected, for-loops stay when clearer, and abstraction is added only where it genuinely improves code. It runs Tuesday and Thursday mornings, systematically improving patterns over time.
An example PR from our own use of this workflow is [Apply functional programming and immutability improvements](https://github.com/github/gh-aw/pull/12921).
Functional Pragmatist (originally named “Functional Enhancer”) is a recent addition - so far it has created **2 PRs (both merged, 100% merge rate)**, demonstrating that its pragmatic approach to functional patterns is well-received.
### Repository Quality Improver: The Holistic Analyst
[Section titled “Repository Quality Improver: The Holistic Analyst”](#repository-quality-improver-the-holistic-analyst)
**Repository Quality Improver** takes the widest view, selecting a different *focus area* each day to analyze the repository from that perspective.
It uses cache memory to ensure diverse coverage: 60% custom areas (repository-specific concerns), 30% standard categories (code quality, documentation, testing, security, performance), and 10% revisits for consistency.
Standard categories cover fundamentals. Custom areas are repository-specific: error message consistency, CLI flag naming conventions, workflow YAML generation patterns, console output formatting, configuration validation.
The workflow loads recent history, selects the next area, spends 20 minutes on deep analysis, generates discussions with recommendations, and saves state. It looks for cross-cutting concerns that don’t fit neatly into other categories but impact overall quality.
Example reports from our own use of this workflow are:
* [Repository Quality Improvement - CI/CD Optimization](https://github.com/github/gh-aw/discussions/6863)
* [Repository Quality Improvement Report - Performance](https://github.com/github/gh-aw/discussions/13280).
Through its multi-agent causal chain (59 discussions → 30 issues → 40 PRs), Repository Quality Improver has produced **25 merged PRs out of 40 proposed (62% merge rate)**, taking a holistic view of quality from multiple angles.
## The Power of Continuous Improvement
[Section titled “The Power of Continuous Improvement”](#the-power-of-continuous-improvement)
These workflows complete the autonomous improvement picture: Go Module Usage Expert keeps dependencies fresh, Typist strengthens type safety, Functional Pragmatist applies functional techniques, and Repository Quality Improver maintains coherence.
Combined with earlier workflows, we have agents improving code at every level: line-level output (Terminal Stylist), function-level complexity (Code Simplifier), file-level organization (Semantic Function Refactor), pattern-level consistency (Go Pattern Detector), functional clarity (Functional Pragmatist), type safety (Typist), module dependencies (Go Module Usage Expert), and repository coherence (Repository Quality Improver).
This is the future of code quality: not periodic cleanup sprints, but continuous autonomous improvement across every dimension simultaneously.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Go Module Usage Expert:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/go-fan.md
```
**Typist:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/typist.md
```
**Functional Pragmatist:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/main/.github/workflows/functional-programming-enhancer.md
```
**Repository Quality Improver:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/repository-quality-improver.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Next Up: Continuous Documentation
[Section titled “Next Up: Continuous Documentation”](#next-up-continuous-documentation)
Beyond code quality, we need to keep documentation accurate and up-to-date as code evolves. How do we maintain docs that stay current?
Continue reading: [Continuous Documentation Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-documentation/)
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
***
*This is part 5 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Continuous Refactoring
> Agents that identify structural improvements and systematically refactor code

Welcome back to [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/), we met automated agents that detect complexity and propose simpler solutions. These work tirelessly in the background, cleaning things up. Now let’s explore similar agents that take a deeper structural view, extending the automation to *structural refactoring*.
## Continuous Refactoring
[Section titled “Continuous Refactoring”](#continuous-refactoring)
Our next two agents continuously analyze code structure, suggesting systematic improvements:
* **[Semantic Function Refactor](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/semantic-function-refactor.md?plain=1)** - Spots refactoring opportunities we might have missed
* **[Large File Simplifier](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-file-diet.md?plain=1)** - Monitors file sizes and proposes splitting oversized files
The **Semantic Function Refactor** workflow combines agentic AI with code analysis tools to analyze and address the structure of the entire codebase. It analyzes all Go source files in the `pkg/` directory to identify functions that might be in the wrong place.
As codebases evolve, functions sometimes end up in files where they don’t quite belong. Humans struggle to notice these organizational issues because we work on one file at a time and focus on making code work rather than on where it lives.
The workflow performs comprehensive discovery by
1. algorithmically collecting all function names from non-test Go files, then
2. agentically grouping functions semantically by name and purpose.
It then identifies functions that don’t fit their current file’s theme as outliers, uses Serena-powered semantic code analysis to detect potential duplicates, and creates issues recommending consolidated refactoring. These issues can then be reviewed and addressed by coding agents.
The workflow follows a “one file per feature” principle: files should be named after their primary purpose, and functions within each file should align with that purpose. It closes existing open issues with the `[refactor]` prefix before creating new ones. This prevents issue accumulation and ensures recommendations stay current.
In our extended use of Semantic Function Refactoring, the workflow has driven **112 merged PRs out of 142 proposed (79% merge rate)** through causal chains - creating 99 refactoring issues that downstream agents turn into code changes. For example, [issue #12291](https://github.com/github/gh-aw/issues/12291) analyzing code organization opportunities led to [PR #12363 splitting permissions.go into focused modules](https://github.com/github/gh-aw/pull/12363) (928→133 lines).
An example PR from our own use of this workflow is [Move misplaced extraction functions to frontmatter\_extraction.go](https://github.com/github/gh-aw/pull/7043).
### Large File Simplifier: The Size Monitor
[Section titled “Large File Simplifier: The Size Monitor”](#large-file-simplifier-the-size-monitor)
Large files are a common code smell - they often indicate unclear boundaries, mixed responsibilities, or accumulated complexity. The **Large File Simplifier** workflow monitors file sizes daily and creates actionable issues when files grow too large.
The workflow runs on weekdays, analyzing all Go source files in the `pkg/` directory. It identifies the largest file, checks if it exceeds healthy size thresholds, and creates a detailed issue proposing how to split it into smaller, more focused files.
What makes this workflow effective is its focus and prioritization. Instead of overwhelming developers with issues about every large file, it creates at most one issue, targeting the largest offender. The workflow also skips if an open `[file-diet]` issue already exists, preventing duplicate work.
In our extended use, Large File Simplifier (also known as “Daily File Diet”) has driven **26 merged PRs out of 33 proposed (79% merge rate)** through causal chains - creating 37 file-diet issues targeting the largest files, which downstream agents turn into modular code changes. For example, [issue #12535](https://github.com/github/gh-aw/issues/12535) targeting add\_interactive.go led to [PR #12545 refactoring it into 6 domain-focused modules](https://github.com/github/gh-aw/pull/12545).
The workflow uses Serena for semantic code analysis to understand function relationships and propose logical boundaries for splitting. It both counts lines and analyzes the code structure to suggest meaningful module boundaries that make sense.
## The Power of Continuous Refactoring
[Section titled “The Power of Continuous Refactoring”](#the-power-of-continuous-refactoring)
These workflows demonstrate how AI agents can continuously maintain institutional knowledge about code organization. The benefits compound over time: better organization makes code easier to find, consistent patterns reduce cognitive load, reduced duplication improves maintainability, and clean structure attracts further cleanliness. They’re particularly valuable in AI-assisted development, where code gets written quickly and organizational concerns can take a backseat to functionality.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Semantic Function Refactor:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/semantic-function-refactor.md
```
**Large File Simplifier:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-file-diet.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Next Up: Continuous Style
[Section titled “Next Up: Continuous Style”](#next-up-continuous-style)
Beyond structure and organization, there’s another dimension of code quality: presentation and style. How do we maintain beautiful, consistent console output and formatting?
Continue reading: [Meet the Workflows: Continuous Style →](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-style/)
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
***
*This is part 3 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Continuous Simplicity
> Agents that detect complexity and propose simpler solutions

Ah, what marvelous timing! Come, come, let me show you the *next wonders* in [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows/), we explored how a simple triage workflow helps us stay on top of incoming activity - automatically labeling issues and reducing cognitive load.
Now let’s meet the agents that work quietly in the background to keep code simple and clean. These workflows embody a powerful principle: **code quality is not a destination, it’s a continuous practice**. While developers race ahead implementing features and fixing bugs, autonomous cleanup agents trail behind, constantly sweeping, polishing, and simplifying. Let’s meet the agents that hunt for complexity.
## Continuous Simplicity
[Section titled “Continuous Simplicity”](#continuous-simplicity)
The next two agents represent different aspects of code simplicity: detecting *overcomplicated code* and *duplicated logic*:
* **[Automatic Code Simplifier](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/code-simplifier.md?plain=1)** - Analyzes recently modified code and creates PRs with simplifications
* **[Duplicate Code Detector](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/duplicate-code-detector.md?plain=1)** - Uses Serena’s semantic analysis to identify duplicate code patterns
The **Automatic Code Simplifier** runs daily, analyzing recently modified code for opportunities to simplify without changing functionality. It looks at what changed in the last few commits and asks: “Could this be clearer? Could it be shorter? Could it be more idiomatic?”
This workflow is particularly valuable after rapid development sessions. When you’re racing to implement a feature or fix a bug, code often becomes more complex than necessary. Variables get temporary names, logic becomes nested, error handling gets verbose. The workflow tirelessly cleans up after these development sessions, creating PRs that preserve functionality while improving clarity, consistency, and maintainability.
The kinds of simplifications it proposes range from extracting repeated logic into helper functions to converting nested if-statements to early returns. It spots opportunities to simplify boolean expressions, use standard library functions instead of custom implementations, and consolidate similar error handling patterns.
Code Simplifier is a recent addition - so far it has created **6 PRs (5 merged, 83% merge rate)**, such as [extracting an action mode helper to reduce code duplication](https://github.com/github/gh-aw/pull/13982) and [simplifying validation config code for clarity](https://github.com/github/gh-aw/pull/13118).
The **Duplicate Code Detector** uses traditional, road-tested semantic code analysis in conjunction with agentic reasoning to find duplicate patterns. It understands code *meaning* rather than just textual similarity, catching patterns where:
* The same logic appears with different variable names
* Similar functions exist across different files
* Repeated patterns could be extracted into utilities
* Structure is duplicated even if implementation differs
What makes this workflow special is its use of semantic analysis through [Serena](https://oraios.github.io/serena/) - a powerful coding agent toolkit capable of turning an LLM into a fully-featured agent that works directly on your codebase. When we use Serena, we understand code at the compiler-resolved level, not just syntax.
The workflow focuses on recent changes in the latest commits, intelligently filtering out test files, workflows, and non-code files. It creates issues only for significant duplication: patterns spanning more than 10 lines or appearing in 3 or more locations. It performs a multi-phase analysis. It starts by setting up Serena’s semantic environment for the repository, then finds changed `.go` and `.cjs` files while excluding tests and workflows. Using `get_symbols_overview` and `find_symbol`, it understands structure, identifies similar function signatures and logic blocks, and compares symbol overviews across files for deeper similarities. It creates issues with the `[duplicate-code]` prefix and limits itself to 3 issues per run, preventing overwhelm. Issues include specific file references, code snippets, and refactoring suggestions.
In our extended use of Duplicate Code Detector, the agent has raised **76 merged PRs out of 96 proposed (79% merge rate)**, demonstrating sustained practical value of semantic code analysis. Recent examples include [refactoring expired-entity cleanup scripts to share expiration processing](https://github.com/github/gh-aw/pull/13420) and [refactoring safe-output update handlers to eliminate duplicate control flow](https://github.com/github/gh-aw/pull/8791).
## Continuous AI for Simplicity - A New Paradigm
[Section titled “Continuous AI for Simplicity - A New Paradigm”](#continuous-ai-for-simplicity---a-new-paradigm)
Together, these workflows point towards **an emerging shift in how we maintain code quality**. Instead of periodic “cleanup sprints” or waiting for code reviews to catch complexity, we have agents that clean up after us and continuously monitor and propose improvements. This is especially valuable in AI-assisted development. When developers use AI to write code faster, these cleanup agents ensure speed doesn’t sacrifice simplicity. They understand the same patterns that humans recognize but apply them consistently across the entire codebase, every day.
The workflows never take a day off, never get tired, and never let technical debt accumulate. They embody the principle that *good enough* can always become *better*, and that incremental improvements compound over time.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Automatic Code Simplifier:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/code-simplifier.md
```
**Duplicate Code Detector:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/duplicate-code-detector.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Next Up: Continuous Refactoring
[Section titled “Next Up: Continuous Refactoring”](#next-up-continuous-refactoring)
Simplification is just the beginning. Beyond removing complexity, we can use agents to continuously improve code in many more ways. Our next posts explore this topic.
Continue reading: [Continuous Refactoring →](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-refactoring/)
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
***
*This is part 2 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Continuous Style
> The agent that makes console output beautiful and consistent

Welcome back to [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous posts](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/), we’ve explored how autonomous cleanup agents work continuously in the background, simplifying code and improving structure. Today’s post is dedicated to one agent, and the larger admirable concept it represents: continuously making things *beautiful*.
## A Continuous Style Workflow
[Section titled “A Continuous Style Workflow”](#a-continuous-style-workflow)
Today’s post is dedicated to one agent, and the larger concept it represents: the **[Terminal Stylist](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/terminal-stylist.md?plain=1)** workflow. This agent’s purpose is to **make things look better**, by reviewing and enhancing the style of command-line interface (CLI) output.
Command-line interfaces are a primary interaction point for developer tools. When output is inconsistent or noisy, it still “works,” but it adds friction. When it’s well-styled, information becomes scannable, color highlights what matters, layouts remain readable across light and dark themes, and the overall experience feels professional.
Under the hood, the workflow looks for non-test Go files with console-related code and patterns such as `fmt.Print*`, `console.*`, and Lipgloss usage. It then checks for consistency in formatting helpers (especially for errors), sensible TTY-aware rendering, and accessible color choices. When it finds rough edges, it proposes concrete improvements, such as replacing plain output like `fmt.Println("Error: compilation failed")` with `fmt.Fprintln(os.Stderr, console.FormatErrorMessage("Compilation failed"))`, or swapping ad-hoc ANSI coloring for adaptive Lipgloss styles.
Rather than opening issues or PRs, the Terminal Stylist posts GitHub Discussions in the “General” category. Styling changes are often subjective, and discussions make it easier to converge on the right balance between simplicity and polish.
Terminal Stylist demonstrates multi-agent collaboration at its best. The workflow created **31 daily analysis reports** as discussions, which were then mined by Discussion Task Miner and Plan Command into **25 actionable issues**. Those issues spawned **16 merged PRs (80% merge rate)** improving console output across the codebase - from [Charmbracelet best practices adoption](https://github.com/github/gh-aw/pull/9928) to [progress bars](https://github.com/github/gh-aw/pull/8731) to [stderr routing fixes](https://github.com/github/gh-aw/pull/12302). Terminal Stylist never creates PRs directly; instead, it identifies opportunities that other agents implement, showing how workflows can collaborate through GitHub’s discussion → issue → PR pipeline.
The Terminal Stylist is proof that autonomous cleanup agents can have surprisingly specific taste. It focuses on terminal UI craft, using the Charmbracelet ecosystem (especially Lipgloss and Huh) to keep the CLI not just correct, but pleasant to use.
## The Art of Continuous Style
[Section titled “The Art of Continuous Style”](#the-art-of-continuous-style)
The Terminal Stylist shows that autonomous improvement isn’t limited to structure and correctness; it also covers user experience. By continuously reviewing output patterns, it helps new features match the project’s visual language, keeps styling aligned with evolving libraries, and nudges the CLI toward accessibility and clarity.
This is especially useful in AI-assisted development, where quick suggestions tend to default to `fmt.Println`. The Terminal Stylist cleans up after the AI, bringing that output back in line with the project’s conventions.
Continuous Style is a new frontier in code quality. It recognizes that how code *looks* matters just as much as how it *works*. By automating style reviews, we ensure that every interaction with our tools feels polished and professional.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add this workflow to your own repository and remix it as follows:
**Terminal Stylist:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/terminal-stylist.md
```
Then edit and remix the workflow specification to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Next Up: Continuous Improvement
[Section titled “Next Up: Continuous Improvement”](#next-up-continuous-improvement)
Beyond simplicity, structure, and style, there’s a final dimension: holistic quality improvement. How do we analyze dependencies, type safety, and overall repository health?
Continue reading: [Continuous Improvement Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-improvement/)
## Learn More
[Section titled “Learn More”](#learn-more)
Learn more about **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)**, try the **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** guide, and explore **[Charmbracelet](https://charm.sh/)**, the terminal UI ecosystem referenced by the Terminal Stylist.
***
*This is part 4 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Teamwork & Culture
> A curated tour of creative and culture workflows that bring joy to work

*Oh, my dear friends!* Let’s explore the *playful workshop* - the most fun corner of [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-security-compliance/), we explored security and compliance workflows - the essential guardrails that manage vulnerability campaigns, validate network security, and prevent credential exposure. These workflows let us sleep soundly knowing our agents operate within safe boundaries.
But here’s the thing: work doesn’t have to be all business. While we’ve built serious, production-critical workflows for quality, releases, and security, we also discovered something unexpected - AI agents can bring joy, build team culture, and create moments of delight. Not every workflow needs to solve a critical problem; some can simply make your day better. Let’s explore the playful side of our agent factory, where we learned that personality and fun drive engagement just as powerfully as utility.
## Teamwork & Culture Workflows
[Section titled “Teamwork & Culture Workflows”](#teamwork--culture-workflows)
These agents facilitate team communication and remind us that work can be fun:
* **[Daily Team Status](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-team-status.md?plain=1)** - Shares team mood and status updates - **22 issues**, **17 discussions** (plus 2 causal chain PRs!)
* **[Daily News](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-news.md?plain=1)** - Curates relevant news for the team - **45 news digest discussions**
* **[Poem Bot](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/poem-bot.md?plain=1)** - Responds to `/poem-bot` commands with creative verses (yes, really)
* **[Weekly Issue Summary](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/weekly-issue-summary.md?plain=1)** - Creates digestible summaries complete with charts and trends - **5 weekly analysis discussions**
* **[Daily Repo Chronicle](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-repo-chronicle.md?plain=1)** - Narrates the day’s activity like a storyteller - **6 chronicle discussions**
The Poem Bot started as a whimsy in our Copilot for PRs project in 2022. Someone said “wouldn’t it be funny if we had an agent that writes poems about our code?” and then we built it. Poem Bot responds to `/poem-bot` commands with creative verses about code, adding a touch of whimsy to the development workflow. We learned that AI agents don’t have to be all business - they can build culture and create moments of joy.
Daily News has created **45 news digest discussions** curating relevant developments for the team - for example, [#6932](https://github.com/github/gh-aw/discussions/6932) with the daily status roundup. It shares links, adds commentary and connects them to our work.
Daily Team Status has created **22 issues** and **17 discussions** sharing daily team status updates - for example, [#6930](https://github.com/github/gh-aw/discussions/6930) with the daily team status report. Two of its issues even led to merged PRs by downstream agents, showing that even “soft” workflows can drive concrete improvements.
Weekly Issue Summary has created **5 weekly analysis discussions** with digestible summaries, charts, and trends - for example, [#5844](https://github.com/github/gh-aw/discussions/5844) analyzing the week of December 1-8, 2025.
Daily Repo Chronicle has created **6 chronicle discussions** narrating the repository’s activity like a storyteller - for example, [#6750](https://github.com/github/gh-aw/discussions/6750) chronicling a development surge with 42 active PRs.
A theme here is the **reduction of cognitive load**. Having agents summarize and narrate daily activity means we don’t have to mentally parse long lists of issues or PRs. Instead, we get digestible stories that highlight what’s important. This frees up mental bandwidth for actual work.
Another theme is that **tone** can help make things more enjoyable. The Daily Repo Chronicle started writing summaries in a narrative, almost journalistic style. The outputs from AI agents don’t have to be robotic - they can have personality while still being informative.
These communication workflows help build team cohesion and remind us that work can be delightful.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Daily Team Status:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-team-status.md
```
**Daily News:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-news.md
```
**Poem Bot:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/poem-bot.md
```
**Weekly Issue Summary:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/weekly-issue-summary.md
```
**Daily Repo Chronicle:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-repo-chronicle.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Summon an Agent on Demand
[Section titled “Next Up: Summon an Agent on Demand”](#next-up-summon-an-agent-on-demand)
Scheduled workflows are great, but sometimes you need help *right now*. Enter ChatOps and interactive workflows.
Continue reading: [Interactive & ChatOps Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-interactive-chatops/)
***
*This is part 12 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Continuous Documentation
> A curated tour of workflows that maintain high-quality documentation

Step right up, step right up, and enter the *documentation chamber* of [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! Pure imagination meets technical accuracy in this most delightful corner of our establishment!
In our [previous posts](/gh-aw/blog/2026-01-13-meet-the-workflows-continuous-simplicity/), we explored autonomous cleanup agents - workflows that continuously improve code quality by simplifying complexity, refactoring structure, polishing style, and maintaining overall repository health. These agents never take a day off, quietly working to make our codebase better.
Now let’s address one of software development’s eternal challenges: keeping documentation accurate and up-to-date. Code evolves rapidly; docs… not so much. Terminology drifts, API examples become outdated, slide decks grow stale, and blog posts reference deprecated features. The question isn’t “can AI agents write good documentation?” but rather “can they maintain it as code changes?” Documentation and content workflows challenge conventional wisdom about AI-generated technical content. Spoiler: the answer involves human review, but it’s way better than the alternative (no docs at all).
## Continuous Documentation Workflows
[Section titled “Continuous Documentation Workflows”](#continuous-documentation-workflows)
These agents maintain high-quality documentation and content:
* **[Daily Documentation Updater](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-doc-updater.md?plain=1)** - Reviews and updates documentation to ensure accuracy and completeness - **57 merged PRs out of 59 proposed (96% merge rate)**
* **[Glossary Maintainer](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/glossary-maintainer.md?plain=1)** - Keeps glossary synchronized with codebase - **10 merged PRs out of 10 proposed (100% merge rate)**
* **[Documentation Unbloat](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/unbloat-docs.md?plain=1)** - Reviews and simplifies documentation by reducing verbosity - **88 merged PRs out of 103 proposed (85% merge rate)**
* **[Documentation Noob Tester](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/docs-noob-tester.md?plain=1)** - Tests documentation as a new user would, identifying confusing steps - **9 merged PRs (43% merge rate)** via causal chain
* **[Slide Deck Maintainer](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/slide-deck-maintainer.md?plain=1)** - Maintains presentation slide decks - **2 merged PRs out of 5 proposed (40% merge rate)**
* **[Multi-device Docs Tester](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-multi-device-docs-tester.md?plain=1)** - Tests documentation site across mobile, tablet, and desktop devices - **2 merged PRs out of 2 proposed (100% merge rate)**
* **[Blog Auditor](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/blog-auditor.md?plain=1)** - Verifies blog posts are accessible and contain expected content - **6 audits completed** (5 passed, 1 flagged issues)
Documentation is where we challenged conventional wisdom. Can AI agents write *good* documentation?
The **Technical Doc Writer** generates API docs from code, but more importantly, it *maintains* them - updating docs when code changes. The Glossary Maintainer caught terminology drift (“we’re using three different terms for the same concept”).
The **Slide Deck Maintainer** keeps our presentation materials current without manual updates.
The **Multi-device Docs Tester** uses Playwright to verify our documentation site works across phones, tablets, and desktops - testing responsive layouts, accessibility, and interactive elements. It catches visual regressions and layout issues that only appear on specific screen sizes.
The **Blog Auditor** ensures our blog posts stay accurate as the codebase evolves - it flags outdated code examples and broken links. Blog Auditor is a **validation-only workflow** that creates audit reports rather than code changes. It has run **6 audits** (5 passed, [1 flagged out-of-date content](https://github.com/github/gh-aw/issues/2162)), confirming blog accuracy.
Documentation Noob Tester deserves special mention for its exploratory nature. It has produced **9 merged PRs out of 21 proposed (43% merge rate)** through a causal chain: 62 discussions analyzed → 21 issues created → 21 PRs. The lower merge rate reflects this workflow’s exploratory nature - it identifies many potential improvements, some of which are too ambitious for immediate implementation. For example, [Discussion #8477](https://github.com/github/gh-aw/discussions/8477) led to [Issue #8486](https://github.com/github/gh-aw/issues/8486) which spawned PRs [#8716](https://github.com/github/gh-aw/pull/8716) and [#8717](https://github.com/github/gh-aw/pull/8717), both merged.
AI-generated docs need human/agent review, but they’re dramatically better than *no* docs (which is often the alternative). Validation can be automated to a large extent, freeing writers to focus on content shaping, topic, clarity, tone, and accuracy.
In this collection of agents, we took a heterogeneous approach - some workflows generate content, others maintain it, and still others validate it. Other approaches are possible - all tasks can be rolled into a single agent. We found that it’s easier to explore the space by using multiple agents, to separate concerns, and that encouraged us to use agents for other communication outputs such as blogs and slides.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Daily Documentation Updater:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-doc-updater.md
```
**Glossary Maintainer:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/glossary-maintainer.md
```
**Documentation Unbloat:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/unbloat-docs.md
```
**Documentation Noob Tester:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/docs-noob-tester.md
```
**Slide Deck Maintainer:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/slide-deck-maintainer.md
```
**Multi-device Docs Tester:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-multi-device-docs-tester.md
```
**Blog Auditor:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/blog-auditor.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Issue & PR Management Workflows
[Section titled “Next Up: Issue & PR Management Workflows”](#next-up-issue--pr-management-workflows)
Beyond writing code and docs, we need to manage the flow of issues and pull requests. How do we keep collaboration smooth and efficient?
Continue reading: [Issue & PR Management Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-issue-management/)
***
*This is part 6 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Interactive & ChatOps
> A curated tour of interactive workflows that respond to commands

*Onwards, onwards!* Let’s keep exploring the wonders of [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! To the *command center* where instant magic happens!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-creative-culture/), we explored creative and culture workflows - agents that bring joy, build team culture, and create moments of delight. We discovered that AI agents don’t have to be all business; they can have personality while making work more enjoyable.
But sometimes you need help *right now*, at the exact moment you’re stuck on a problem. You don’t want to wait for a scheduled run - you want to summon an expert agent with a command. That’s where interactive workflows and ChatOps come in. These agents respond to slash commands and GitHub reactions, providing on-demand assistance with full context of the current situation.
We learned that the right agent at the right moment with the right information is a valuable addition to an agent portfolio.
## Interactive & ChatOps Workflows
[Section titled “Interactive & ChatOps Workflows”](#interactive--chatops-workflows)
These agents respond to commands, providing on-demand assistance whenever you need it:
* **[Q](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/q.md?plain=1)** - Workflow optimizer that investigates performance and creates PRs - **69 merged PRs out of 88 proposed (78% merge rate)**
* **[Grumpy Reviewer](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/grumpy-reviewer.md?plain=1)** - Performs critical code reviews with personality - creates issues for downstream agents
* **[Workflow Generator](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/workflow-generator.md?plain=1)** - Creates new workflows from issue requests - scaffolds workflow files
Interactive workflows changed how we think about agent invocation. Instead of everything running on a schedule, these respond to slash commands and reactions - `/q` summons the workflow optimizer, a reaction triggers analysis. Q (yes, named after the James Bond quartermaster) became our go-to troubleshooter - it has contributed **69 merged PRs out of 88 proposed (78% merge rate)**, responding to commands and investigating workflow issues on demand. Recent examples include [fixing the daily-fact workflow action-tag](https://github.com/github/gh-aw/pull/14127) and [configuring PR triage reports with 1-day expiration](https://github.com/github/gh-aw/pull/13903).
The Grumpy Reviewer performs opinionated code reviews, creating issues that flag security risks and code quality concerns (e.g., [#13990](https://github.com/github/gh-aw/issues/13990) about risky event triggers) for downstream agents to fix. It gave us surprisingly valuable feedback with a side of sass (“This function is so nested it has its own ZIP code”).
Workflow Generator creates new agentic workflows from issue requests, scaffolding the markdown workflow files that other agents then refine (e.g., [#13379](https://github.com/github/gh-aw/issues/13379) requesting AWF mode changes).
We learned that **context is king** - these agents work because they’re invoked at the right moment with the right context, not because they run on a schedule.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Q:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/q.md
```
**Grumpy Reviewer:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/grumpy-reviewer.md
```
**Workflow Generator:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/workflow-generator.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Testing & Validation Workflows
[Section titled “Next Up: Testing & Validation Workflows”](#next-up-testing--validation-workflows)
While ChatOps agents respond to commands, we also need workflows that continuously verify our systems still function as expected.
Continue reading: [Testing & Validation Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-testing-validation/)
***
*This is part 13 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Issue & PR Management
> A curated tour of workflows that enhance GitHub collaboration

*Ah!* Let’s discuss the art of managing issues and pull requests at [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! A most delicious topic indeed!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-documentation/), we explored documentation and content workflows - agents that maintain glossaries, technical docs, slide decks, and blog content. We learned how we took a heterogeneous approach to documentation agents - some workflows generate content, others maintain it, and still others validate it.
Now let’s talk about the daily rituals of software development: managing issues and pull requests. GitHub provides excellent primitives for collaboration, but there’s ceremony involved - linking related issues, merging main into PR branches, assigning work, closing completed sub-issues, optimizing templates. These are small papercuts individually, but they can add up to significant friction.
## Issue & PR Management Workflows
[Section titled “Issue & PR Management Workflows”](#issue--pr-management-workflows)
These agents enhance issue and pull request workflows:
* **[Issue Arborist](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/issue-arborist.md?plain=1)** - Links related issues as sub-issues - **77 discussion reports** and **18 parent issues** created
* **[Issue Monster](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/issue-monster.md?plain=1)** - Assigns issues to the asynchronous [GitHub Copilot coding agent](https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-coding-agent) one at a time - **task dispatcher** for the whole system
* **[Mergefest](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/mergefest.md?plain=1)** - Automatically merges main branch into PR branches - **orchestrator workflow**
* **[Sub Issue Closer](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/sub-issue-closer.md?plain=1)** - Closes completed sub-issues automatically - **orchestrator workflow**
The Issue Arborist is an **organizational workflow** that has created **77 discussion reports** (titled “\[Issue Arborist] Issue Arborist Report”) and **18 parent issues** to group related sub-issues. It keeps the issue tracker organized by automatically linking related issues, building a dependency tree we’d never maintain manually. For example, [#12037](https://github.com/github/gh-aw/issues/12037) grouped engine documentation updates.
The Issue Monster is the **task dispatcher** - it assigns issues to the GitHub platform’s asynchronous [Copilot coding agent](https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-coding-agent) one at a time. It doesn’t create PRs itself, but enables every other agent’s work by feeding them tasks. This prevents the chaos of parallel work on the same codebase.
Mergefest is an **orchestrator workflow** that automatically merges main into PR branches, keeping long-lived PRs up to date without manual intervention. It eliminates the “please merge main” dance.
Sub Issue Closer automatically closes completed sub-issues when their parent issue is resolved, keeping the issue tracker clean.
Issue and PR management workflows don’t replace GitHub’s features; they enhance them, removing ceremony and making collaboration feel smoother.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Issue Arborist:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/issue-arborist.md
```
**Issue Monster:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/issue-monster.md
```
**Mergefest:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/mergefest.md
```
**Sub Issue Closer:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/sub-issue-closer.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Fault Investigation Workflows
[Section titled “Next Up: Fault Investigation Workflows”](#next-up-fault-investigation-workflows)
Next up we look at agents that maintain codebase health - spotting problems before they escalate.
Continue reading: [Fault Investigation Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-quality-hygiene/)
***
*This is part 7 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Metrics & Analytics
> A curated tour of metrics and analytics workflows that turn data into insights

Excellent journey! Now it’s time to plunge into the *observatory* - the nerve center of [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-quality-hygiene/), we explored quality and hygiene workflows - the vigilant caretakers that investigate failed CI runs, detect schema drift, and catch breaking changes before users do. These workflows maintain codebase health by spotting problems before they escalate.
When you’re running dozens of AI agents, how do you know if they’re actually working well? How do you spot performance issues, cost problems, or quality degradation? That’s where metrics and analytics workflows come in - they’re the agents that monitor other agents. The aim is to turn raw activity data into actionable insights.
## Metrics & Analytics Workflows
[Section titled “Metrics & Analytics Workflows”](#metrics--analytics-workflows)
Let’s take a look at these three workflows:
* **[Metrics Collector](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/metrics-collector.md?plain=1)** - Tracks daily performance across the entire agent ecosystem
* **[Portfolio Analyst](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/portfolio-analyst.md?plain=1)** - Identifies cost reduction opportunities
* **[Audit Workflows](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/audit-workflows.md?plain=1)** - A meta-agent that audits all the other agents’ runs
The Metrics Collector has created **41 daily metrics discussions** tracking performance across the agent ecosystem - for example, [#6986](https://github.com/github/gh-aw/discussions/6986) with the daily code metrics report. It became our central nervous system, gathering performance data that feeds into higher-level orchestrators.
Portfolio Analyst has created **7 portfolio analysis discussions** identifying cost reduction opportunities and token optimization patterns - for example, [#6499](https://github.com/github/gh-aw/discussions/6499) with a weekly portfolio analysis. The workflow has identified workflows that were costing us money unnecessarily (turns out some agents were way too chatty with their LLM calls).
Audit Workflows is our most prolific discussion-creating agent with **93 audit report discussions** and **9 issues**, acting as a meta-agent that analyzes logs, costs, errors, and success patterns across all other workflow runs. Four of its issues led to PRs by downstream agents.
Observability isn’t optional when you’re running dozens of AI agents - it’s the difference between a well-oiled machine and an expensive black box.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Metrics Collector:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/metrics-collector.md
```
**Portfolio Analyst:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/portfolio-analyst.md
```
**Audit Workflows:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/audit-workflows.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Operations & Release Workflows
[Section titled “Next Up: Operations & Release Workflows”](#next-up-operations--release-workflows)
Now that we can measure and optimize our agent ecosystem, let’s talk about the moment of truth: actually shipping software to users.
Continue reading: [Operations & Release Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-operations-release/)
***
*This is part 9 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Multi-Phase Improvers
> A curated tour of multi-phase workflows that tackle long-running projects

Let’s continue our journey through [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-tool-infrastructure/), we explored infrastructure workflows - the meta-monitoring layer that validates MCP servers, checks tool configurations, and ensures the platform itself stays healthy. These workflows watch the watchers, providing visibility into the invisible plumbing.
Most workflows we’ve seen so far run once and complete: analyze this PR, triage that issue, test this deployment. They’re ephemeral - they execute, produce results, and disappear. But what about projects that are too big to tackle in a single run? What about initiatives that require research, setup, and incremental implementation? Traditional CI/CD is built for stateless execution, but we discovered something powerful: workflows that maintain state across days, working a little bit each day like a persistent team member who never takes breaks. Welcome to our most ambitious experiment - multi-phase improvers that prove AI agents can handle complex, long-running projects.
## Multi-Phase Improver Workflows
[Section titled “Multi-Phase Improver Workflows”](#multi-phase-improver-workflows)
These are some of our most ambitious agents - they tackle big projects over multiple days:
* **[Daily Backlog Burner](https://github.com/githubnext/agentics/blob/main/workflows/daily-backlog-burner.md?plain=1)** - Systematically works through issues and PRs, one day at a time
* **[Daily Perf Improver](https://github.com/githubnext/agentics/blob/main/workflows/daily-perf-improver.md?plain=1)** - Three-phase performance optimization (research, setup, implement)
* **[Daily QA](https://github.com/githubnext/agentics/blob/main/workflows/daily-qa.md?plain=1)** - Continuous quality assurance that never sleeps
* **[Daily Accessibility Review](https://github.com/githubnext/agentics/blob/main/workflows/daily-accessibility-review.md?plain=1)** - WCAG compliance checking with Playwright
* **[PR Fix](https://github.com/githubnext/agentics/blob/main/workflows/pr-fix.md?plain=1)** - On-demand slash command to fix failing CI checks (super handy!)
This is where we got experimental with agent persistence and multi-day workflows. Traditional CI runs are ephemeral, but these workflows maintain state across days using repo-memory. The Daily Perf Improver runs in three phases - research (find bottlenecks), setup (create profiling infrastructure), implement (optimize). It’s like having a performance engineer who works a little bit each day. The Daily Backlog Burner systematically tackles our issue backlog - one issue per day, methodically working through technical debt. We learned that **incremental progress beats heroic sprints** - these agents never get tired, never get distracted, and never need coffee breaks. The PR Fix workflow is our emergency responder - when CI fails, invoke `/pr-fix` and it investigates and attempts repairs.
These workflows prove that AI agents can handle complex, long-running projects when given the right architecture.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Daily Backlog Burner:**
```bash
gh aw add-wizard githubnext/agentics/workflows/daily-backlog-burner.md
```
**Daily Perf Improver:**
```bash
gh aw add-wizard githubnext/agentics/workflows/daily-perf-improver.md
```
**Daily QA:**
```bash
gh aw add-wizard githubnext/agentics/workflows/daily-qa.md
```
**Daily Accessibility Review:**
```bash
gh aw add-wizard githubnext/agentics/workflows/daily-accessibility-review.md
```
**PR Fix:**
```bash
gh aw add-wizard githubnext/agentics/workflows/pr-fix.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Organization & Cross-Repo Workflows
[Section titled “Next Up: Organization & Cross-Repo Workflows”](#next-up-organization--cross-repo-workflows)
Single-repository workflows are powerful, but what happens when you scale to an entire organization with dozens of repositories?
Continue reading: [Organization & Cross-Repo Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-organization/)
***
*This is part 16 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Operations & Release
> A curated tour of operations and release workflows that ship software

Ah! Right this way to our next chamber in [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! The chamber where our AI agents enhance the magical moment of *shipping software*.
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/), we explored metrics and analytics workflows - the agents that monitor other agents, turning raw activity data into actionable insights.
## Operations & Release Workflows
[Section titled “Operations & Release Workflows”](#operations--release-workflows)
The agents that help us actually ship software:
* **[Changeset](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/changeset.md?plain=1)** - Manages version bumps and changelog entries for releases - **22 merged PRs out of 28 proposed (78% merge rate)**
* **[Daily Workflow Updater](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-workflow-updater.md?plain=1)** - Keeps GitHub Actions and dependencies current
Shipping software is stressful enough without worrying about whether you formatted your release notes correctly.
Changeset Generator has contributed **22 merged PRs out of 28 proposed (78% merge rate)**, automating version bumps and changelog generation for every release. It analyzes commits since the last release, determines the appropriate version bump (major, minor, patch), and updates the changelog accordingly.
Daily Workflow Updater keeps GitHub Actions and dependencies current, ensuring workflows don’t fall behind on security patches or new features.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Changeset:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/changeset.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Security-related Workflows
[Section titled “Next Up: Security-related Workflows”](#next-up-security-related-workflows)
After all this focus on shipping, we need to talk about the guardrails: how do we ensure these powerful agents operate safely?
Continue reading: [Security-related Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-security-compliance/)
***
*This is part 10 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Organization & Cross-Repo
> A curated tour of workflows that operate at organization scale

Let’s zoom out at [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-multi-phase/), we explored multi-phase improver workflows - our most ambitious agents that tackle big projects over multiple days, maintaining state and making incremental progress. These workflows proved that AI agents can handle complex, long-running initiatives when given the right architecture.
But all that sophisticated functionality has focused on a single repository. What happens when you zoom out to organization scale? What insights emerge when you analyze dozens or hundreds of repositories together? What looks perfectly normal in one repo might be a red flag across an organization. Organization and cross-repo workflows operate at enterprise scale, requiring careful permission management, thoughtful rate limiting, and different analytical lenses. Let’s explore workflows that see the forest, not just the trees.
## Organization & Cross-Repo Workflows
[Section titled “Organization & Cross-Repo Workflows”](#organization--cross-repo-workflows)
These agents work at organization scale, across multiple repositories:
* **[Org Health Report](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/org-health-report.md?plain=1)** - Organization-wide repository health metrics - **4 organization health discussions** created
* **[Stale Repo Identifier](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/stale-repo-identifier.md?plain=1)** - Identifies inactive repositories - **2 issues** flagging truly stale repos
* **[Ubuntu Image Analyzer](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/ubuntu-image-analyzer.md?plain=1)** - Documents GitHub Actions runner environments - **4 merged PRs out of 8 proposed (50% merge rate)**
Scaling agents across an entire organization changes the game. Org Health Report has created **4 organization health discussions** analyzing dozens of repositories at scale - for example, [#6777](https://github.com/github/gh-aw/discussions/6777) with the December 2025 organization health report. It identifies patterns and outliers (“these three repos have no tests, these five haven’t been updated in months”).
Stale Repo Identifier has created **2 issues** flagging truly stale repositories for organizational hygiene - for example, [#5384](https://github.com/github/gh-aw/issues/5384) identifying Skills-Based-Volunteering-Public as truly stale. It helps find abandoned projects that should be archived or transferred.
We learned that **cross-repo insights are different** - what looks fine in one repository might be an outlier across the organization. These workflows require careful permission management (reading across repos needs organization-level tokens) and thoughtful rate limiting (you can hit API limits fast when analyzing 50+ repos).
Ubuntu Image Analyzer has contributed **4 merged PRs out of 8 proposed (50% merge rate)**, documenting GitHub Actions runner environments to keep the team informed about available tools and versions. It’s wonderfully meta - it documents the very environment that runs our agents.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Org Health Report:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/org-health-report.md
```
**Stale Repo Identifier:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/stale-repo-identifier.md
```
**Ubuntu Image Analyzer:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/ubuntu-image-analyzer.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Advanced Analytics & ML Workflows
[Section titled “Next Up: Advanced Analytics & ML Workflows”](#next-up-advanced-analytics--ml-workflows)
Cross-repo insights reveal patterns, but we wanted to go even deeper - using machine learning to understand agent behavior.
Continue reading: [Advanced Analytics & ML Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-advanced-analytics/)
***
*This is part 17 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Fault Investigation
> A curated tour of proactive fault investigation workflows that maintain codebase health

*Ah, splendid!* Welcome back to [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! Come, let me show you the chamber where vigilant caretakers investigate faults before they escalate!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-issue-management/), we explored issue and PR management workflows.
Now let’s shift from collaboration ceremony to fault investigation.
While issue workflows help us handle what comes in, fault investigation workflows act as vigilant caretakers - spotting problems before they escalate and keeping our codebase healthy. These are the agents that investigate failed CI runs, detect schema drift, and catch breaking changes before users do.
## Fault Investigation Workflows
[Section titled “Fault Investigation Workflows”](#fault-investigation-workflows)
These are our diligent caretakers - the agents that spot problems before they become bigger problems:
* **[CI Doctor](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/ci-doctor.md?plain=1)** - Investigates failed workflows and opens diagnostic issues - **9 merged PRs out of 13 proposed (69% merge rate)**
* **[Schema Consistency Checker](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/schema-consistency-checker.md?plain=1)** - Detects when schemas, code, and docs drift apart - **55 analysis discussions** created
* **[Breaking Change Checker](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/breaking-change-checker.md?plain=1)** - Watches for changes that might break things for users - creates alert issues
The CI Doctor (also known as “CI Failure Doctor”) was one of our most important workflows. Instead of drowning in CI failure notifications, we now get *timely*, *investigated* failures with actual diagnostic insights. The agent doesn’t just tell us something broke - it analyzes logs, identifies patterns, searches for similar past issues, and even suggests fixes - even before the human has read the failure notification. CI Failure Doctor has contributed **9 merged PRs out of 13 proposed (69% merge rate)**, including fixes like [adding Go module download pre-flight checks](https://github.com/github/gh-aw/pull/13740) and [adding retry logic to prevent proxy 403 failures](https://github.com/github/gh-aw/pull/13155). We learned that agents excel at the tedious investigation work that humans find draining.
The Schema Consistency Checker has created **55 analysis discussions** examining schema drift between JSON schemas, Go structs, and documentation - for example, [#7020](https://github.com/github/gh-aw/discussions/7020) analyzing conditional logic consistency across the codebase. It caught drift that would have taken us days to notice manually.
Breaking Change Checker is a newer workflow that monitors for backward-incompatible changes and creates alert issues (e.g., [#14113](https://github.com/github/gh-aw/issues/14113) flagging CLI version updates) before they reach production.
These “hygiene” workflows became our first line of defense, catching issues before they reached users.
The CI Doctor has inspired a growing range of similar workflows inside GitHub, where agents proactively do depth investigations of site incidents and failures. This is the future of operational excellence: AI agents kicking in immediately to do depth investigation, for faster organizational response.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**CI Doctor:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/ci-doctor.md
```
**Schema Consistency Checker:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/schema-consistency-checker.md
```
**Breaking Change Checker:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/breaking-change-checker.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Metrics & Analytics Workflows
[Section titled “Next Up: Metrics & Analytics Workflows”](#next-up-metrics--analytics-workflows)
Next up, we look at workflows which help us understand if the agent collection as a whole is working well That’s where metrics and analytics workflows come in.
Continue reading: [Metrics & Analytics Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-metrics-analytics/)
***
*This is part 8 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Security-related
> A curated tour of security and compliance workflows that enforce safe boundaries

*Splendid!* How great to have you back at [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! Now, let me show you the *guardian chamber* - where the watchful protectors stand vigil!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-operations-release/), we explored operations and release workflows that handle the critical process of shipping software - building, testing, generating release notes, and publishing. These workflows need to be rock-solid reliable because they represent the moment when our work reaches users.
But reliability alone isn’t enough - we also need *security*. When AI agents can access APIs, modify code, and interact with external services, security becomes paramount. How do we ensure agents only access authorized resources? How do we track vulnerabilities and enforce compliance deadlines? How do we prevent credential exposure? That’s where security and compliance workflows become our essential guardrails - the watchful guardians that let us sleep soundly at night.
## Security-related Workflows
[Section titled “Security-related Workflows”](#security-related-workflows)
These agents are our security guards, keeping watch and enforcing the rules:
* **[Security Compliance](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/security-compliance.md?plain=1)** - Runs vulnerability campaigns with deadline tracking
* **[Firewall](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/firewall.md?plain=1)** - Tests network security and validates rules - **59 daily firewall report discussions**, **5 smoke test issues**
* **[Daily Secrets Analysis](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-secrets-analysis.md?plain=1)** - Scans for exposed credentials (yes, it happens)
* **[Daily Malicious Code Scan](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-malicious-code-scan.md?plain=1)** - Reviews recent code changes for suspicious patterns
* **[Static Analysis Report](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/static-analysis-report.md?plain=1)** - Daily security scans using zizmor, poutine, and actionlint - **57 analysis discussions** plus **12 Zizmor security reports**
Security Compliance manages vulnerability remediation campaigns with deadline tracking, ensuring security issues are addressed within defined SLAs - perfect for those “audit in 3 weeks” panic moments.
The Firewall workflow has created **59 daily firewall report discussions** and **5 smoke test issues**, validating that our agents can’t access unauthorized resources - for example, [#6943](https://github.com/github/gh-aw/discussions/6943) with the daily firewall analysis. It’s the bouncer that enforces network rules.
Daily Secrets Analysis scans for exposed credentials in commits and discussions, providing an automated security net against accidental secret exposure - catching those “oops, I committed my API key” moments before they become incidents.
Daily Malicious Code Scan reviews recent code changes for suspicious patterns, adding an automated defense layer against supply chain attacks.
Static Analysis Report has created **57 analysis discussions** plus **12 Zizmor security reports**, running comprehensive daily security audits using industry-standard tools - for example, [#6973](https://github.com/github/gh-aw/discussions/6973) with the latest static analysis findings and [#3033](https://github.com/github/gh-aw/discussions/3033) with a Zizmor security analysis. This shows how traditional security tools can be integrated into an AI agent workflow.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Security Compliance:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/security-compliance.md
```
**Firewall:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/firewall.md
```
**Daily Secrets Analysis:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-secrets-analysis.md
```
**Daily Malicious Code Scan:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-malicious-code-scan.md
```
**Static Analysis Report:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/static-analysis-report.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Teamwork & Culture Workflows
[Section titled “Next Up: Teamwork & Culture Workflows”](#next-up-teamwork--culture-workflows)
After all this serious talk, let’s explore the fun side: agents that bring joy and build team culture.
Continue reading: [Teamwork & Culture Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-creative-culture/)
***
*This is part 11 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Testing & Validation
> A curated tour of testing workflows that keep everything running smoothly

*Right this way!* Let’s continue our grand tour of [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! Into the *verification chamber* where nothing escapes scrutiny!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-interactive-chatops/), we explored ChatOps workflows - agents that respond to slash commands and GitHub reactions, providing on-demand assistance with full context.
But making code *better* is only half the battle. We also need to ensure it keeps *working*. As we refactor, optimize, and evolve our codebase, how do we know we haven’t broken something? How do we catch regressions before users do? That’s where testing and validation workflows come in - the skeptical guardians that continuously verify our systems still function as expected. We learned that AI infrastructure needs constant health checks, because what worked yesterday might silently fail today. These workflows embody **trust but verify**.
## Testing & Validation Workflows
[Section titled “Testing & Validation Workflows”](#testing--validation-workflows)
These agents keep everything running smoothly through continuous testing:
### Code Quality & Test Validation
[Section titled “Code Quality & Test Validation”](#code-quality--test-validation)
* **[Daily Testify Uber Super Expert](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-testify-uber-super-expert.md?plain=1)** - Analyzes test files daily and suggests testify-based improvements - **19 issues created**, **13 led to merged PRs (100% causal chain merge rate)**
* **[Daily Test Improver](https://github.com/githubnext/agentics/blob/main/workflows/daily-test-improver.md?plain=1)** - Identifies coverage gaps and implements new tests incrementally
* **[Daily Compiler Quality Check](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-compiler-quality.md?plain=1)** - Analyzes compiler code to ensure it meets quality standards
### User Experience & Integration Testing
[Section titled “User Experience & Integration Testing”](#user-experience--integration-testing)
* **[Daily Multi-Device Docs Tester](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-multi-device-docs-tester.md?plain=1)** - Tests documentation across devices with Playwright - **2 merged PRs out of 2 proposed (100% merge rate)**
* **[CLI Consistency Checker](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/cli-consistency-checker.md?plain=1)** - Inspects the CLI for inconsistencies, typos, and documentation gaps - **80 merged PRs out of 102 proposed (78% merge rate)**
### CI/CD Optimization
[Section titled “CI/CD Optimization”](#cicd-optimization)
* **[CI Coach](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/ci-coach.md?plain=1)** - Analyzes CI pipelines and suggests optimizations - **9 merged PRs out of 9 proposed (100% merge rate)**
* **[Workflow Health Manager](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/workflow-health-manager.md?plain=1)** - Meta-orchestrator monitoring health of all agentic workflows - **40 issues created**, **5 direct PRs + 14 causal chain PRs merged**
The Daily Testify Expert has created **19 issues** analyzing test quality, and **13 of those issues led to merged PRs** by downstream agents - a perfect 100% causal chain merge rate. For example, [issue #13701](https://github.com/github/gh-aw/issues/13701) led to [#13722](https://github.com/github/gh-aw/pull/13722) modernizing console render tests with testify assertions. The Daily Test Improver works alongside it to identify coverage gaps and implement new tests.
The Multi-Device Docs Tester uses Playwright to test our documentation on different screen sizes - it has created **2 PRs (both merged)**, including [adding —network host to Playwright Docker containers](https://github.com/github/gh-aw/pull/7158). It found mobile rendering issues we never would have caught manually. The CLI Consistency Checker has contributed **80 merged PRs out of 102 proposed (78% merge rate)**, maintaining consistency in CLI interface and documentation. Recent examples include [removing undocumented CLI commands](https://github.com/github/gh-aw/pull/12762) and [fixing upgrade command documentation](https://github.com/github/gh-aw/pull/11559).
CI Optimization Coach has contributed **9 merged PRs out of 9 proposed (100% merge rate)**, optimizing CI pipelines for speed and efficiency with perfect execution. Examples include [removing unnecessary test dependencies](https://github.com/github/gh-aw/pull/13925) and [fixing duplicate test execution](https://github.com/github/gh-aw/pull/8176).
The Workflow Health Manager has created **40 issues** monitoring the health of all other workflows, with **25 of those issues leading to 34 PRs** (14 merged) by downstream agents - plus **5 direct PRs merged**. For example, [issue #14105](https://github.com/github/gh-aw/issues/14105) about a missing runtime file led to [#14127](https://github.com/github/gh-aw/pull/14127) fixing the workflow configuration.
These workflows embody the principle: **trust but verify**. Just because it worked yesterday doesn’t mean it works today.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**Daily Testify Uber Super Expert:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-testify-uber-super-expert.md
```
**Daily Test Improver:**
```bash
gh aw add-wizard githubnext/agentics/daily-test-improver
```
**Daily Compiler Quality Check:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-compiler-quality.md
```
**Daily Multi-Device Docs Tester:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/daily-multi-device-docs-tester.md
```
**CLI Consistency Checker:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/cli-consistency-checker.md
```
**CI Coach:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/ci-coach.md
```
**Workflow Health Manager:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/workflow-health-manager.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Monitoring the Monitors
[Section titled “Next Up: Monitoring the Monitors”](#next-up-monitoring-the-monitors)
But what about the infrastructure itself? Who watches the watchers? Time to go meta.
Continue reading: [Tool & Infrastructure Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-tool-infrastructure/)
***
*This is part 14 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Meet the Workflows: Tool & Infrastructure
> A curated tour of infrastructure workflows that monitor the agentic systems

*Delighted to have you back* on our journey through [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/)! Now, prepare yourself for something *quite peculiar* - the room where we watch the watchers!
In our [previous post](/gh-aw/blog/2026-01-13-meet-the-workflows-testing-validation/), we explored testing and validation workflows that continuously verify our systems function correctly - running smoke tests, checking documentation across devices, and catching regressions before users notice them. We learned that trust must be verified.
But here’s a question that kept us up at night: what if the *infrastructure itself* fails? What if MCP servers are misconfigured, tools become unavailable, or agents can’t access the capabilities they need? Testing the *application* is one thing; monitoring the *platform* that runs AI agents is another beast entirely. Tool and infrastructure workflows provide meta-monitoring - they watch the watchers, validate configurations, and ensure the invisible plumbing stays functional. Welcome to the layer where we monitor agents monitoring agents monitoring code. Yes, it gets very meta.
## Tool & Infrastructure Workflows
[Section titled “Tool & Infrastructure Workflows”](#tool--infrastructure-workflows)
These agents monitor and analyze the agentic infrastructure itself:
* **[MCP Inspector](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/mcp-inspector.md?plain=1)** - Validates Model Context Protocol configurations - ensures agents can access tools
* **[GitHub MCP Tools Report](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/github-mcp-tools-report.md?plain=1)** - Analyzes available MCP tools - **5 merged PRs out of 6 proposed (83% merge rate)**
* **[Agent Performance Analyzer](https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/agent-performance-analyzer.md?plain=1)** - Meta-orchestrator for agent quality - **29 issues created, 14 leading to PRs (8 merged)**
Infrastructure for AI agents is different from traditional infrastructure - you need to validate that tools are available, properly configured, and actually working. The MCP Inspector continuously validates Model Context Protocol server configurations because a misconfigured MCP server means an agent can’t access the tools it needs.
GitHub MCP Tools Report Generator has contributed **5 merged PRs out of 6 proposed (83% merge rate)**, analyzing MCP tool availability and keeping tool configurations up to date. For example, [PR #13169](https://github.com/github/gh-aw/pull/13169) updates MCP server tool configurations.
Agent Performance Analyzer has created **29 issues** identifying performance problems across the agent ecosystem, and **14 of those issues led to PRs** (8 merged) by downstream agents - for example, it detected that draft PRs accounted for 9.6% of open PRs, created issue #12168, which led to [#12174](https://github.com/github/gh-aw/pull/12174) implementing automated draft cleanup.
We learned that **layered observability** is crucial: you need monitoring at the infrastructure level (are servers up?), the tool level (can agents access what they need?), and the agent level (are they performing well?).
These workflows provide visibility into the invisible.
## Using These Workflows
[Section titled “Using These Workflows”](#using-these-workflows)
You can add these workflows to your own repository and remix them. Get going with our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/), then run one of the following:
**MCP Inspector:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/mcp-inspector.md
```
**GitHub MCP Tools Report:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/github-mcp-tools-report.md
```
**Agent Performance Analyzer:**
```bash
gh aw add-wizard https://github.com/github/gh-aw/blob/v0.45.5/.github/workflows/agent-performance-analyzer.md
```
Then edit and remix the workflow specifications to meet your needs, regenerate the lock file using `gh aw compile`, and push to your repository. See our [Quick Start](https://github.github.com/gh-aw/setup/quick-start/) for further installation and setup instructions.
You can also [create your own workflows](/gh-aw/setup/creating-workflows/).
## Learn More
[Section titled “Learn More”](#learn-more)
* **[GitHub Agentic Workflows](https://github.github.com/gh-aw/)** - The technology behind the workflows
* **[Quick Start](https://github.github.com/gh-aw/setup/quick-start/)** - How to write and compile workflows
## Next Up: Multi-Phase Improver Workflows
[Section titled “Next Up: Multi-Phase Improver Workflows”](#next-up-multi-phase-improver-workflows)
Most workflows we’ve seen are stateless - they run, complete, and disappear. But what if agents could maintain memory across days?
Continue reading: [Multi-Phase Improver Workflows →](/gh-aw/blog/2026-01-13-meet-the-workflows-multi-phase/)
***
*This is part 15 of a 19-part series exploring the workflows in Peli’s Agent Factory.*
# Weekly Update – March 18, 2026
> Seven releases in seven days: guard policy overhaul, new triggers, GHE improvements, and a healthy dose of quality-of-life fixes.
It’s been a busy week in [github/gh-aw](https://github.com/github/gh-aw) — seven releases shipped between March 13 and March 17, covering everything from a security model overhaul to a new label-based trigger and a long-overdue terminal resize fix. Let’s dig in.
## Releases This Week
[Section titled “Releases This Week”](#releases-this-week)
### [v0.61.0](https://github.com/github/gh-aw/releases/tag/v0.61.0) — March 17
[Section titled “v0.61.0 — March 17”](#v0610--march-17)
The freshest release focuses on reliability and developer experience:
* **Automatic debug logging** ([#21406](https://github.com/github/gh-aw/pull/21406)): Set `ACTIONS_RUNNER_DEBUG=true` on your runner and full debug logging activates automatically — no more manually adding `DEBUG=*` to every troubleshooting run.
* **Cross-repo project item updates** ([#21404](https://github.com/github/gh-aw/pull/21404)): `update_project` now accepts a `target_repo` parameter, so org-level project boards can update fields on items from any repository.
* **GHE Cloud data residency support** ([#21408](https://github.com/github/gh-aw/pull/21408)): Compiled workflows now auto-inject a `GH_HOST` step, fixing `gh` CLI failures on `*.ghe.com` instances.
* **CI build artifacts** ([#21440](https://github.com/github/gh-aw/pull/21440)): The `build` CI job now uploads the compiled `gh-aw` binary as a downloadable artifact — handy for testing PRs without a local build.
### [v0.60.0](https://github.com/github/gh-aw/releases/tag/v0.60.0) — March 17
[Section titled “v0.60.0 — March 17”](#v0600--march-17)
This release rewires the security model. **Breaking change**: automatic `lockdown=true` is gone. Instead, the runtime now auto-configures guard policies on the GitHub MCP server — `min_integrity=approved` for public repos, `min_integrity=none` for private/internal. Remove any explicit `lockdown: false` from your frontmatter; it’s no longer needed.
Other highlights:
* **GHES domain auto-allowlisting** ([#21301](https://github.com/github/gh-aw/pull/21301)): When `engine.api-target` points to a GHES instance, the compiler automatically adds GHES API hostnames to the firewall. No more silent blocks after every recompile.
* **`github-app:` auth in APM dependencies** ([#21286](https://github.com/github/gh-aw/pull/21286)): APM `dependencies:` can now use `github-app:` auth for cross-org private package access.
### [v0.59.0](https://github.com/github/gh-aw/releases/tag/v0.59.0) — March 16
[Section titled “v0.59.0 — March 16”](#v0590--march-16)
A feature-packed release with two breaking changes (field renames in `safe-outputs.allowed-domains`) and several new capabilities:
* **Label Command Trigger** ([#21118](https://github.com/github/gh-aw/pull/21118)): Activate a workflow by adding a label to an issue, PR, or discussion. The label is automatically removed so it can be reapplied to re-trigger.
* **`gh aw domains` command** ([#21086](https://github.com/github/gh-aw/pull/21086)): Inspect the effective network domain configuration for all your workflows, with per-domain ecosystem annotations.
* **Pre-activation step injection** — New `on.steps` and `on.permissions` frontmatter fields let you inject custom steps and permissions into the activation job for advanced scenarios.
### Earlier in the Week
[Section titled “Earlier in the Week”](#earlier-in-the-week)
* [v0.58.3](https://github.com/github/gh-aw/releases/tag/v0.58.3) (March 15): MCP write-sink guard policy for non-GitHub MCP servers, Copilot pre-flight diagnostic for GHES, and a richer run details step summary.
* [v0.58.2](https://github.com/github/gh-aw/releases/tag/v0.58.2) (March 14): GHES auto-detection in `audit` and `add-wizard`, `excluded-files` support for `create-pull-request`, and clearer `run` command errors.
* [v0.58.1](https://github.com/github/gh-aw/releases/tag/v0.58.1) / [v0.58.0](https://github.com/github/gh-aw/releases/tag/v0.58.0) (March 13): `call-workflow` safe output for chaining workflows, `checkout: false` for agent jobs, custom OpenAI/Anthropic API endpoints, and 92 merged PRs in v0.58.0 alone.
## Notable Pull Requests
[Section titled “Notable Pull Requests”](#notable-pull-requests)
* **[Top-level `github-app` fallback](https://github.com/github/gh-aw/pull/21510)** ([#21510](https://github.com/github/gh-aw/pull/21510)): Define your GitHub App config once at the top level and let it propagate to safe-outputs, checkout, MCP, APM, and activation — instead of repeating it in every section.
* **[GitHub App-only permission scopes](https://github.com/github/gh-aw/pull/21511)** ([#21511](https://github.com/github/gh-aw/pull/21511)): 31 new `PermissionScope` constants cover repository, org, and user-level GitHub App permissions (e.g., `administration`, `members`, `environments`).
* **[Custom Huh theme](https://github.com/github/gh-aw/pull/21557)** ([#21557](https://github.com/github/gh-aw/pull/21557)): All 11 interactive CLI forms now use a Dracula-inspired theme consistent with the rest of the CLI’s visual identity.
* **[Weekly blog post writer workflow](https://github.com/github/gh-aw/pull/21575)** ([#21575](https://github.com/github/gh-aw/pull/21575)): Yes, the workflow that wrote this post was itself merged this week. Meta!
* **[CI job timeout limits](https://github.com/github/gh-aw/pull/21601)** ([#21601](https://github.com/github/gh-aw/pull/21601)): All 25 CI jobs that relied on GitHub’s 6-hour default now have explicit timeouts, preventing a stuck test from silently burning runner compute.
## Agent of the Week: auto-triage-issues
[Section titled “ Agent of the Week: auto-triage-issues”](#-agent-of-the-week-auto-triage-issues)
The first-ever Agent of the Week goes to the workflow that handles the unglamorous but essential job of keeping the issue tracker from becoming a swamp.
`auto-triage-issues` runs on a schedule and fires on every new issue, reading each one and deciding how to categorize it. This week it ran five times — three successful runs and two that were triggered by push events to a feature branch (which apparently fire the workflow but don’t give it much to work with). On its scheduled run this morning, it found zero open issues in the repository, so it created a tidy summary discussion to announce the clean state, as instructed. On an earlier issues-triggered run, it attempted to triage issue [#21572](https://github.com/github/gh-aw/pull/21572) but hit empty results from GitHub MCP tools on all three read attempts — so it gracefully called `missing_data` and moved on rather than hallucinating a label.
Across its recent runs it made 131 `search_repositories` calls. We’re not sure why it finds repository searches so compelling, but clearly it’s very thorough about knowing its neighborhood before making any decisions.
**Usage tip**: Pair `auto-triage-issues` with a notify workflow on specific labels (e.g., `security` or `needs-repro`) so the right people get pinged automatically without anyone having to watch the inbox.
→ [View the workflow on GitHub](https://github.com/github/gh-aw/blob/main/.github/workflows/auto-triage-issues.md)
## Try It Out
[Section titled “Try It Out”](#try-it-out)
Update to [v0.61.0](https://github.com/github/gh-aw/releases/tag/v0.61.0) to get all the improvements from this packed week. If you run workflows on GHES or in GHE Cloud, the new auto-detection and `GH_HOST` injection features are especially worth trying. As always, contributions and feedback are welcome in [github/gh-aw](https://github.com/github/gh-aw).
# Weekly Update – March 23, 2026
> Eight releases this week: security hardening, custom Actions as safe-output tools, a 20-second speed boost, and timezone support for scheduled workflows.
Another week, another flurry of releases in [github/gh-aw](https://github.com/github/gh-aw). Eight versions shipped between March 18 and March 21, pushing security hardening, extensibility, and performance improvements across the board. Here’s what you need to know.
## Releases This Week
[Section titled “Releases This Week”](#releases-this-week)
### [v0.62.5](https://github.com/github/gh-aw/releases/tag/v0.62.5) — March 21
[Section titled “v0.62.5 — March 21”](#v0625--march-21)
The latest release leads with two important security fixes:
* **Supply chain protection**: The Trivy vulnerability scanner action was removed after a supply chain compromise was discovered ([#22007](https://github.com/github/gh-aw/pull/22007), [#22065](https://github.com/github/gh-aw/pull/22065)). Scanning has been replaced with a safer alternative.
* **Public repo integrity hardening** ([#21969](https://github.com/github/gh-aw/pull/21969)): GitHub App authentication no longer exempts public repositories from the minimum-integrity guard policy, closing a gap where untrusted content could bypass integrity checks.
On the feature side:
* **Timezone support for `on.schedule`** ([#22018](https://github.com/github/gh-aw/pull/22018)): Cron entries now accept an optional `timezone` field — finally, no more mental UTC arithmetic when you want your workflow to run “at 9 AM Pacific”.
* **Boolean expression optimizer** ([#22025](https://github.com/github/gh-aw/pull/22025)): Condition trees are optimized at compile time, generating cleaner `if:` expressions in compiled workflows.
* **Wildcard `target-repo` in safe-output handlers** ([#21877](https://github.com/github/gh-aw/pull/21877)): Use `target-repo: "*"` to write a single handler definition that works across any repository.
### [v0.62.3](https://github.com/github/gh-aw/releases/tag/v0.62.3) — March 20
[Section titled “v0.62.3 — March 20”](#v0623--march-20)
This one is a standout for extensibility and speed:
* **Custom Actions as Safe Output Tools** ([#21752](https://github.com/github/gh-aw/pull/21752)): You can now expose any GitHub Action as an MCP tool via the new `safe-outputs.actions` block. The compiler resolves `action.yml` at compile time to derive the tool schema and inject it into the agent — no custom wiring needed. This opens the door to a whole ecosystem of reusable safe-output handlers built from standard Actions.
* **\~20 seconds faster per workflow run** ([#21873](https://github.com/github/gh-aw/pull/21873)): A bump to `DefaultFirewallVersion` v0.24.5 eliminates a 10-second shutdown delay for both the agent container and the threat detection container. That’s 20 free seconds on every single run.
* **`trustedBots` support in MCP Gateway** ([#21865](https://github.com/github/gh-aw/pull/21865)): Pass an allowlist of additional GitHub bot identities to the MCP Gateway, enabling safe cross-bot collaboration in guarded environments.
* **`gh-aw-metadata` v3** ([#21899](https://github.com/github/gh-aw/pull/21899)): Lock files now embed the configured agent ID/model in the `gh-aw-metadata` comment, making audits much easier.
### [v0.62.2](https://github.com/github/gh-aw/releases/tag/v0.62.2) — March 19
[Section titled “v0.62.2 — March 19”](#v0622--march-19)
! **Breaking change alert**: `lockdown: true` is gone. It has been replaced by the more expressive `min-integrity` field. If you have `lockdown: false` in your frontmatter, remove it — it’s no longer recognized. The new integrity-level system gives you finer control over what content can trigger your workflows.
This release also introduces **integrity filtering for log analysis** — the `gh aw logs` command can now filter to only runs where DIFC integrity events were triggered, making security investigations much faster.
### [v0.62.0](https://github.com/github/gh-aw/releases/tag/v0.62.0) — March 19
[Section titled “v0.62.0 — March 19”](#v0620--march-19)
The GitHub MCP guard policy graduates to **general availability**. The policy automatically configures appropriate access controls on the GitHub MCP server at runtime — no manual `lockdown` configuration required. Also new: **inline custom safe-output scripts**, letting you define JavaScript handlers directly in your workflow frontmatter without a separate file.
### [v0.61.x](https://github.com/github/gh-aw/releases/tag/v0.61.2) — March 18
[Section titled “v0.61.x — March 18”](#v061x--march-18)
Three patch releases covered:
* Signed-commit support for protected branches ([v0.61.1](https://github.com/github/gh-aw/releases/tag/v0.61.1))
* Broader ecosystem domain coverage for language package registries ([v0.61.2](https://github.com/github/gh-aw/releases/tag/v0.61.2))
* Critical `workflow_dispatch` expression evaluation fix ([v0.61.2](https://github.com/github/gh-aw/releases/tag/v0.61.2))
## Notable Pull Requests
[Section titled “Notable Pull Requests”](#notable-pull-requests)
Several important fixes landed today (March 23):
* **[Propagate `assign_copilot` failures to agent failure comment](https://github.com/github/gh-aw/pull/22371)** ([#22371](https://github.com/github/gh-aw/pull/22371)): When `assign_copilot_to_created_issues` fails (e.g., bad credentials), the failure context is now surfaced in the agent failure issue so you can actually diagnose it.
* **[Post failure comment when agent assignment fails](https://github.com/github/gh-aw/pull/22347)** ([#22347](https://github.com/github/gh-aw/pull/22347)): A follow-up to the above — the failure now also posts a comment directly on the target issue or PR for immediate visibility.
* **[Hot-path regexp and YAML parse elimination](https://github.com/github/gh-aw/pull/22359)** ([#22359](https://github.com/github/gh-aw/pull/22359)): Redundant regexp compilations and YAML re-parses on the hot path have been eliminated, improving throughput for high-volume workflow execution.
* **[`blocked-users` and `approval-labels` in guard policy](https://github.com/github/gh-aw/pull/22360)** ([#22360](https://github.com/github/gh-aw/pull/22360)): The `tools.github` guard policy now supports `blocked-users` and `approval-labels` fields, giving you more granular control over who can trigger guarded workflows.
* **[Pull merged workflow files after GitHub confirms readiness](https://github.com/github/gh-aw/pull/22335)** ([#22335](https://github.com/github/gh-aw/pull/22335)): A race condition where merged workflow files were pulled before GitHub reported the workflow as ready has been fixed.
## Agent of the Week: contribution-check
[Section titled “ Agent of the Week: contribution-check”](#-agent-of-the-week-contribution-check)
Your tireless four-hourly guardian of PR quality — reads every open pull request and evaluates it against `CONTRIBUTING.md` for compliance and completeness.
`contribution-check` ran five times this week (once every four hours, as scheduled) and processed a steady stream of incoming PRs, creating issues for contributors who needed guidance, adding labels, and leaving review comments. Four of five runs completed in under 5 minutes with 6–9 turns. The fifth run, however, apparently found the task of reviewing PRs during a particularly active Sunday evening so intellectually stimulating that it worked through 50 turns and consumed 1.55 million tokens — roughly 5× its usual appetite — before the safe\_outputs step politely called it a night. It still managed to file issues, label PRs, and post comments on the way out. Overachiever.
One earlier run also hit a minor hiccup: the pre-agent filter step forgot to write its output file, leaving the agent with nothing to evaluate. Rather than fabricating a list of PRs to review, it dutifully reported “missing data” and moved on. Sometimes the bravest thing is knowing when there’s nothing to do.
**Usage tip**: The `contribution-check` pattern works best when your `CONTRIBUTING.md` is explicit and opinionated — the more specific your guidelines, the more actionable its feedback will be for contributors.
→ [View the workflow on GitHub](https://github.com/github/gh-aw/blob/main/.github/workflows/contribution-check.md)
## Try It Out
[Section titled “Try It Out”](#try-it-out)
Update to [v0.62.5](https://github.com/github/gh-aw/releases/tag/v0.62.5) to pick up the security fixes and timezone support. If you’ve been holding off on migrating from `lockdown: true`, now’s the time — check the [v0.62.2 release notes](https://github.com/github/gh-aw/releases/tag/v0.62.2) for the migration path. As always, contributions and feedback are welcome in [github/gh-aw](https://github.com/github/gh-aw).
# Weekly Update – March 30, 2026
> Six releases in seven days: audit superpowers, integrity-aware cache-memory, a serious security sweep, and runner flexibility for compile-stable jobs.
Six releases shipped in [github/gh-aw](https://github.com/github/gh-aw) between March 24 and March 30 — that’s almost one a day. From expanded audit tooling to integrity-isolated cache storage and a wave of security fixes, this was a dense week. Here’s the rundown.
## Releases This Week
[Section titled “Releases This Week”](#releases-this-week)
### [v0.64.4](https://github.com/github/gh-aw/releases/tag/v0.64.4) — March 30
[Section titled “v0.64.4 — March 30”](#v0644--march-30)
The freshest release ships with quality-of-life wins for workflow authors:
* **`runs-on-slim` for compile-stable jobs** ([#23490](https://github.com/github/gh-aw/pull/23490)): Override the runner for `compile-stable` framework jobs with a new `runs-on-slim` key, giving you fine-grained control over which machine handles compilation.
* **Sibling nested imports fixed** ([#23475](https://github.com/github/gh-aw/pull/23475)): `./file.md` imports now resolve relative to the importing file’s directory, not the working directory. Modular workflows that import sibling files were silently broken before — now they’re not.
* **Custom tools in `` prompt** ([#23487](https://github.com/github/gh-aw/pull/23487)): Custom jobs, scripts, and actions are now listed in the agent’s `` prompt block so the AI actually knows they exist.
* **Compile-time validation of safe-output job ordering** ([#23486](https://github.com/github/gh-aw/pull/23486)): Misconfigured `needs:` ordering on custom safe-output jobs is now caught at compile time.
* **MCP Gateway v0.2.9** ([#23513](https://github.com/github/gh-aw/pull/23513)) and **firewall v0.25.4** ([#23514](https://github.com/github/gh-aw/pull/23514)) bumped for all compiled workflows.
### [v0.64.3](https://github.com/github/gh-aw/releases/tag/v0.64.3) — March 29
[Section titled “v0.64.3 — March 29”](#v0643--march-29)
A security-heavy release with one major architectural upgrade:
**Integrity-aware cache-memory** is the headline. Cache storage now uses dedicated git branches — `merged`, `approved`, `unapproved`, and `none` — to enforce integrity isolation at the storage level. A run operating at `unapproved` integrity can no longer read data written by a `merged`-integrity run, and any change to your `allow-only` guard policy automatically invalidates stale cache entries. If you upgrade and see a cache miss on your first run, that’s intentional — legacy data has no integrity provenance and must be regenerated.
**`patch-format: bundle`** ([#23338](https://github.com/github/gh-aw/pull/23338)) is the other highlight: code-push flows now support `git bundle` as an alternative to `git am`, preserving merge commits, authorship, and per-commit messages that were previously dropped.
Security fixes:
* **Secret env var exclusion** ([#23360](https://github.com/github/gh-aw/pull/23360)): AWF now strips all secret-bearing env vars (tokens, API keys, MCP secrets) from the agent container’s visible environment, closing a potential prompt-injection exfiltration path in `pull_request_target` workflows.
* **Argument injection fix** ([#23374](https://github.com/github/gh-aw/pull/23374)): Package and image names in `gh aw compile --validate-packages` are validated before being passed to `npm view`, `pip index versions`, `uv pip show`, and `docker`.
### [v0.64.2](https://github.com/github/gh-aw/releases/tag/v0.64.2) — March 26
[Section titled “v0.64.2 — March 26”](#v0642--march-26)
The `gh aw logs` command gained cross-run report generation via the new `--format` flag:
**`gh aw logs --format`** aggregates firewall behavior across multiple workflow runs and produces an executive summary, domain inventory, and per-run breakdown:
```bash
gh aw logs agent-task --format markdown --count 10 # Markdown
gh aw logs --format markdown --json # JSON for dashboards
gh aw logs --format pretty # Console output
```
This release also includes a **YAML env injection security fix** ([#23055](https://github.com/github/gh-aw/pull/23055)): all `env:` emission sites in the compiler now use `%q`-escaped YAML scalars, preventing newlines or quote characters in frontmatter values from injecting sibling env variables into `.lock.yml` files.
### [v0.64.1](https://github.com/github/gh-aw/releases/tag/v0.64.1) — March 26
[Section titled “v0.64.1 — March 26”](#v0641--march-26)
**`gh aw audit diff`** ([#22996](https://github.com/github/gh-aw/pull/22996)) lets you compare two workflow runs side-by-side — firewall behavior, MCP tool invocations, token usage, and duration — to spot regressions and behavioral drift before they become incidents:
```bash
gh aw audit diff --format markdown
```
Five new sections also landed in the standard `gh aw audit` report: Engine Configuration, Prompt Analysis, Session & Agent Performance, Safe Output Summary, and MCP Server Health. One report now gives you the full picture.
### [v0.64.0](https://github.com/github/gh-aw/releases/tag/v0.64.0) — March 25
[Section titled “v0.64.0 — March 25”](#v0640--march-25)
**Bot-actor concurrency isolation**: Workflows combining `safe-outputs.github-app` with `issue_comment`-capable triggers now automatically get bot-isolated concurrency keys, preventing the workflow from cancelling itself mid-run when the bot posts a comment that re-triggers the same workflow.
### [v0.63.1](https://github.com/github/gh-aw/releases/tag/v0.63.1) — March 24
[Section titled “v0.63.1 — March 24”](#v0631--march-24)
A focused patch adding the **`skip-if-check-failing`** pre-activation gate — workflows can now bail out before the agent runs if a named CI check is currently failing, avoiding wasted inference on a broken codebase. Also ships an improved fuzzy schedule algorithm with weighted preferred windows and peak avoidance to reduce queue contention on shared runners.
***
## Agent of the Week: auto-triage-issues
[Section titled “ Agent of the Week: auto-triage-issues”](#-agent-of-the-week-auto-triage-issues)
The self-appointed gatekeeper of the issue tracker — reads every new issue and assigns labels so the right people see it.
This week, `auto-triage-issues` handled three runs. Two of them were textbook efficiency: triggered the moment a new issue landed, ran the pre-activation check, decided there was nothing worth labeling, and wrapped up in under 42 seconds flat. No fuss, no drama. Then came the Monday scheduled sweep. That run went a different direction: 18 turns, 817,000 tokens, and after all that contemplation… a failure. Somewhere between turn one and turn eighteen, the triage workflow decided this batch of issues deserved its most thoughtful analysis yet, burned through a frontier model’s patience, and still couldn’t quite close the loop.
It’s the classic overachiever problem — sometimes the issues that look the simplest turn out to be the ones that take all day.
**Usage tip**: If your `auto-triage-issues` scheduled runs are consistently expensive, the new `agentic_fraction` metric in `gh aw audit` can help you identify which turns are pure data-gathering and could be moved to deterministic shell steps.
→ [View the workflow on GitHub](https://github.com/github/gh-aw/blob/main/.github/workflows/auto-triage-issues.md)
***
## Try It Out
[Section titled “Try It Out”](#try-it-out)
Update to [v0.64.4](https://github.com/github/gh-aw/releases/tag/v0.64.4) today with `gh extension upgrade aw`. The integrity-aware cache-memory migration will trigger a one-time cache miss on first run — expected and safe. As always, questions and contributions are welcome in [github/gh-aw](https://github.com/github/gh-aw).
# Weekly Update – April 6, 2026
> Ten releases in seven days: full OpenTelemetry distributed tracing, a new report_incomplete safe output, Claude Code 1.0.0 support, and security hardening across the board.
Ten releases landed in [github/gh-aw](https://github.com/github/gh-aw) between March 31 and April 6 — a relentless pace that delivered production-ready distributed tracing, new safe output signals, and a sweeping security cleanup. Here’s what shipped.
## Release Highlights
[Section titled “Release Highlights”](#release-highlights)
### [v0.67.1](https://github.com/github/gh-aw/releases/tag/v0.67.1) — OpenTelemetry Overhaul & Security Hardening (April 6)
[Section titled “v0.67.1 — OpenTelemetry Overhaul & Security Hardening (April 6)”](#v0671--opentelemetry-overhaul--security-hardening-april-6)
The headline release of the week polishes the OTLP tracing story introduced in v0.67.0 and adds a wave of security fixes.
* **Accurate span names and real job durations** ([#24823](https://github.com/github/gh-aw/pull/24823)): Job lifecycle spans now use the actual job name (e.g. `gh-aw.agent.conclusion`) and record real execution time — previously spans always reported 2–5 ms due to a missing `startMs`.
* **OTLP payload sanitization**: Sensitive values (`token`, `secret`, `key`, `auth`, etc.) in span attributes are automatically redacted before sending to any OTLP collector.
* **OTLP headers masking** ([#24805](https://github.com/github/gh-aw/pull/24805)): `OTEL_EXPORTER_OTLP_HEADERS` is masked with `::add-mask::` in every job, preventing auth tokens from leaking into GitHub Actions debug logs.
* **MCP Gateway OpenTelemetry** ([#24697](https://github.com/github/gh-aw/pull/24697)): The MCP Gateway now receives OpenTelemetry config derived from `observability.otlp` frontmatter and the `actions/setup` trace IDs, correlating all MCP tool-call traces under the workflow root trace.
* **`report_incomplete` safe output** ([#24796](https://github.com/github/gh-aw/pull/24796)): A new first-class signal lets agents surface infrastructure or tool failures without being misclassified as successful runs. When an agent emits `report_incomplete`, the safe-outputs handler activates failure handling regardless of agent exit code.
* **`checks` as a first-class MCP tool** ([#24818](https://github.com/github/gh-aw/pull/24818)): The `checks` tool is now registered in the gh-aw MCP server, returning a normalized CI verdict (`success`, `failed`, `pending`, `no_checks`, `policy_blocked`).
* **Token/secret injection prevention**: 422 instances of `${{ secrets.* }}` interpolated directly into `run:` blocks were moved to `env:` mappings across lock files.
* **Claude Code 1.0.0 compatibility** ([#24807](https://github.com/github/gh-aw/pull/24807)): Removed the `--disable-slash-commands` flag that was dropped in Claude Code 1.0.0.
### [v0.67.0](https://github.com/github/gh-aw/releases/tag/v0.67.0) — OTLP Trace Export & GitHub API Rate Limit Analytics (April 5)
[Section titled “v0.67.0 — OTLP Trace Export & GitHub API Rate Limit Analytics (April 5)”](#v0670--otlp-trace-export--github-api-rate-limit-analytics-april-5)
The milestone release that first shipped distributed tracing support:
* **`observability.otlp` frontmatter**: Workflows can now export structured OpenTelemetry spans to any OTLP-compatible backend (Honeycomb, Grafana Tempo, Sentry) with a single frontmatter block. Every job emits setup and conclusion spans; cross-job trace correlation is wired automatically with a single trace ID from the activation job.
* **GitHub API rate limit analytics**: `gh aw audit`, `gh aw logs`, and `gh aw audit diff` now show GitHub API quota consumed per run, per resource.
* **Environment Variable Reference**: A new comprehensive reference section covers all CLI configuration variables.
### [v0.66.1](https://github.com/github/gh-aw/releases/tag/v0.66.1) — Richer `gh aw logs` & Breaking Change (April 4)
[Section titled “v0.66.1 — Richer gh aw logs & Breaking Change (April 4)”](#v0661--richer-gh-aw-logs--breaking-change-april-4)
**! Breaking change**: `gh aw audit report` has been removed. Cross-run security reports are now generated directly by `gh aw logs --format`. The new `--last` flag aliases `--count` to ease migration.
* **Flat run classification** in `gh aw logs --json`: Each run now carries a top-level `classification` string (`"risky"`, `"normal"`, `"baseline"`, or `"unclassified"`), eliminating null-guard gymnastics.
* **Per-tool-call metrics in logs**: Granular token usage, failure counts, and latency per tool — perfect for identifying which tools consume the most resources.
### [v0.66.0](https://github.com/github/gh-aw/releases/tag/v0.66.0) — Token Usage Artifacts & Threat Detection Extensibility (April 3)
[Section titled “v0.66.0 — Token Usage Artifacts & Threat Detection Extensibility (April 3)”](#v0660--token-usage-artifacts--threat-detection-extensibility-april-3)
* **Token Usage Artifact** ([#24315](https://github.com/github/gh-aw/pull/24315)): Agent token usage is now uploaded as a workflow artifact, making it easy to track spend over time.
* Workflow reliability and threat detection extensibility improvements shipped alongside.
### Earlier in the week
[Section titled “Earlier in the week”](#earlier-in-the-week)
[v0.65.7](https://github.com/github/gh-aw/releases/tag/v0.65.7) through [v0.65.2](https://github.com/github/gh-aw/releases/tag/v0.65.2) (March 31–April 3) focused on cross-repo workflow reliability, MCP gateway keepalive configuration, safe-outputs improvements, and token optimization tooling.
***
## Agent of the Week: agentic-observability-kit
[Section titled “ Agent of the Week: agentic-observability-kit”](#-agent-of-the-week-agentic-observability-kit)
The tireless watchdog that monitors your entire fleet of agentic workflows and escalates when things go sideways.
Every day, `agentic-observability-kit` pulls logs from all running workflows, classifies their behavior, and posts a structured observability report as a GitHub Discussion — then files issues when patterns of waste or failure cross defined thresholds. This past week it had a particularly eventful run: on April 6 it spotted that `smoke-copilot` and `smoke-claude` had each burned through 675K–1.7M tokens across multiple runs (flagged as `resource_heavy_for_domain` with high severity), and it filed an issue titled *“Smoke Copilot and Smoke Claude repeatedly resource-heavy”* before anyone on the team had noticed. It also caught that the GitHub Remote MCP Authentication Test workflow had a 100% failure rate across two runs — one of which completed at zero tokens, suggesting a config or auth problem rather than an agent misbehaving.
In a delightfully meta moment, the observability kit itself hit token-limit errors while trying to ingest its own log data — it made four attempts with progressively smaller `count` and `max_tokens` parameters before it could fit the output into context. It got there in the end.
**Usage tip**: Pair `agentic-observability-kit` with Slack or email notifications so escalation issues trigger an alert — otherwise the issues it files can sit unread while the token bill quietly grows.
→ [View the workflow on GitHub](https://github.com/github/gh-aw/blob/main/.github/workflows/agentic-observability-kit.md)
***
## Try It Out
[Section titled “Try It Out”](#try-it-out)
Update to [v0.67.1](https://github.com/github/gh-aw/releases/tag/v0.67.1) and start exporting traces from your workflows today — all it takes is an `observability.otlp` block in your frontmatter. Feedback and contributions are always welcome in [github/gh-aw](https://github.com/github/gh-aw).
# Comment-Triggered Workflows
> Interactive workflows triggered by slash commands in issues, PRs, and discussions - ChatOps patterns for human-in-the-loop automation
Comment-triggered workflows respond to slash commands typed in GitHub conversations. They enable ChatOps patterns where team members interact with AI agents through natural commands like `/review`, `/deploy`, or `/analyze`.
## When to Use Comment-Triggered Workflows
[Section titled “When to Use Comment-Triggered Workflows”](#when-to-use-comment-triggered-workflows)
* **Interactive assistance**: Code review helpers, analysis on demand
* **Controlled automation**: Human decides when workflow runs
* **Context-aware responses**: AI acts on specific issue/PR context
* **Team collaboration**: Shared commands for common tasks
## Patterns in This Section
[Section titled “Patterns in This Section”](#patterns-in-this-section)
* **[ChatOps](/gh-aw/patterns/chat-ops/)** - Build interactive automation with command triggers
## Example Command Triggers
[Section titled “Example Command Triggers”](#example-command-triggers)
```yaml
on:
slash_command:
name: review # Responds to /review
events: [pull_request_comment]
```
```yaml
on:
slash_command:
name: analyze
events: [issue_comment, pull_request_comment]
```
## Quick Start
[Section titled “Quick Start”](#quick-start)
Add a ChatOps workflow to your repository:
```bash
gh aw add-wizard githubnext/agentics/repo-ask
```
Then trigger it by commenting `/review` on a pull request!
# Issue & PR Event Workflows
> Workflows triggered by GitHub events - issues opened, PRs created, labels added - for automated triage, analysis, and code assistance
Issue and PR event workflows run automatically when specific GitHub events occur. They’re ideal for automated triage, intelligent labeling, code analysis, and quality checks that happen without any manual trigger.
## When to Use Event-Triggered Workflows
[Section titled “When to Use Event-Triggered Workflows”](#when-to-use-event-triggered-workflows)
* **Immediate response**: Auto-triage new issues, welcome contributors
* **Automated analysis**: Accessibility audits, security scans
* **Smart labeling**: Classify issues/PRs based on content
* **Quality gates**: Run checks when PRs are opened or updated
## Patterns in This Section
[Section titled “Patterns in This Section”](#patterns-in-this-section)
* **[IssueOps](/gh-aw/patterns/issue-ops/)** - Automate issue triage and management
* **[LabelOps](/gh-aw/patterns/label-ops/)** - Use labels as workflow triggers
* **[ProjectOps](/gh-aw/patterns/project-ops/)** - Automate project board management
* **[Triage & Analysis](/gh-aw/examples/issue-pr-events/triage-analysis/)** - Intelligent triage and problem investigation
* **[Coding & Development](/gh-aw/examples/issue-pr-events/coding-development/)** - PR assistance and code improvements
* **[Quality & Testing](/gh-aw/examples/issue-pr-events/quality-testing/)** - Automated quality checks
## Example Event Triggers
[Section titled “Example Event Triggers”](#example-event-triggers)
```yaml
on:
issues:
types: [opened, labeled]
```
```yaml
on:
pull_request:
types: [opened, synchronize]
```
```yaml
on:
pull_request_target:
types: [labeled]
branches: [main]
```
## Quick Start
[Section titled “Quick Start”](#quick-start)
Add event-triggered workflows to your repository:
```bash
gh aw add-wizard githubnext/agentics/issue-triage
gh aw add-wizard githubnext/agentics/pr-fix
```
# Coding & Development
> PR assistance, dependency updates, and documentation maintenance - automated development help
Coding and development workflows streamline common development tasks through intelligent automation, reducing manual overhead and improving code quality. You can write your own workflows tailored to your specific technology stack and development practices.
## When to Use Coding & Development Workflows
[Section titled “When to Use Coding & Development Workflows”](#when-to-use-coding--development-workflows)
* **PR assistance** - Automated code review suggestions
* **Dependency updates** - Smart package upgrade proposals
* **Documentation sync** - Keep docs in sync with code changes
* **Code generation** - Automated boilerplate or tests
## Sample Workflows
[Section titled “Sample Workflows”](#sample-workflows)
### Daily Dependabot PR Bundler
[Section titled “Daily Dependabot PR Bundler”](#daily-dependabot-pr-bundler)
This workflow checks Dependabot alerts and updates dependencies in package manifests (not just lock files). Bundles multiple compatible updates into single pull requests, runs tests to verify compatibility, and creates draft PRs with working changes. Documents investigation attempts for problematic updates. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/dependabot-pr-bundler.md)
### Regular Documentation Update
[Section titled “Regular Documentation Update”](#regular-documentation-update)
Analyzes code changes and creates documentation PRs using Diátaxis methodology to ensure documentation stays current with code changes and API updates. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/update-docs.md)
### PR Fix
[Section titled “PR Fix”](#pr-fix)
Investigates failing PR checks, identifies root causes, and pushes fixes to PR branches to speed up PR resolution and reduce developer context switching. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/pr-fix.md)
### Daily Adhoc QA
[Section titled “Daily Adhoc QA”](#daily-adhoc-qa)
Follows README instructions, tests build processes, and validates user experience to catch user experience issues and documentation problems proactively. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/daily-qa.md)
### Grumpy Code Reviewer
[Section titled “Grumpy Code Reviewer”](#grumpy-code-reviewer)
Reviews pull request code changes with a grumpy senior developer personality, identifying code smells, performance issues, security concerns, and best practice violations. Triggered by `/grumpy` command on PR comments and uses cache memory to avoid duplicate feedback. [Learn more](https://github.com/github/gh-aw/blob/main/.github/workflows/grumpy-reviewer.md)
## Security Considerations
[Section titled “Security Considerations”](#security-considerations)
Caution
Coding workflows have network access and execute in GitHub Actions. Review all outputs carefully before merging, as they could potentially be influenced by untrusted inputs like issue descriptions or comments.
# Quality & Testing
> Test coverage improvements and performance optimization - automated quality enhancements
Quality and testing workflows automate test coverage analysis, performance optimization, and systematic quality improvements.
## When to Use Quality & Testing Workflows
[Section titled “When to Use Quality & Testing Workflows”](#when-to-use-quality--testing-workflows)
* **Test coverage** - Daily incremental test improvements
* **Performance checks** - Automated performance regression detection
* **Quality gates** - Enforce standards on PRs
* **Systematic improvements** - Gradual quality enhancements
### Daily Test Coverage Improver
[Section titled “Daily Test Coverage Improver”](#daily-test-coverage-improver)
Analyzes test coverage, identifies gaps, and creates PRs with comprehensive tests to systematically improve code quality and reduce bugs. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/daily-test-improver.md)
### Daily Performance Improver
[Section titled “Daily Performance Improver”](#daily-performance-improver)
Identifies performance bottlenecks, runs benchmarks, and implements optimizations to proactively improve application performance. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/daily-perf-improver.md)
### Test Failure Investigation
[Section titled “Test Failure Investigation”](#test-failure-investigation)
Automatically investigates failed workflow runs by analyzing logs, identifying root causes, and creating detailed investigation reports with actionable recommendations to prevent similar failures. [Learn more](https://github.com/github/gh-aw/blob/main/.github/workflows/smoke-detector.md)
# Triage & Analysis
> Automated issue triage, accessibility reviews, and CI failure investigation - intelligent problem analysis
Triage and analysis workflows provide intelligent automation for managing issues, investigating problems, and ensuring quality standards.
## When to Use Triage & Analysis Workflows
[Section titled “When to Use Triage & Analysis Workflows”](#when-to-use-triage--analysis-workflows)
* **Auto-triage issues** - Classify and prioritize incoming issues
* **Accessibility audits** - Automated a11y checks on PRs
* **CI failure analysis** - Investigate and explain test failures
* **Problem investigation** - Deep dive into reported issues
Here are sample workflows from the Agentics collection you can customize for your project:
### Issue Triage
[Section titled “Issue Triage”](#issue-triage)
Analyzes new issues, applies appropriate labels, and provides triage comments for consistent issue management. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/issue-triage.md)
### CI Doctor
[Section titled “CI Doctor”](#ci-doctor)
Investigates failed CI runs, identifies patterns, and provides actionable fix recommendations to reduce time to resolution. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/ci-doctor.md)
### Daily Accessibility Review
[Section titled “Daily Accessibility Review”](#daily-accessibility-review)
Performs automated accessibility scans using WCAG 2.2 standards and browser automation to ensure inclusive user experiences. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/daily-accessibility-review.md)
# Manual Workflows
> On-demand workflows triggered manually via workflow_dispatch - research, analysis, and tasks you run when needed
Manual workflows run only when explicitly triggered via the GitHub Actions UI or CLI. They’re perfect for on-demand tasks like research, analysis, or operations that need human judgment about timing.
## When to Use Manual Workflows
[Section titled “When to Use Manual Workflows”](#when-to-use-manual-workflows)
* **On-demand research**: Search and analyze topics as needed
* **Manual operations**: Tasks requiring human judgment on timing
* **Testing and debugging**: Run workflows with custom inputs
* **One-time tasks**: Operations that don’t fit a schedule
## Example Manual Triggers
[Section titled “Example Manual Triggers”](#example-manual-triggers)
```yaml
on:
workflow_dispatch:
inputs:
topic:
description: 'Research topic'
required: true
type: string
```
```yaml
on:
workflow_dispatch:
inputs:
severity:
description: 'Issue severity level'
required: false
type: choice
options:
- low
- medium
- high
```
## Accessing Inputs in Workflows
[Section titled “Accessing Inputs in Workflows”](#accessing-inputs-in-workflows)
Use `${{ github.event.inputs.INPUT_NAME }}` to access input values in your workflow markdown:
```aw
---
on:
workflow_dispatch:
inputs:
topic:
description: 'Research topic'
required: true
type: string
depth:
description: 'Analysis depth'
type: choice
options:
- brief
- detailed
default: brief
permissions:
contents: read
safe-outputs:
create-discussion:
---
# Research Assistant
Research the topic: "${{ github.event.inputs.topic }}"
Analysis depth: ${{ github.event.inputs.depth }}
Provide findings based on the requested depth level.
```
## Running Manual Workflows
[Section titled “Running Manual Workflows”](#running-manual-workflows)
Via CLI:
```bash
gh aw run workflow
```
Via GitHub Actions UI:
1. Go to Actions tab
2. Select workflow
3. Click “Run workflow”
4. Fill in inputs (if any)
5. Click “Run workflow” button
## Quick Start
[Section titled “Quick Start”](#quick-start)
Add a manual workflow to your repository:
```bash
gh aw add-wizard githubnext/agentics/weekly-research
```
Then run it:
```bash
gh aw run weekly-research
```
# Multi-Repository Examples
> Complete examples for managing workflows across multiple GitHub repositories, including feature synchronization, cross-repo tracking, and organization-wide updates.
Multi-repository operations enable coordinating work across multiple GitHub repositories while maintaining security and proper access controls. These examples demonstrate common patterns for cross-repo workflows.
## Featured Examples
[Section titled “Featured Examples”](#featured-examples)
### [Feature Synchronization](/gh-aw/examples/multi-repo/feature-sync/)
[Section titled “Feature Synchronization”](#feature-synchronization)
Automates code synchronization from main repositories to sub-repositories or downstream services through pull requests with change detection, path filters, and bidirectional sync support. Use for monorepo alternatives, shared component libraries, multi-platform deployments, or fork maintenance.
### [Cross-Repository Issue Tracking](/gh-aw/examples/multi-repo/issue-tracking/)
[Section titled “Cross-Repository Issue Tracking”](#cross-repository-issue-tracking)
Centralizes issue tracking by automatically creating tracking issues in a central repository with status synchronization and multi-component coordination. Use for component-based architecture visibility, multi-team coordination, cross-project initiatives, or upstream dependency tracking.
## Getting Started
[Section titled “Getting Started”](#getting-started)
All multi-repo workflows require proper authentication:
### Personal Access Token Setup
[Section titled “Personal Access Token Setup”](#personal-access-token-setup)
```bash
# Create PAT with required permissions
gh auth token
# Store as repository or organization secret
gh aw secrets set GH_AW_CROSS_REPO_PAT --value "ghp_your_token_here"
```
The PAT needs permissions **only on target repositories** (not the source repository where the workflow runs): `repo` for private repos, `contents: write` for commits, `issues: write` for issues, and `pull-requests: write` for PRs.
Tip
**Security Best Practice**: If you only need to read from one repo and write to another, scope your PAT to have read access on the source and write access only on target repositories. Use separate tokens for different operations when possible.
### GitHub App Configuration
[Section titled “GitHub App Configuration”](#github-app-configuration)
For enhanced security, use GitHub Apps for automatic token minting and revocation. GitHub App tokens are minted on-demand, automatically revoked after job completion, and provide better security than long-lived PATs.
See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication) for complete configuration examples including specific repository scoping and org-wide access.
## Common Patterns
[Section titled “Common Patterns”](#common-patterns)
### Hub-and-Spoke Architecture
[Section titled “Hub-and-Spoke Architecture”](#hub-and-spoke-architecture)
Central repository aggregates information from multiple component repositories:
```text
Component Repo A ──┐
Component Repo B ──┼──> Central Tracker
Component Repo C ──┘
```
### Upstream-to-Downstream Sync
[Section titled “Upstream-to-Downstream Sync”](#upstream-to-downstream-sync)
Main repository propagates changes to downstream repositories:
```text
Main Repo ──> Sub-Repo Alpha
──> Sub-Repo Beta
──> Sub-Repo Gamma
```
### Organization-Wide Coordination
[Section titled “Organization-Wide Coordination”](#organization-wide-coordination)
Single workflow creates issues across multiple repositories:
```text
Control Workflow ──> Repo 1 (tracking issue)
──> Repo 2 (tracking issue)
──> Repo 3 (tracking issue)
──> ... (up to max limit)
```
## Cross-Repository Safe Outputs
[Section titled “Cross-Repository Safe Outputs”](#cross-repository-safe-outputs)
Most safe output types support the `target-repo` parameter for cross-repository operations. **Without `target-repo`, these safe outputs operate on the repository where the workflow is running.**
| Safe Output | Cross-Repo Support | Example Use Case |
| ---------------------- | ------------------ | -------------------------------------- |
| `create-issue` | ✓ | Create tracking issues in central repo |
| `add-comment` | ✓ | Comment on issues in other repos |
| `update-issue` | ✓ | Update issue status across repos |
| `add-labels` | ✓ | Label issues in target repos |
| `create-pull-request` | ✓ | Create PRs in downstream repos |
| `create-discussion` | ✓ | Create discussions in any repo |
| `create-agent-session` | ✓ | Create tasks in target repos |
| `update-release` | ✓ | Update release notes across repos |
| `update-project` | ✓ (`target_repo`) | Update project items from other repos |
**Configuration Example:**
```yaml
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
target-repo: "org/tracking-repo" # Cross-repo: creates in tracking-repo
title-prefix: "[component] "
add-comment:
# No target-repo: operates on current repository
```
See [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) for complete configuration options.
## GitHub API Tools for Multi-Repo Access
[Section titled “GitHub API Tools for Multi-Repo Access”](#github-api-tools-for-multi-repo-access)
Enable GitHub toolsets to allow agents to query multiple repositories:
```yaml
tools:
github:
toolsets: [repos, issues, pull_requests, actions]
```
Agents can access **repos** (read files, search code, list commits, get releases), **issues** (list and search across repositories), **pull\_requests** (list and search PRs), and **actions** (workflow runs and artifacts).
## Best Practices
[Section titled “Best Practices”](#best-practices)
Use GitHub Apps for automatic token revocation, scope PATs minimally, rotate tokens regularly, and store them as GitHub secrets. Set appropriate `max` limits on safe outputs, use meaningful title prefixes and consistent labels, and include clear documentation in created items. Validate repository access before operations, handle rate limits appropriately, and monitor workflow execution. Test with public repositories first, pilot with small subsets, verify configurations, and monitor costs.
## Advanced Topics
[Section titled “Advanced Topics”](#advanced-topics)
### Private Repository Access
[Section titled “Private Repository Access”](#private-repository-access)
When working with private repositories, ensure the PAT owner has repository access, install GitHub Apps in target organizations, configure repository lists explicitly, and test permissions before full rollout.
### Deterministic Workflows
[Section titled “Deterministic Workflows”](#deterministic-workflows)
For direct repository access, use an AI engine with custom steps via `actions/checkout`:
```yaml
engine:
id: claude
steps:
- name: Checkout main repo
uses: actions/checkout@v6
with:
path: main-repo
- name: Checkout secondary repo
uses: actions/checkout@v6
with:
repository: org/secondary-repo
token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
path: secondary-repo
```
### Organization-Level Operations
[Section titled “Organization-Level Operations”](#organization-level-operations)
For organization-wide workflows, use organization-level secrets, configure GitHub Apps at organization level, plan phased rollouts, and provide clear communication.
## Complete Guide
[Section titled “Complete Guide”](#complete-guide)
For comprehensive documentation on the MultiRepoOps design pattern, see:
[MultiRepoOps Design Pattern](/gh-aw/patterns/multi-repo-ops/)
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Cross-Repository Operations](/gh-aw/reference/cross-repository/) - Checkout and target-repo configuration
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Configuration options
* [GitHub Tools](/gh-aw/reference/github-tools/) - API access configuration
* [Security Best Practices](/gh-aw/introduction/architecture/) - Authentication and security
* [Reusing Workflows](/gh-aw/guides/packaging-imports/) - Sharing workflows
# Feature Synchronization
> Synchronize features from a main repository to sub-repositories or downstream services with automated pull requests.
Feature synchronization workflows propagate changes from a main repository to related sub-repositories, ensuring downstream projects stay current with upstream improvements while maintaining proper change tracking through pull requests.
## When to Use
[Section titled “When to Use”](#when-to-use)
Use feature sync when maintaining related projects in separate repositories (monorepo alternative), propagating library updates to dependent projects, updating platform-specific repos after core changes, or keeping downstream forks synchronized with upstream.
## How It Works
[Section titled “How It Works”](#how-it-works)
The workflow monitors specific paths in the main repository and creates pull requests in target repositories when changes occur, adapting the changes for each target’s structure while maintaining full audit trails.
## Basic Feature Sync
[Section titled “Basic Feature Sync”](#basic-feature-sync)
Synchronize changes from shared directory to downstream repository:
```aw
---
on:
push:
branches: [main]
paths:
- 'shared/**'
permissions:
contents: read
actions: read
tools:
github:
toolsets: [repos]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: "myorg/downstream-service"
title-prefix: "[sync] "
labels: [auto-sync, upstream-update]
reviewers: [team-lead]
draft: true
---
# Sync Shared Components to Downstream Service
When shared components change, synchronize them to `myorg/downstream-service`. Review the git diff, read current versions from the target repo, adapt paths if needed, and create a PR with descriptive commit messages linking to original commits. Include structural adaptations and migration notes for breaking changes.
```
## Multi-Target Sync
[Section titled “Multi-Target Sync”](#multi-target-sync)
Synchronize to multiple repositories simultaneously:
```aw
---
on:
push:
branches: [main]
paths:
- 'core/**'
permissions:
contents: read
actions: read
tools:
github:
toolsets: [repos]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
max: 3
title-prefix: "[core-sync] "
labels: [automated-sync]
draft: true
---
# Sync Core Library to All Services
When core library files change, create PRs in dependent services (`myorg/api-service`, `myorg/web-frontend`, `myorg/mobile-backend`). For each target, check if they use the changed modules, adapt imports/paths, and create a PR with compatibility notes and links to source commits.
```
## Release-Based Sync
[Section titled “Release-Based Sync”](#release-based-sync)
Synchronize when new releases are published:
```aw
---
on:
release:
types: [published]
permissions:
contents: read
actions: read
tools:
github:
toolsets: [repos]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: "myorg/production-service"
title-prefix: "[upgrade] "
labels: [version-upgrade, auto-generated]
reviewers: [release-manager]
draft: false
---
# Upgrade Production Service to New Release
When a new release is published (version ${{ github.event.release.tag_name }}), create an upgrade PR that updates version references, applies API changes from release notes, updates configuration for breaking changes, and includes a migration guide with testing recommendations.
```
## Selective File Sync
[Section titled “Selective File Sync”](#selective-file-sync)
Synchronize only specific file types or patterns:
```aw
---
on:
push:
branches: [main]
paths:
- 'types/**/*.ts'
- 'interfaces/**/*.ts'
permissions:
contents: read
actions: read
tools:
github:
toolsets: [repos]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: "myorg/client-sdk"
title-prefix: "[types] "
labels: [type-definitions]
draft: true
---
# Sync TypeScript Type Definitions
Synchronize TypeScript type definitions to client SDK. Identify changed `.ts` files in `types/` and `interfaces/`, update them in `myorg/client-sdk` while preserving client-specific extensions, validate no breaking changes, and document any compatibility concerns.
```
## Bidirectional Sync with Conflict Detection
[Section titled “Bidirectional Sync with Conflict Detection”](#bidirectional-sync-with-conflict-detection)
Handle bidirectional synchronization with conflict awareness:
```aw
---
on:
push:
branches: [main]
paths:
- 'shared-config/**'
permissions:
contents: read
actions: read
tools:
github:
toolsets: [repos, pull_requests]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: "myorg/sister-project"
title-prefix: "[config-sync] "
labels: [config-update, needs-review]
draft: true
---
# Bidirectional Config Sync
Synchronize shared configuration between this project and `myorg/sister-project`, which may be modified independently. Compare timestamps and change history; if conflicts are detected, create a PR marked for manual review with conflict notes. If no conflict, apply changes automatically and record sync timestamp.
```
## Feature Branch Sync
[Section titled “Feature Branch Sync”](#feature-branch-sync)
Synchronize feature branches between repositories:
```aw
---
on:
pull_request:
types: [opened, synchronize]
branches:
- 'feature/**'
permissions:
contents: read
pull-requests: read
actions: read
tools:
github:
toolsets: [repos, pull_requests]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: "myorg/integration-tests"
title-prefix: "[feature-test] "
labels: [feature-branch, auto-sync]
draft: true
---
# Sync Feature Branch for Integration Testing
When feature branch ${{ github.event.pull_request.head.ref }} (PR #${{ github.event.pull_request.number }}) is updated, create a matching branch in the integration test repo, sync relevant changes, update test configurations, and create a PR linking to the source with test scenarios and integration points.
```
## Scheduled Sync Check
[Section titled “Scheduled Sync Check”](#scheduled-sync-check)
Regularly check for sync drift and create catch-up PRs:
```aw
---
on: weekly on monday
permissions:
contents: read
actions: read
tools:
github:
toolsets: [repos, pull_requests]
edit:
bash:
- "git:*"
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: "myorg/downstream-fork"
title-prefix: "[weekly-sync] "
labels: [scheduled-sync]
draft: true
---
# Weekly Sync Check
Check for accumulated changes needing synchronization to downstream fork. Find the last sync PR, identify all commits since then, categorize changes (features, fixes, docs), and create a comprehensive PR grouping commits by category with breaking changes highlighted and migration guidance.
```
## Authentication Setup
[Section titled “Authentication Setup”](#authentication-setup)
Cross-repo sync workflows require authentication via PAT or GitHub App.
### PAT Configuration
[Section titled “PAT Configuration”](#pat-configuration)
Create a PAT with `repo`, `contents: write`, and `pull-requests: write` permissions, then store it as a repository secret:
```bash
gh aw secrets set GH_AW_CROSS_REPO_PAT --value "ghp_your_token_here"
```
### GitHub App Configuration
[Section titled “GitHub App Configuration”](#github-app-configuration)
For enhanced security, use GitHub App installation tokens. See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication) for complete configuration including repository scoping options.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [MultiRepoOps Design Pattern](/gh-aw/patterns/multi-repo-ops/) - Complete multi-repo overview
* [Cross-Repo Issue Tracking](/gh-aw/examples/multi-repo/issue-tracking/) - Issue management patterns
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Pull request configuration
* [GitHub Tools](/gh-aw/reference/github-tools/) - Repository access tools
# Cross-Repository Issue Tracking
> Centralize issue tracking across multiple repositories with automated tracking issue creation and status synchronization.
Cross-repository issue tracking enables organizations to maintain a centralized view of work across multiple component repositories. When issues are created in component repos, tracking issues are automatically created in a central repository, providing visibility without requiring direct access to all repositories.
## When to Use
[Section titled “When to Use”](#when-to-use)
Use cross-repo issue tracking for component-based architectures where multiple teams need centralized visibility, when tracking external dependencies, coordinating cross-project initiatives, or aggregating metrics from distributed repositories.
## How It Works
[Section titled “How It Works”](#how-it-works)
Workflows in component repositories create tracking issues in a central repository when local issues are opened, updated, or closed. The central repository maintains references to all component issues, enabling organization-wide visibility and reporting.
## Basic Tracking Issue Creation
[Section titled “Basic Tracking Issue Creation”](#basic-tracking-issue-creation)
Create tracking issues in central repository when component issues are opened:
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
target-repo: "myorg/central-tracker"
title-prefix: "[component-alpha] "
labels: [from-component-alpha, tracking-issue]
---
# Create Central Tracking Issue
When an issue is opened in component-alpha, create a corresponding
tracking issue in the central tracker.
**Original issue:** ${{ github.event.issue.html_url }}
**Issue number:** ${{ github.event.issue.number }}
**Content:** "${{ steps.sanitized.outputs.text }}"
Create tracking issue with link to original, component identifier, summary, suggested priority, and labels `from-component-alpha` and `tracking-issue`.
```
## Status Synchronization
[Section titled “Status Synchronization”](#status-synchronization)
Update tracking issues when component issues change status:
```aw
---
on:
issues:
types: [closed, reopened, labeled, unlabeled]
permissions:
contents: read
actions: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
add-comment:
target-repo: "myorg/central-tracker"
target: "*" # Find related tracking issue
---
# Update Central Tracking Issue Status
When this component issue changes status, update the central tracking issue.
**Original issue:** ${{ github.event.issue.html_url }}
**Action:** ${{ github.event.action }}
Search for tracking issue in `myorg/central-tracker` and add comment with status update (✓ resolved, reopened, or label changes), issue link, and timestamp.
```
## Multi-Component Tracking
[Section titled “Multi-Component Tracking”](#multi-component-tracking)
Track issues that span multiple component repositories:
```aw
---
on:
issues:
types: [opened]
# Triggered when issue has 'cross-component' label
permissions:
contents: read
actions: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
max: 3 # May create issues in multiple tracking repos
target-repo: "myorg/central-tracker"
title-prefix: "[cross-component] "
labels: [cross-component, needs-coordination]
---
# Track Cross-Component Issues
When an issue is marked as cross-component, create coordinated tracking issues.
**Original issue:** ${{ github.event.issue.html_url }}
Identify affected components, create primary tracking issue in central tracker with affected components list and coordination requirements, and create child issues in component repos if needed. Tag team leads and schedule coordination meeting for high-priority issues.
```
## External Dependency Tracking
[Section titled “External Dependency Tracking”](#external-dependency-tracking)
Track issues from external/upstream repositories:
```aw
---
on:
workflow_dispatch:
inputs:
external_issue_url:
description: 'URL of external issue to track'
required: true
type: string
permissions:
contents: read
tools:
github:
toolsets: [issues]
web-fetch:
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
target-repo: "myorg/dependency-tracker"
title-prefix: "[upstream] "
labels: [external-dependency, upstream-issue]
---
# Track External Dependency Issue
Create tracking issue for external dependency problem.
**External issue URL:** ${{ github.event.inputs.external_issue_url }}
Fetch external issue details, identify affected internal projects, and create tracking issue with external link, status, impact assessment, affected repositories, and monitoring plan. Set weekly reminder and notify affected teams.
```
## Automated Triage and Routing
[Section titled “Automated Triage and Routing”](#automated-triage-and-routing)
Triage component issues and route to appropriate trackers:
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
max: 2
title-prefix: "[auto-triaged] "
---
# Triage and Route to Tracking Repos
Analyze new issues and create tracking issues in appropriate repositories.
**Original issue:** ${{ github.event.issue.html_url }}
**Content:** "${{ steps.sanitized.outputs.text }}"
Analyze issue severity and route to appropriate tracker: security issues to `myorg/security-tracker`, features to `myorg/feature-tracker`, bugs to `myorg/bug-tracker`, or infrastructure to `myorg/ops-tracker`. Include original link, triage reasoning, priority, affected components, and SLA targets.
```
## Aggregated Reporting
[Section titled “Aggregated Reporting”](#aggregated-reporting)
Create weekly summary of tracked issues:
```aw
---
on: weekly on monday
permissions:
contents: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-discussion:
target-repo: "myorg/central-tracker"
category: "Status Reports"
title-prefix: "[weekly] "
---
# Weekly Cross-Repo Issue Summary
Generate weekly summary of tracked issues across all component repositories.
Summarize issues from all component repositories including open counts by priority, issues opened/closed this week, stale issues (>30 days), and blockers. Create discussion with executive summary, per-repo breakdown, trending analysis, and action items formatted as markdown table.
```
## Bidirectional Linking
[Section titled “Bidirectional Linking”](#bidirectional-linking)
Maintain references between component and tracking issues:
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
target-repo: "myorg/central-tracker"
title-prefix: "[linked] "
add-comment:
max: 1
---
# Create Tracking Issue with Bidirectional Links
Create tracking issue and add comment to original with link.
**Original issue:** ${{ github.event.issue.html_url }}
Create tracking issue in `myorg/central-tracker` with title "[linked] ${{ github.event.issue.title }}" and body linking to original. Add comment to original issue with tracking link. This enables easy navigation, automatic GitHub reference detection, and clear audit trail.
```
## Priority-Based Routing
[Section titled “Priority-Based Routing”](#priority-based-routing)
Route issues to different trackers based on priority:
```aw
---
on:
issues:
types: [opened, labeled]
permissions:
contents: read
actions: read
tools:
github:
toolsets: [issues]
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
max: 1
title-prefix: "[priority-routed] "
---
# Route Issues Based on Priority
Route issues to appropriate tracking repository based on priority level.
**Original issue:** ${{ github.event.issue.html_url }}
**Labels:** Check for priority labels (P0, P1, P2, P3)
Route by priority: P0 → `myorg/incidents`, P1 → `myorg/priority-tracker`, P2 → `myorg/central-tracker`, P3 → `myorg/backlog`. Include original link, priority, SLA expectations, and escalation path. For P0, alert on-call team and include incident response checklist.
```
## Authentication Setup
[Section titled “Authentication Setup”](#authentication-setup)
Cross-repo issue tracking requires appropriate authentication:
### PAT Configuration
[Section titled “PAT Configuration”](#pat-configuration)
```bash
# Create PAT with issues and repository read permissions
gh aw secrets set GH_AW_CROSS_REPO_PAT --value "ghp_your_token_here"
```
**Required Permissions:**
* `repo` (for private repositories)
* `public_repo` (for public repositories)
### GitHub App Configuration
[Section titled “GitHub App Configuration”](#github-app-configuration)
For enhanced security, use GitHub App installation tokens. See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication) for complete configuration including repository scoping options.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [MultiRepoOps Design Pattern](/gh-aw/patterns/multi-repo-ops/) - Complete multi-repo overview
* [Feature Synchronization](/gh-aw/examples/multi-repo/feature-sync/) - Code sync patterns
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Issue creation configuration
* [GitHub Tools](/gh-aw/reference/github-tools/) - API access configuration
# Project Tracking
> Automatically track issues and pull requests in GitHub Projects boards using safe-outputs configuration
The `update-project` and `create-project-status-update` safe-output tools enable automatic tracking of workflow-created items in GitHub Projects boards. Configure these tools in the `safe-outputs` section of your workflow frontmatter to enable project management capabilities including item addition, field updates, and status reporting.
## Quick Start
[Section titled “Quick Start”](#quick-start)
Add project configuration to your workflow’s `safe-outputs` section:
```yaml
---
on:
issues:
types: [opened]
safe-outputs:
create-issue:
max: 3
update-project:
project: https://github.com/orgs/github/projects/123
max: 10
create-project-status-update:
project: https://github.com/orgs/github/projects/123
max: 1
---
```
This enables:
* **update-project** - Add items to projects, update fields (status, priority, etc.)
* **create-project-status-update** - Post status updates to project boards
## Configuration
[Section titled “Configuration”](#configuration)
### Update Project Configuration
[Section titled “Update Project Configuration”](#update-project-configuration)
Configure `update-project` in the `safe-outputs` section:
```yaml
safe-outputs:
update-project:
project: https://github.com/orgs/github/projects/123 # Default project URL
max: 20 # Max operations per run (default: 10)
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
views: # Optional: auto-create views
- name: "Sprint Board"
layout: board
filter: "is:issue is:open"
- name: "Task Tracker"
layout: table
```
Supported operations: `add` (add items), `update` (update fields), `create_fields` (custom fields), `create_views` (project views).
### Project Status Update Configuration
[Section titled “Project Status Update Configuration”](#project-status-update-configuration)
Configure `create-project-status-update` to post status updates — useful for progress reports, milestone summaries, and workflow health indicators:
```yaml
safe-outputs:
create-project-status-update:
project: https://github.com/orgs/github/projects/123 # Default project URL
max: 1 # Max status updates per run (default: 1)
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
```
| Field | Type | Default | Description |
| -------------- | ------- | -------------- | ------------------------------------------------------------------------------- |
| `project` | string | (required) | GitHub Project URL for update-project or create-project-status-update |
| `max` | integer | 10 | Maximum operations per run (update-project) or 1 (create-project-status-update) |
| `github-token` | string | `GITHUB_TOKEN` | Custom token with Projects permissions |
| `views` | array | - | Optional auto-created views for update-project (with name, layout, filter) |
See [Safe Outputs: Project Board Updates](/gh-aw/reference/safe-outputs/#project-board-updates-update-project) for complete configuration details.
### Authentication
[Section titled “Authentication”](#authentication)
See [Project token authentication](/gh-aw/patterns/project-ops/#project-token-authentication).
## Example: Issue Triage
[Section titled “Example: Issue Triage”](#example-issue-triage)
Automatically add new issues to a project board with intelligent categorization:
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
issues: read
tools:
github:
toolsets: [default, projects]
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
safe-outputs:
add-comment:
max: 1
update-project:
project: https://github.com/orgs/myorg/projects/1
max: 10
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
---
# Smart Issue Triage
When a new issue is created, analyze it and add to the project board.
## Task
Examine the issue title and description to determine its type:
- **Bug reports** → Add to project, set status="Needs Triage", priority="High"
- **Feature requests** → Add to project, set status="Backlog", priority="Medium"
- **Documentation** → Add to project, set status="Todo", priority="Low"
After adding to the project board, comment on the issue confirming where it was added.
```
## Example: Pull Request Tracking
[Section titled “Example: Pull Request Tracking”](#example-pull-request-tracking)
Track pull requests through the development workflow:
```aw
---
on:
pull_request:
types: [opened, review_requested]
permissions:
contents: read
actions: read
pull-requests: read
tools:
github:
toolsets: [default, projects]
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
safe-outputs:
update-project:
project: https://github.com/orgs/myorg/projects/2
max: 5
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
---
# PR Project Tracker
Track pull requests in the development project board.
## Task
When a pull request is opened or reviews are requested:
1. Add the PR to the project board
2. Set status based on PR state:
- Just opened → "In Progress"
- Reviews requested → "In Review"
3. Set priority based on PR labels:
- Has "urgent" label → "High"
- Has "enhancement" label → "Medium"
- Default → "Low"
```
## How this fits
[Section titled “How this fits”](#how-this-fits)
* **Projects & Monitoring:** Use `update-project` to track work items and `create-project-status-update` to publish run summaries.
* **Orchestration:** An orchestrator can dispatch workers and use the same project safe-outputs to keep a shared board updated.
See:
* [Projects & Monitoring](/gh-aw/patterns/monitoring/)
* [Orchestration](/gh-aw/patterns/orchestration/)
## Common Patterns
[Section titled “Common Patterns”](#common-patterns)
### Progressive Status Updates
[Section titled “Progressive Status Updates”](#progressive-status-updates)
Move items through workflow stages:
```aw
Analyze the issue and determine its current state:
- If new and unreviewed → status="Needs Triage"
- If reviewed and accepted → status="Todo"
- If work started → status="In Progress"
- If PR merged → status="Done"
Update the project item with the appropriate status.
```
### Priority Assignment
[Section titled “Priority Assignment”](#priority-assignment)
Set priority based on content analysis:
```aw
Examine the issue for urgency indicators:
- Contains "critical", "urgent", "blocker" → priority="High"
- Contains "important", "soon" → priority="Medium"
- Default → priority="Low"
Update the project item with the assigned priority.
```
### Field-Based Routing
[Section titled “Field-Based Routing”](#field-based-routing)
Use custom fields for workflow routing:
```aw
Determine the team that should handle this issue:
- Security-related → team="Security"
- UI/UX changes → team="Design"
- API changes → team="Backend"
- Default → team="General"
Update the project item with the team field.
```
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
### Items Not Added to Project
[Section titled “Items Not Added to Project”](#items-not-added-to-project)
**Symptoms**: Workflow runs successfully but items don’t appear in project board
**Solutions**:
* Verify project URL is correct (check browser address bar)
* Confirm token has Projects: Read & Write permissions
* Check that organization allows Projects access for the token
* Review workflow logs for safe\_outputs job errors
### Permission Errors
[Section titled “Permission Errors”](#permission-errors)
**Symptoms**: Workflow fails with “Resource not accessible” or “Insufficient permissions”
**Solutions**:
* For organization projects: Use fine-grained PAT with organization Projects permission
* For user projects: Use classic PAT with `project` scope
* Ensure token is stored in correct secret name
* Verify repository settings allow Actions to access secrets
### Token Not Resolved
[Section titled “Token Not Resolved”](#token-not-resolved)
**Symptoms**: Workflow fails with “invalid token” or token appears as literal string
**Solutions**:
* Use GitHub expression syntax: `${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}`
* Don’t quote the expression in YAML
* Ensure secret name matches exactly (case-sensitive)
* Check secret is set at repository or organization level
## See Also
[Section titled “See Also”](#see-also)
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Complete safe-outputs documentation
* [update-project](/gh-aw/reference/safe-outputs/#project-board-updates-update-project) - Detailed update-project configuration
* [create-project-status-update](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update) - Status update configuration
* [Project token authentication](/gh-aw/patterns/project-ops/#project-token-authentication) - Token setup guide
* [Projects & Monitoring](/gh-aw/patterns/monitoring/) - Design pattern guide
* [Orchestration](/gh-aw/patterns/orchestration/) - Design pattern guide
# Scheduled Workflows
> Workflows that run automatically on a schedule using cron expressions - daily reports, weekly research, and continuous improvement patterns
Scheduled workflows run automatically at specified times using cron expressions. They’re perfect for recurring tasks like daily status updates, weekly research reports, continuous code improvements, and automated maintenance.
## When to Use Scheduled Workflows
[Section titled “When to Use Scheduled Workflows”](#when-to-use-scheduled-workflows)
* **Regular reporting**: Daily team status, weekly summaries
* **Continuous improvement**: Incremental code quality improvements (DailyOps)
* **Research & monitoring**: Weekly industry research, dependency updates
* **Maintenance tasks**: Cleaning up stale issues, archiving old discussions
## Patterns in This Section
[Section titled “Patterns in This Section”](#patterns-in-this-section)
* **[DailyOps](/gh-aw/patterns/daily-ops/)** - Make incremental improvements through small daily changes
* **[Research & Planning](/gh-aw/examples/scheduled/research-planning/)** - Automated research, status reports, and planning
## Example Schedule Triggers
[Section titled “Example Schedule Triggers”](#example-schedule-triggers)
**Recommended: Short fuzzy syntax**
```yaml
on: daily # Automatically scattered to different time
on: weekly # Scattered across days and times
on: weekly on monday # Scattered time on specific day
```
**Traditional cron syntax**
```yaml
on:
schedule:
- cron: "0 9 * * 1" # Every Monday at 9 AM
- cron: "0 0 * * *" # Daily at midnight
- cron: "0 */6 * * *" # Every 6 hours
```
See the [Schedule Syntax reference](/gh-aw/reference/schedule-syntax/) for complete documentation of all supported formats.
## Quick Start
[Section titled “Quick Start”](#quick-start)
Add a scheduled workflow to your repository:
```bash
gh aw add-wizard githubnext/agentics/weekly-research
gh aw add-wizard githubnext/agentics/daily-repo-status
```
# Research & Planning
> Scheduled research reports, team status updates, and automated planning - weekly/daily intelligence gathering
Research and planning workflows help teams stay informed, coordinate activities, and maintain strategic direction through automated intelligence gathering and status reporting.
## When to Use Research & Planning Workflows
[Section titled “When to Use Research & Planning Workflows”](#when-to-use-research--planning-workflows)
* **Weekly research** - Stay current with industry trends and competitors
* **Daily status reports** - Automatic team activity summaries
* **Planning updates** - Keep project plans current and visible
* **Intelligence gathering** - Automated research on specific topics
You can write your own workflows customized for your team’s specific needs. Here are some sample workflows from the Agentics collection:
### Weekly Research
[Section titled “Weekly Research”](#weekly-research)
Automatically collects latest trends, competitive analysis, and relevant research every Monday, keeping teams informed about industry developments without manual research overhead. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/weekly-research.md)
### Daily Team Status
[Section titled “Daily Team Status”](#daily-team-status)
Analyzes repository activity, pull requests, and team progress to provide automated visibility into team productivity and project health. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/daily-team-status.md)
### Daily Plan
[Section titled “Daily Plan”](#daily-plan)
Maintains and updates project planning issues with current priorities, ensuring project plans stay current and accessible to all team members. [Learn more](https://github.com/githubnext/agentics/blob/main/docs/daily-plan.md)
### Basic Research
[Section titled “Basic Research”](#basic-research)
Searches for information on a given topic, analyzes results, and creates structured summaries with relevant sources. Triggered manually via workflow\_dispatch with research topic input. Workflow file: `.github/workflows/research.md`
### Model Context Protocol (MCP) Inspector
[Section titled “Model Context Protocol (MCP) Inspector”](#model-context-protocol-mcp-inspector)
Analyzes all [MCP](/gh-aw/reference/glossary/#mcp-model-context-protocol) configuration files, extracts server details, and generates comprehensive inventory reports to maintain visibility into available [MCP servers](/gh-aw/reference/glossary/#mcp-server) and their capabilities. Runs weekly on Mondays at 10am UTC, or manually via workflow\_dispatch. Workflow file: `.github/workflows/mcp-inspector.md`
# Agentic Authoring
> More advanced techniques to author agentic workflows using agents.
Using our authoring agent is an effective way to create, debug, optimize your agentic workflows. This is a continuation of the [Create Agentic Workflows](/gh-aw/setup/creating-workflows/) page.
## Configuring Your Repository
[Section titled “Configuring Your Repository”](#configuring-your-repository)
In order to enable the agentic authoring experience, you will need to configure your repository with a few files. Run this prompt or the `init` command.
```text
Initialize this repository for GitHub Agentic Workflows using https://raw.githubusercontent.com/github/gh-aw/main/install.md
```
or
```plaintext
gh aw init
```
Make sure to commit and push the files to your repository.
## Using the GitHub Web Interface
[Section titled “Using the GitHub Web Interface”](#using-the-github-web-interface)
**If you have access to GitHub Copilot**, you can create and edit Agentic Workflows directly from the web interface. While non-interactive, it’s useful for quickly turning an idea into a working workflow. For a more interactive experience, use a coding agent (see below).
Your browser doesn't support HTML5 video. Download the video [here](/gh-aw/videos/create-workflow-on-github.mp4).
Create an agentic workflow from the GitHub web interface
Tip
On the first run in a new repository, the workflow will surely fail because the secrets are not configured. The agentic workflow should detect the missing tokens and create an issue with instructions on how to configure them.
## Remixing Workflows Between Repositories
[Section titled “Remixing Workflows Between Repositories”](#remixing-workflows-between-repositories)
When you need to adapt an existing workflow from another repository, use the `create-agentic-agent` to perform AI-assisted migration. The agent analyzes the source workflow, identifies dependencies, adapts configuration for your repository, and validates the result. This is useful for forking workflows as starting points or one-time migrations requiring substantial changes. For synchronized updates across repositories, use [Reusing Workflows](/gh-aw/guides/packaging-imports/) with `gh aw add` instead.
Example prompt for migration:
```text
Migrate the release.md workflow from github/gh-aw to this repository.
Adapt permissions and repository-specific references for our structure.
```
## Debugging Workflows
[Section titled “Debugging Workflows”](#debugging-workflows)
Use the agentic workflows agent to diagnose and fix failing workflow runs.
### Through Copilot
[Section titled “Through Copilot”](#through-copilot)
If your repository is [configured for agentic authoring](#configuring-your-repository), use the `agentic-workflows` agent in Copilot Chat:
```text
/agent agentic-workflows debug https://github.com/OWNER/REPO/actions/runs/RUN_ID
```
The agent audits the run, identifies the root cause (missing tools, permission errors, network blocks), and suggests targeted fixes.
Tip
Copy this prompt, replace `OWNER`, `REPO`, and `RUN_ID` with your values, and paste it into Copilot Chat. You can find the run URL on the GitHub Actions run page.
### Self-Contained (with URL)
[Section titled “Self-Contained (with URL)”](#self-contained-with-url)
For any AI assistant or coding agent, share the URL to the standalone debugging prompt:
```text
Debug this workflow run using https://raw.githubusercontent.com/github/gh-aw/main/debug.md
The failed workflow run is at https://github.com/OWNER/REPO/actions/runs/RUN_ID
```
Copy debug instructions
The `debug.md` file is a self-contained prompt. The agent fetches it and follows the instructions to install the `gh aw` CLI, analyze logs, apply fixes, and open a pull request with the changes.
## Advanced Techniques
[Section titled “Advanced Techniques”](#advanced-techniques)
### Planner
[Section titled “Planner”](#planner)
If you prefer to use an AI chatbot to author agentic workflows, use the [agentic-chat instructions](https://raw.githubusercontent.com/github/gh-aw/main/.github/aw/agentic-chat.md) with any conversational AI to create clear, actionable task descriptions. Copy agentic-chat instructions
Copy the instructions, paste into your AI chat, then describe your workflow goal. The assistant asks clarifying questions and generates a structured task description (wrapped in 5 backticks) ready to use in your workflow. It focuses on what needs to be done rather than how, making it ideal for creating specifications that coding agents can execute.
### Dictation
[Section titled “Dictation”](#dictation)
When creating agentic workflows using speech-to-text, use the [dictation instructions prompt](https://raw.githubusercontent.com/github/gh-aw/main/skills/dictation/SKILL.md) to correct terminology mismatches and formatting issues. Copy dictation instructions
This prompt corrects terminology (e.g., “ghaw” → “gh-aw”, “work flow” → “workflow”), transforms casual speech into imperative task descriptions, removes filler words, and adds implicit context. Load it into your AI assistant before or after dictating.
# Consuming Audit Reports with Agents
> How to feed structured audit output into agentic workflows for automated triage, trend analysis, and remediation.
When running locally, all three audit commands accept `--json` to write structured output to stdout. Pipe through `jq` to extract the fields a model needs.
| Command | Use case |
| ---------------------------------------- | --------------------------------------------------------- |
| `gh aw audit --json` | Single run — `key_findings`, `recommendations`, `metrics` |
| `gh aw logs [workflow] --last 10 --json` | Trend analysis — `per_run_breakdown`, `domain_inventory` |
| `gh aw audit diff --json` | Before/after — `run_metrics_diff`, `firewall_diff` |
Inside GitHub Actions workflows, agents access these commands through the `agentic-workflows` MCP tool rather than calling the CLI directly.
## Posting findings as a PR comment
[Section titled “Posting findings as a PR comment”](#posting-findings-as-a-pr-comment)
```aw
---
description: Post audit findings as a PR comment after each agent run
on:
workflow_run:
workflows: ['my-workflow']
types: [completed]
engine: copilot
tools:
github:
toolsets: [pull_requests]
agentic-workflows:
permissions:
contents: read
actions: read
pull-requests: write
---
# Summarize Audit Findings
Use the `agentic-workflows` MCP tool `audit` with run ID ${{ github.event.workflow_run.id }}, identify the pull request that triggered it, and post a comment summarizing key findings and blocked domains. Highlight issues with severity `high` or `critical`. If there are no findings, post a brief "no issues found" comment.
```
## Detecting regressions with diff
[Section titled “Detecting regressions with diff”](#detecting-regressions-with-diff)
```aw
---
description: Detect regressions between two workflow runs
on:
workflow_dispatch:
inputs:
base_run_id:
description: 'Baseline run ID'
required: true
current_run_id:
description: 'Current run ID to compare'
required: true
engine: copilot
tools:
github:
toolsets: [issues]
agentic-workflows:
permissions:
contents: read
actions: read
issues: write
---
# Regression Detection
Use the `agentic-workflows` MCP tool `audit diff` with base run ID ${{ inputs.base_run_id }} and current run ID ${{ inputs.current_run_id }}. Check for new blocked domains, increased MCP error rates, cost increase > 20%, or token usage increase > 50%. If regressions are found, open a GitHub issue with a table from `run_metrics_diff`, affected domains from `firewall_diff`, and affected MCP tools from `mcp_tools_diff`.
```
## Filing issues from audit findings
[Section titled “Filing issues from audit findings”](#filing-issues-from-audit-findings)
```aw
---
description: File GitHub issues for high-severity audit findings
on:
workflow_run:
workflows: ['my-workflow']
types: [completed]
engine: copilot
tools:
github:
toolsets: [issues]
agentic-workflows:
permissions:
contents: read
actions: read
issues: write
---
# Auto-File Issues for Critical Findings
Use the `agentic-workflows` MCP tool `audit` with run ID ${{ github.event.workflow_run.id }}. Filter `key_findings` for severity `high` or `critical`. For each finding without a matching open issue, create one with the finding title, description, impact, and recommendations, labelled `audit-finding`. If no critical findings, call the `noop` safe output tool.
```
## Weekly audit monitoring agent
[Section titled “Weekly audit monitoring agent”](#weekly-audit-monitoring-agent)
```aw
---
description: Weekly audit digest with trend analysis
on:
schedule: weekly
engine: copilot
tools:
github:
toolsets: [discussions]
agentic-workflows:
cache-memory:
key: audit-monitoring-trends
permissions:
contents: read
actions: read
discussions: write
---
# Weekly Audit Monitoring Digest
1. Use the `agentic-workflows` MCP tool `logs` with parameters `workflow: my-workflow, last: 10` and read `/tmp/gh-aw/cache-memory/audit-trends.json` as the previous baseline.
2. Detect: cost spikes (`cost_spike: true` in `per_run_breakdown`), new denied domains in `domain_inventory`, MCP servers with `error_rate > 0.10` or `unreliable: true`, and week-over-week changes in `error_trend.runs_with_errors`.
3. Create a GitHub discussion "Audit Digest — [YYYY-MM-DD]" with an executive summary, anomalies table, and MCP health table.
4. Update `/tmp/gh-aw/cache-memory/audit-trends.json` with rolling averages (cost, tokens, error count, deny rate), keeping only the last 30 days.
```
## Tips
[Section titled “Tips”](#tips)
Top-level fields (`key_findings`, `recommendations`, `metrics`, `firewall_analysis`, `mcp_tool_usage`) are stable; nested sub-fields may be extended but are not removed without deprecation. Add `--parse` to populate `behavior_fingerprint` and `agentic_assessments`. Cross-run JSON can be large — extract only the slices your model needs.
# Deterministic & Agentic Patterns
> Learn how to combine deterministic computation steps with agentic reasoning in GitHub Agentic Workflows for powerful hybrid automation.
GitHub Agentic Workflows combine deterministic computation with AI reasoning, enabling data preprocessing, custom trigger filtering, and post-processing patterns.
## When to Use
[Section titled “When to Use”](#when-to-use)
Combine deterministic steps with AI agents to precompute data, filter triggers, preprocess inputs, post-process outputs, or build multi-stage computation and reasoning pipelines.
## Architecture
[Section titled “Architecture”](#architecture)
Define deterministic jobs in frontmatter alongside agentic execution:
```text
┌────────────────────────┐
│ Deterministic Jobs │
│ - Data fetching │
│ - Preprocessing │
└───────────┬────────────┘
│ artifacts/outputs
▼
┌────────────────────────┐
│ Agent Job (AI) │
│ - Reasons & decides │
└───────────┬────────────┘
│ safe outputs
▼
┌────────────────────────┐
│ Safe Output Jobs │
│ - GitHub API calls │
└────────────────────────┘
```
## Precomputation Example
[Section titled “Precomputation Example”](#precomputation-example)
.github/workflows/release-highlights.md
```yaml
---
on:
push:
tags: ['v*.*.*']
engine: copilot
safe-outputs:
update-release:
steps:
- run: |
gh release view "${GITHUB_REF#refs/tags/}" --json name,tagName,body > /tmp/gh-aw/agent/release.json
gh pr list --state merged --limit 100 --json number,title,labels > /tmp/gh-aw/agent/prs.json
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
---
# Release Highlights Generator
Generate release highlights for `${GITHUB_REF#refs/tags/}`. Analyze PRs in `/tmp/gh-aw/agent/prs.json`, categorize changes, and use update-release to prepend highlights to the release notes.
```
Files in `/tmp/gh-aw/agent/` are automatically uploaded as artifacts and available to the AI agent.
## Multi-Job Pattern
[Section titled “Multi-Job Pattern”](#multi-job-pattern)
.github/workflows/static-analysis.md
```yaml
---
on:
schedule: daily
engine: claude
safe-outputs:
create-discussion:
jobs:
run-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: ./gh-aw compile --zizmor --poutine > /tmp/gh-aw/agent/analysis.txt
steps:
- uses: actions/download-artifact@v6
with:
name: analysis-results
path: /tmp/gh-aw/
---
# Static Analysis Report
Parse findings in `/tmp/gh-aw/agent/analysis.txt`, cluster by severity, and create a discussion with fix suggestions.
```
Pass data between jobs via artifacts, job outputs, or environment variables.
## Custom Trigger Filtering
[Section titled “Custom Trigger Filtering”](#custom-trigger-filtering)
### Inline Steps (`on.steps:`) — Preferred
[Section titled “Inline Steps (on.steps:) — Preferred”](#inline-steps-onsteps--preferred)
Inject deterministic steps directly into the pre-activation job using `on.steps:`. This saves **one workflow job** compared to the multi-job pattern and is the recommended approach for lightweight filtering:
.github/workflows/smart-responder.md
```yaml
---
on:
issues:
types: [opened]
steps:
- id: check
env:
LABELS: ${{ toJSON(github.event.issue.labels.*.name) }}
run: echo "$LABELS" | grep -q '"bug"'
# exits 0 (outcome: success) if the label is found, 1 (outcome: failure) if not
engine: copilot
safe-outputs:
add-comment:
if: needs.pre_activation.outputs.check_result == 'success'
---
# Bug Issue Responder
Triage bug report: "${{ github.event.issue.title }}" and add-comment with a summary of the next steps.
```
Each step with an `id` gets an auto-wired output `_result` set to `${{ steps..outcome }}` — `success` when the step’s exit code is 0, `failure` when non-zero. Gate the workflow by checking `needs.pre_activation.outputs._result == 'success'`.
To pass an explicit value rather than relying on exit codes, set a step output and re-expose it via `jobs.pre-activation.outputs`:
```yaml
jobs:
pre-activation:
outputs:
has_bug_label: ${{ steps.check.outputs.has_bug_label }}
if: needs.pre_activation.outputs.has_bug_label == 'true'
```
When `on.steps:` need GitHub API access, use `on.permissions:` to grant the required scopes to the pre-activation job:
```yaml
on:
schedule: every 30m
permissions:
issues: read
steps:
- id: search
uses: actions/github-script@v8
with:
script: |
const open = await github.rest.issues.listForRepo({ ...context.repo, state: 'open' });
core.setOutput('has_work', open.data.length > 0 ? 'true' : 'false');
jobs:
pre-activation:
outputs:
has_work: ${{ steps.search.outputs.has_work }}
if: needs.pre_activation.outputs.has_work == 'true'
```
See [Pre-Activation Steps](/gh-aw/reference/triggers/#pre-activation-steps-onsteps) and [Pre-Activation Permissions](/gh-aw/reference/triggers/#pre-activation-permissions-onpermissions) for full documentation.
### Multi-Job Pattern — For Complex Cases
[Section titled “Multi-Job Pattern — For Complex Cases”](#multi-job-pattern--for-complex-cases)
Use a separate `jobs:` entry when filtering requires heavy tooling (checkout, compiled tools, multiple runners):
.github/workflows/smart-responder.md
```yaml
---
on:
issues:
types: [opened]
engine: copilot
safe-outputs:
add-comment:
jobs:
filter:
runs-on: ubuntu-latest
outputs:
should-run: ${{ steps.check.outputs.result }}
steps:
- id: check
env:
LABELS: ${{ toJSON(github.event.issue.labels.*.name) }}
run: |
if echo "$LABELS" | grep -q '"bug"'; then
echo "result=true" >> "$GITHUB_OUTPUT"
else
echo "result=false" >> "$GITHUB_OUTPUT"
fi
if: needs.filter.outputs.should-run == 'true'
---
# Bug Issue Responder
Triage bug report: "${{ github.event.issue.title }}" and add-comment with a summary of the next steps.
```
The compiler automatically adds the filter job as a dependency of the activation job, so when the condition is false the workflow run is **skipped** (not failed), keeping the Actions tab clean.
### Simple Context Conditions
[Section titled “Simple Context Conditions”](#simple-context-conditions)
For conditions that can be expressed directly with GitHub Actions context, use `if:` without a custom job:
```yaml
---
on:
pull_request:
types: [opened, synchronize]
engine: copilot
if: github.event.pull_request.draft == false
---
```
### Query-Based Filtering
[Section titled “Query-Based Filtering”](#query-based-filtering)
For conditions based on GitHub search results, use [`skip-if-match:`](/gh-aw/reference/triggers/#skip-if-match-condition-skip-if-match) or [`skip-if-no-match:`](/gh-aw/reference/triggers/#skip-if-no-match-condition-skip-if-no-match) in the `on:` section — these accept standard [GitHub search query syntax](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests) and are evaluated in the pre-activation job, producing the same skipped-not-failed behaviour:
```yaml
---
on:
issues:
types: [opened]
# Skip if a duplicate issue already exists (GitHub search query syntax)
skip-if-match: 'is:issue is:open label:duplicate'
engine: copilot
---
```
## Post-Processing Pattern
[Section titled “Post-Processing Pattern”](#post-processing-pattern)
.github/workflows/code-review\.md
```yaml
---
on:
pull_request:
types: [opened]
engine: copilot
safe-outputs:
jobs:
format-and-notify:
description: "Format and post review"
runs-on: ubuntu-latest
inputs:
summary: {required: true, type: string}
steps:
- ...
---
# Code Review Agent
Review the pull request and use format-and-notify to post your summary.
```
## Importing Shared Instructions
[Section titled “Importing Shared Instructions”](#importing-shared-instructions)
Define reusable guidance in shared files and import them:
.github/workflows/analysis.md
```yaml
---
on:
schedule: daily
engine: copilot
imports:
- shared/reporting.md
safe-outputs:
create-discussion:
---
# Daily Analysis
Follow the report formatting guidelines from shared/reporting.md.
```
## Agent Data Directory
[Section titled “Agent Data Directory”](#agent-data-directory)
Use `/tmp/gh-aw/agent/` to share data with AI agents. Files here are automatically uploaded as artifacts and accessible to the agent:
```yaml
steps:
- run: |
gh api repos/${{ github.repository }}/issues > /tmp/gh-aw/agent/issues.json
gh api repos/${{ github.repository }}/pulls > /tmp/gh-aw/agent/pulls.json
```
Reference in prompts: “Analyze issues in `/tmp/gh-aw/agent/issues.json` and PRs in `/tmp/gh-aw/agent/pulls.json`.”
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Pre-Activation Steps](/gh-aw/reference/triggers/#pre-activation-steps-onsteps) - Inline step injection into the pre-activation job
* [Pre-Activation Permissions](/gh-aw/reference/triggers/#pre-activation-permissions-onpermissions) - Grant additional scopes for `on.steps:` API calls
* [Custom Safe Outputs](/gh-aw/reference/custom-safe-outputs/) - Custom post-processing jobs
* [Frontmatter Reference](/gh-aw/reference/frontmatter/) - Configuration options
* [Compilation Process](/gh-aw/reference/compilation-process/) - How jobs are orchestrated
* [Imports](/gh-aw/reference/imports/) - Sharing configurations across workflows
* [Templating](/gh-aw/reference/templating/) - Using GitHub Actions expressions
# Editing Workflows
> Learn when you can edit workflows directly on GitHub.com versus when recompilation is required, and best practices for iterating on agentic workflows.
Agentic workflows consist of two parts: the **YAML frontmatter** (compiled into the lock file; changes require recompilation) and the **markdown body** (loaded at runtime; changes take effect immediately). This lets you iterate on AI instructions without recompilation while maintaining strict control over security-sensitive configuration.
See [Creating Agentic Workflows](/gh-aw/setup/creating-workflows/) for guidance on creating workflows with AI assistance.
## Editing Without Recompilation
[Section titled “Editing Without Recompilation”](#editing-without-recompilation)
Tip
You can edit the **markdown body** directly on GitHub.com or in any editor without recompiling. Changes take effect on the next workflow run.
### What You Can Edit
[Section titled “What You Can Edit”](#what-you-can-edit)
The markdown body is loaded at runtime from the original `.md` file. You can freely edit task instructions, output templates, conditional logic (“If X, then do Y”), context explanations, and examples.
### Example: Adding Instructions
[Section titled “Example: Adding Instructions”](#example-adding-instructions)
**Before** (in `.github/workflows/issue-triage.md`):
```markdown
---
on:
issues:
types: [opened]
---
# Issue Triage
Read issue #${{ github.event.issue.number }} and add appropriate labels.
```
**After** (edited on GitHub.com):
```markdown
---
on:
issues:
types: [opened]
---
# Issue Triage
Read issue #${{ github.event.issue.number }} and add appropriate labels.
## Labeling Criteria
Apply these labels based on content:
- `bug`: Issues describing incorrect behavior with reproduction steps
- `enhancement`: Feature requests or improvements
- `question`: Help requests or clarifications needed
- `documentation`: Documentation updates or corrections
For priority, consider:
- `high-priority`: Security issues, critical bugs, blocking issues
- `medium-priority`: Important features, non-critical bugs
- `low-priority`: Nice-to-have improvements, minor enhancements
```
✓ This change takes effect immediately without recompilation.
## Editing With Recompilation Required
[Section titled “Editing With Recompilation Required”](#editing-with-recompilation-required)
Caution
Changes to the **YAML frontmatter** always require recompilation. These are security-sensitive configuration options.
### What Requires Recompilation
[Section titled “What Requires Recompilation”](#what-requires-recompilation)
Any changes to the frontmatter configuration between `---` markers:
* **Triggers** (`on:`): Event types, filters, schedules
* **Permissions** (`permissions:`): Repository access levels
* **Tools** (`tools:`): Tool configurations, MCP servers, allowed tools
* **Network** (`network:`): Allowed domains, firewall rules
* **Safe outputs** (`safe-outputs:`): Output types, threat detection
* **MCP Scripts** (`mcp-scripts:`): Custom MCP tools defined inline
* **Runtimes** (`runtimes:`): Node, Python, Go version overrides
* **Imports** (`imports:`): Shared configuration files
* **Custom jobs** (`jobs:`): Additional workflow jobs
* **Engine** (`engine:`): AI engine selection (copilot, claude, codex)
* **Timeout** (`timeout-minutes:`): Maximum execution time
* **Roles** (`roles:`): Permission requirements for actors
### Example: Adding a Tool (Requires Recompilation)
[Section titled “Example: Adding a Tool (Requires Recompilation)”](#example-adding-a-tool-requires-recompilation)
**Before**:
```yaml
---
on:
issues:
types: [opened]
---
```
**After** (must recompile):
```yaml
---
on:
issues:
types: [opened]
tools:
github:
toolsets: [issues]
---
```
! Run `gh aw compile my-workflow` before committing this change.
## Expressions and Environment Variables
[Section titled “Expressions and Environment Variables”](#expressions-and-environment-variables)
### Allowed Expressions
[Section titled “Allowed Expressions”](#allowed-expressions)
You can safely use these expressions in markdown without recompilation:
```markdown
# Process Issue
Read issue #${{ github.event.issue.number }} in repository ${{ github.repository }}.
Issue title: "${{ github.event.issue.title }}"
Use sanitized content: "${{ steps.sanitized.outputs.text }}"
Actor: ${{ github.actor }}
Repository: ${{ github.repository }}
```
These expressions are evaluated at runtime and validated for security. See [Templating](/gh-aw/reference/templating/) for the complete list of allowed expressions.
### Prohibited Expressions
[Section titled “Prohibited Expressions”](#prohibited-expressions)
Arbitrary expressions are blocked for security. This will fail at runtime:
```markdown
# ✗ WRONG - Will be rejected
Run this command: ${{ github.event.comment.body }}
```
Use `steps.sanitized.outputs.text` for sanitized user input instead.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Workflow Structure](/gh-aw/reference/workflow-structure/) - Overall file organization
* [Frontmatter Reference](/gh-aw/reference/frontmatter/) - All configuration options
* [Markdown Reference](/gh-aw/reference/markdown/) - Writing effective instructions
* [Compilation Process](/gh-aw/reference/compilation-process/) - How compilation works
* [Templating](/gh-aw/reference/templating/) - Expression syntax and substitution
# Ephemerals
> Features for automatically expiring workflow resources and reducing noise in your repositories
GitHub Agentic Workflows includes several features designed to automatically expire resources and reduce noise in your repositories. These “ephemeral” features help keep your repository clean by automatically cleaning up temporary issues, discussions, pull requests, and workflow runs after they’ve served their purpose.
## Why Use Ephemerals?
[Section titled “Why Use Ephemerals?”](#why-use-ephemerals)
Ephemerals control costs by stopping scheduled workflows at deadlines, reduce clutter by auto-expiring issues and discussions, keep status timelines clean by hiding older comments, and isolate automation via the SideRepoOps pattern.
## Expiration Features
[Section titled “Expiration Features”](#expiration-features)
### Workflow Stop-After
[Section titled “Workflow Stop-After”](#workflow-stop-after)
Automatically disable workflow triggering after a deadline to control costs and prevent indefinite execution.
```yaml
on: weekly on monday
stop-after: "+25h" # 25 hours from compilation time
```
**Accepted formats**:
* **Absolute dates**: `YYYY-MM-DD`, `MM/DD/YYYY`, `DD/MM/YYYY`, `January 2 2006`, `1st June 2025`, ISO 8601
* **Relative deltas**: `+7d`, `+25h`, `+1d12h30m` (calculated from compilation time)
The minimum granularity is hours - minute-only units (e.g., `+30m`) are not allowed. Recompiling the workflow resets the stop time.
At the deadline, new runs are prevented while existing runs complete. The stop time persists through recompilation; use `gh aw compile --refresh-stop-time` to reset it. Common uses: trial periods, experimental features, orchestrated initiatives, and cost-controlled schedules.
See [Triggers Reference](/gh-aw/reference/triggers/#stop-after-configuration-stop-after) for complete documentation.
### Safe Output Expiration
[Section titled “Safe Output Expiration”](#safe-output-expiration)
Auto-close issues, discussions, and pull requests after a specified time period. This generates a maintenance workflow that runs automatically at appropriate intervals.
#### Issue Expiration
[Section titled “Issue Expiration”](#issue-expiration)
```yaml
safe-outputs:
create-issue:
expires: 7 # Auto-close after 7 days
labels: [automation, agentic]
```
#### Discussion Expiration
[Section titled “Discussion Expiration”](#discussion-expiration)
```yaml
safe-outputs:
create-discussion:
expires: 3 # Auto-close after 3 days as "OUTDATED"
category: "general"
```
#### Pull Request Expiration
[Section titled “Pull Request Expiration”](#pull-request-expiration)
```yaml
safe-outputs:
create-pull-request:
expires: 14 # Auto-close after 14 days (same-repo only)
draft: true
```
**Supported formats**:
* **Integer**: Number of days (e.g., `7` = 7 days)
* **Relative time**: `2h`, `7d`, `2w`, `1m`, `1y`
Hours less than 24 are treated as 1 day minimum for expiration calculation.
**Maintenance workflow frequency**: The generated `agentics-maintenance.yml` workflow runs at the minimum required frequency based on the shortest expiration time across all workflows:
| Shortest Expiration | Maintenance Frequency |
| ------------------- | --------------------- |
| 1 day or less | Every 2 hours |
| 2 days | Every 6 hours |
| 3-4 days | Every 12 hours |
| 5+ days | Daily |
**Expiration markers**: The system adds a visible checkbox line with an XML comment to the body of created items:
```markdown
- [x] expires on Jan 14, 2026, 3:30 PM UTC
```
The maintenance workflow searches for items with this expiration format (checked checkbox with the XML comment) and automatically closes them with appropriate comments and resolution reasons. Users can uncheck the checkbox to prevent automatic expiration.
See [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) for complete documentation.
### Manual Maintenance Operations
[Section titled “Manual Maintenance Operations”](#manual-maintenance-operations)
The generated `agentics-maintenance.yml` workflow also supports manual bulk operations via `workflow_dispatch`. Admin or maintainer users can trigger it from the GitHub Actions UI or the CLI. The operation is restricted to admin and maintainer roles and is not available on forks.
Available operations:
| Operation | Description |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `safe_outputs` | Auto-close expired issues, discussions, and pull requests |
| `disable` | Disable all agentic workflows in the repository |
| `enable` | Re-enable all agentic workflows in the repository |
| `create_labels` | Create any repository labels referenced in safe-outputs that do not yet exist. Runs `gh aw compile --json --no-emit`, collects all unique label names across workflows, and creates missing ones with deterministic pastel colors. |
The `create_labels` operation requires `issues: write` permission and runs in a dedicated job. It is useful when adding new workflows that reference labels that have not yet been created in the repository.
### Close Older Issues
[Section titled “Close Older Issues”](#close-older-issues)
Automatically close older issues with the same workflow-id marker when creating new ones. This keeps your issues focused on the latest information.
```yaml
safe-outputs:
create-issue:
close-older-issues: true # Close previous reports
```
When a new issue is created, up to 10 older issues with the same workflow-id marker are closed as “not planned” with a comment linking to the new issue. Requires `GH_AW_WORKFLOW_ID` to be set and appropriate repository permissions. Ideal for weekly reports and recurring analyses where only the latest result matters.
## Noise Reduction Features
[Section titled “Noise Reduction Features”](#noise-reduction-features)
### Hide Older Comments
[Section titled “Hide Older Comments”](#hide-older-comments)
Minimize previous comments from the same workflow before posting new ones. Useful for status update workflows where only the latest information matters.
```yaml
safe-outputs:
add-comment:
hide-older-comments: true
allowed-reasons: [outdated] # Optional: restrict hiding reasons
```
Before posting, the system finds and minimizes previous comments from the same workflow (identified by `GITHUB_WORKFLOW`). Comments are hidden, not deleted. Use `allowed-reasons` to restrict which minimization reason is applied: `spam`, `abuse`, `off_topic`, `outdated` (default), or `resolved`. Useful for status updates, build notifications, and health checks where only the latest result matters.
See [Safe Outputs Reference](/gh-aw/reference/safe-outputs/#hide-older-comments) for complete documentation.
### SideRepoOps Pattern
[Section titled “SideRepoOps Pattern”](#siderepoops-pattern)
Run agentic workflows from a separate “side” repository that targets your main codebase. This isolates AI-generated issues, comments, and workflow runs from your main repository, keeping automation infrastructure separate from production code.
See [SideRepoOps](/gh-aw/patterns/side-repo-ops/) for complete setup and usage documentation.
### Text Sanitization
[Section titled “Text Sanitization”](#text-sanitization)
Control which GitHub repository references (`#123`, `owner/repo#456`) are allowed in workflow output text. When configured, references to unlisted repositories are escaped with backticks to prevent GitHub from creating timeline items.
```yaml
safe-outputs:
allowed-github-references: [] # Escape all references
create-issue:
target-repo: "my-org/main-repo"
```
See [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) for complete documentation.
### Use Discussions Instead of Issues
[Section titled “Use Discussions Instead of Issues”](#use-discussions-instead-of-issues)
For ephemeral content, use GitHub discussions instead of issues. Discussions are better suited for temporary content, questions, and updates that don’t require long-term tracking.
```yaml
safe-outputs:
create-discussion:
category: "general"
expires: 7 # Auto-close after 7 days
close-older-discussions: true
```
**Why discussions for ephemeral content?**
| Feature | Issues | Discussions |
| ------------------ | ----------------------------------- | ----------------------------------- |
| **Purpose** | Long-term tracking | Conversations & updates |
| **Searchability** | High priority in search | Lower search weight |
| **Project boards** | Native integration | Limited integration |
| **Auto-close** | Supported with maintenance workflow | Supported with maintenance workflow |
| **Timeline noise** | Can clutter project tracking | Separate from development work |
Ephemeral discussions work well for weekly reports, periodic analyses, temporary announcements, time-bound Q\&A, and community updates.
**Combining features**:
```yaml
safe-outputs:
create-discussion:
category: "Status Updates"
expires: 14 # Close after 2 weeks
close-older-discussions: true # Replace previous reports
```
This keeps the “Status Updates” category clean: previous reports are closed on creation and all discussions auto-close after 14 days.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Triggers Reference](/gh-aw/reference/triggers/) - Complete trigger configuration including `stop-after`
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - All safe output types and expiration options
* [SideRepoOps](/gh-aw/patterns/side-repo-ops/) - Complete setup for side repository operations
* [Authentication](/gh-aw/reference/auth/) - Authentication and security considerations
* [Orchestration](/gh-aw/patterns/orchestration/) - Orchestrating multi-workflow initiatives
# Getting Started with MCP
> Learn how to integrate Model Context Protocol (MCP) servers with your agentic workflows to connect AI agents to GitHub, databases, and external services.
This guide walks you through integrating [Model Context Protocol](/gh-aw/reference/glossary/#mcp-model-context-protocol) (MCP) servers with GitHub Agentic Workflows, from your first configuration to advanced patterns.
## What is MCP?
[Section titled “What is MCP?”](#what-is-mcp)
[Model Context Protocol](/gh-aw/reference/glossary/#mcp-model-context-protocol) (MCP) is a standardized protocol that enables agents to connect to external tools, databases, and APIs. [MCP servers](/gh-aw/reference/glossary/#mcp-server) act as specialized adapters, giving agents access to GitHub, web search, databases, and third-party services like Notion, Slack, and Datadog.
## Quick Start
[Section titled “Quick Start”](#quick-start)
Get your first MCP integration running in under 5 minutes.
### Step 1: Add GitHub Tools
[Section titled “Step 1: Add GitHub Tools”](#step-1-add-github-tools)
Create a workflow file at `.github/workflows/my-workflow.md`:
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
issues: read
tools:
github:
toolsets: [default]
---
# Issue Analysis Agent
Analyze the issue and provide a summary of similar existing issues.
```
The `toolsets: [default]` configuration gives your agentic workflow access to repository, issue, and pull request tools.
### Step 2: Compile and Test
[Section titled “Step 2: Compile and Test”](#step-2-compile-and-test)
Compile the workflow to generate the GitHub Actions YAML:
```bash
gh aw compile my-workflow
```
Verify the MCP configuration:
```bash
gh aw mcp inspect my-workflow
```
You now have a working MCP integration. The agent can read issues, search repositories, and access pull request information.
## Configuration Patterns
[Section titled “Configuration Patterns”](#configuration-patterns)
### Toolsets Pattern (Recommended)
[Section titled “Toolsets Pattern (Recommended)”](#toolsets-pattern-recommended)
Use `toolsets:` to enable groups of related GitHub tools:
```yaml
tools:
github:
toolsets: [default] # Expands to: context, repos, issues, pull_requests (action-friendly)
```
Toolsets remain stable across MCP server versions, while individual tool names may change. See [Available Toolsets](#available-toolsets) for the full list.
### Allowed Pattern (Custom MCP Servers)
[Section titled “Allowed Pattern (Custom MCP Servers)”](#allowed-pattern-custom-mcp-servers)
Use `allowed:` when configuring custom (non-GitHub) MCP servers:
```yaml
mcp-servers:
notion:
container: "mcp/notion"
allowed: ["search_pages", "get_page"]
```
## GitHub MCP Server
[Section titled “GitHub MCP Server”](#github-mcp-server)
The GitHub MCP server is built into agentic workflows and provides comprehensive access to GitHub’s API.
### Available Toolsets
[Section titled “Available Toolsets”](#available-toolsets)
| Toolset | Description | Tools |
| --------------- | --------------------------- | ----------------------------------------------------- |
| `context` | User and team information | `get_teams`, `get_team_members` |
| `repos` | Repository operations | `get_repository`, `get_file_contents`, `list_commits` |
| `issues` | Issue management | `list_issues`, `create_issue`, `update_issue` |
| `pull_requests` | PR operations | `list_pull_requests`, `create_pull_request` |
| `actions` | Workflow runs and artifacts | `list_workflows`, `list_workflow_runs` |
| `discussions` | GitHub Discussions | `list_discussions`, `create_discussion` |
| `code_security` | Security alerts | `list_code_scanning_alerts` |
| `users` | User profiles | `get_me`, `get_user`, `list_users` |
The `default` toolset includes: `context`, `repos`, `issues`, `pull_requests`. When used in workflows, `[default]` expands to action-friendly toolsets that work with GitHub Actions tokens. Note: The `users` toolset is not included by default as GitHub Actions tokens do not support user operations.
### Operating Modes
[Section titled “Operating Modes”](#operating-modes)
Remote mode (`mode: remote`) connects to a hosted server for faster startup with no Docker required. Local mode (`mode: local`) runs in Docker, enabling version pinning for offline or restricted environments. See [Remote vs Local Mode](/gh-aw/reference/github-tools/#github-tools-remote-mode).
The GitHub MCP server always operates read-only. Write operations are handled through [safe outputs](/gh-aw/reference/safe-outputs/), which run in a separate permission-controlled job.
## MCP Registry
[Section titled “MCP Registry”](#mcp-registry)
The GitHub MCP registry provides a centralized catalog of MCP servers.
### Adding Servers
[Section titled “Adding Servers”](#adding-servers)
```bash
# Browse available MCP servers
gh aw mcp add
# Add a specific server
gh aw mcp add my-workflow makenotion/notion-mcp-server
# Add with custom tool ID
gh aw mcp add my-workflow makenotion/notion-mcp-server --tool-id my-notion
```
The command searches the registry, adds the server configuration, and recompiles the workflow.
Reference registry servers directly in your workflow:
```yaml
mcp-servers:
markitdown:
registry: https://api.mcp.github.com/v0/servers/microsoft/markitdown
container: "ghcr.io/microsoft/markitdown"
allowed: ["*"]
```
The `registry` field provides metadata for tooling while the `container` or `command` fields specify how to run the server.
### Using a Custom Registry
[Section titled “Using a Custom Registry”](#using-a-custom-registry)
For enterprise or private registries:
```bash
gh aw mcp add my-workflow server-name --registry https://custom.registry.com/v1
```
## Custom MCP Servers
[Section titled “Custom MCP Servers”](#custom-mcp-servers)
Configure third-party MCP servers using commands, Docker containers, or HTTP endpoints:
```yaml
mcp-servers:
# Command-based (stdio)
markitdown:
command: "npx"
args: ["-y", "markitdown-mcp"]
allowed: ["*"]
# Docker container
ast-grep:
container: "mcp/ast-grep:latest"
allowed: ["*"]
# HTTP endpoint with auth
slack:
url: "https://api.slack.com/mcp"
env:
SLACK_BOT_TOKEN: "${{ secrets.SLACK_BOT_TOKEN }}"
network:
allowed: ["api.slack.com"] # Optional egress restrictions
allowed: ["send_message", "get_channel_history"]
```
## Practical Examples
[Section titled “Practical Examples”](#practical-examples)
### Example 1: Basic Issue Triage
[Section titled “Example 1: Basic Issue Triage”](#example-1-basic-issue-triage)
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
issues: read
tools:
github:
toolsets: [default]
safe-outputs:
add-comment:
---
# Issue Triage Agent
Analyze issue #${{ github.event.issue.number }} and add a comment with category, related issues, and suggested labels.
```
### Example 2: Multi-Service Integration
[Section titled “Example 2: Multi-Service Integration”](#example-2-multi-service-integration)
```aw
---
on: weekly on sunday
permissions:
contents: read
security-events: read
discussions: write
tools:
github:
toolsets: [default, code_security, discussions]
safe-outputs:
create-discussion:
category: "Security"
title-prefix: "[security-scan] "
---
# Security Audit Agent
Review code scanning alerts and create weekly security discussions with findings.
```
## Debugging MCP Configurations
[Section titled “Debugging MCP Configurations”](#debugging-mcp-configurations)
Inspect configured servers and available tools:
```bash
# View all MCP servers
gh aw mcp inspect my-workflow
# Get detailed server information
gh aw mcp inspect my-workflow --server github --verbose
# List available tools
gh aw mcp list-tools github my-workflow
# Validate configuration
gh aw compile my-workflow --validate --strict
```
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
**Tool not found:** Run `gh aw mcp inspect my-workflow` to verify available tools. Ensure the correct toolset is enabled or that tool names in `allowed:` match exactly.
**Authentication errors:** Verify the secret exists in repository settings and has required scopes.
**Connection failures:** Check URL syntax for HTTP servers, network configuration for containers, and verify Docker images exist.
**Validation errors:** Check YAML syntax, ensure `toolsets:` uses array format (`[default]` not `default`), and verify `allowed:` is an array.
## Next Steps
[Section titled “Next Steps”](#next-steps)
* [Using MCPs](/gh-aw/guides/mcps/) - Complete MCP configuration reference
* [Tools Reference](/gh-aw/reference/tools/) - All available tools and options
* [Security Guide](/gh-aw/introduction/architecture/) - MCP security best practices
* [CLI Commands](/gh-aw/setup/cli/) - Full CLI documentation including `mcp` commands
* [Imports](/gh-aw/reference/imports/) - Shared MCP configurations in `.github/workflows/shared/mcp/`
# GitHub Actions Primer
> A comprehensive guide to understanding GitHub Actions, from its history and core concepts to testing workflows and comparing with agentic workflows
**GitHub Actions** is GitHub’s integrated automation platform for building, testing, and deploying code from your repository. It enables automated workflows triggered by repository events, schedules, or manual triggers — all defined in YAML files in your repository. Agentic workflows compile from markdown files into secure GitHub Actions YAML, inheriting these core concepts while adding AI-driven decision-making and enhanced security.
## Core Concepts
[Section titled “Core Concepts”](#core-concepts)
### YAML Workflows
[Section titled “YAML Workflows”](#yaml-workflows)
A **YAML workflow** is an automated process defined in `.github/workflows/`. Each workflow consists of jobs that execute when triggered by events. Workflows must be stored on the **main** or default branch to be active and are versioned alongside your code.
**Example** (`.github/workflows/ci.yml`):
```yaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run tests
run: npm test
```
### Jobs
[Section titled “Jobs”](#jobs)
A **job** is a set of steps that execute on the same runner (virtual machine). Jobs run in parallel by default but can depend on each other with `needs:`. Each job runs in a fresh VM, and results are shared between jobs using artifacts. Default timeout is 360 minutes for standard GitHub Actions jobs; the agent execution step in agentic workflows defaults to 20 minutes.
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: npm run build
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: npm test
```
### Steps
[Section titled “Steps”](#steps)
**Steps** are individual tasks within a job, running sequentially. They can execute shell commands or use pre-built actions from the GitHub Marketplace. Steps share the same filesystem and environment; a failed step stops the job by default.
```yaml
steps:
# Action step - uses a pre-built action
- uses: actions/checkout@v6
# Run step - executes a shell command
- name: Install dependencies
run: npm install
# Action with inputs
- uses: actions/setup-node@v4
with:
node-version: '20'
```
## Security Model
[Section titled “Security Model”](#security-model)
### Workflow Storage and Execution
[Section titled “Workflow Storage and Execution”](#workflow-storage-and-execution)
Workflows must be stored in `.github/workflows/` on the **default branch** to be active and trusted. This ensures changes undergo code review, maintains an audit trail, prevents privilege escalation from feature branches, and treats the default branch as a trust boundary.
```yaml
# Workflows on main branch can access secrets
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- run: echo "Has access to production secrets"
```
### Permission Model
[Section titled “Permission Model”](#permission-model)
GitHub Actions uses the **principle of least privilege** with explicit permission declarations. Fork pull requests are read-only by default; all required permissions should be explicitly declared.
```yaml
permissions:
contents: read # Read repository contents
issues: write # Create/modify issues
pull-requests: write # Create/modify PRs
jobs:
example:
runs-on: ubuntu-latest
steps:
- run: echo "Job has specified permissions only"
```
With GItHub Agentic Workflows, **write permissions are not used explicitly**. Instead much more restricted capabilities to write to GitHub are delared through **safe outputs**, which validate, constrain and sanitize all GitHub API interactions.
### Secret Management
[Section titled “Secret Management”](#secret-management)
**Secrets** are encrypted environment variables stored at the repository, organization, or environment level. They are never exposed in logs, only accessible to workflows on default/protected branches, and scoped by environment for additional protection.
```yaml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to production
env:
API_KEY: ${{ secrets.API_KEY }}
run: ./deploy.sh
```
## Testing and Debugging Workflows
[Section titled “Testing and Debugging Workflows”](#testing-and-debugging-workflows)
### Testing from Branches with workflow\_dispatch
[Section titled “Testing from Branches with workflow\_dispatch”](#testing-from-branches-with-workflow_dispatch)
The **`workflow_dispatch`** trigger allows manual workflow execution from any branch, invaluable for development and testing:
```yaml
name: Test Workflow
on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
debug:
description: 'Enable debug logging'
required: false
type: boolean
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "Testing in ${{ inputs.environment }}"
- run: echo "Debug mode: ${{ inputs.debug }}"
```
To run: navigate to the **Actions** tab → select your workflow → click **Run workflow** → choose your branch and provide inputs.
Tip
Enable debug logging by setting repository secrets `ACTIONS_STEP_DEBUG: true` and `ACTIONS_RUNNER_DEBUG: true`.
**Note:** The workflow definition must be merged to the main branch before it can be executed. Only `workflow_dispatch` works on non-default branches — event triggers do not.
### Debugging Workflow Runs
[Section titled “Debugging Workflow Runs”](#debugging-workflow-runs)
View logs in the **Actions** tab by clicking a run, then a job, then individual steps. Use workflow commands for structured output:
```yaml
steps:
- name: Debug context
run: |
echo "::debug::Debugging workflow context"
echo "::notice::This is a notice"
echo "::warning::This is a warning"
echo "::error::This is an error"
- name: Debug environment
run: |
echo "GitHub event: ${{ github.event_name }}"
echo "Actor: ${{ github.actor }}"
printenv | sort
```
## Agentic Workflows vs Traditional GitHub Actions
[Section titled “Agentic Workflows vs Traditional GitHub Actions”](#agentic-workflows-vs-traditional-github-actions)
While agentic workflows compile to GitHub Actions YAML and run on the same infrastructure, they introduce significant enhancements in security, simplicity, and AI-powered decision-making.
| Feature | Traditional GitHub Actions | Agentic Workflows |
| ------------------------- | -------------------------------------- | ---------------------------------------- |
| **Definition Language** | YAML with explicit steps | Natural language markdown |
| **Complexity** | Requires YAML expertise, API knowledge | Describe intent in plain English |
| **Decision Making** | Fixed if-then logic | AI-powered contextual decisions |
| **Security Model** | Token-based with broad permissions | Sandboxed with safe-outputs |
| **Write Operations** | Direct API access with `GITHUB_TOKEN` | Sanitized through safe-output validation |
| **Network Access** | Unrestricted by default | Allowlisted domains only |
| **Execution Environment** | Standard runner VM | Enhanced sandbox with MCP isolation |
| **Tool Integration** | Manual action selection | MCP server automatic tool discovery |
| **Testing** | `workflow_dispatch` on branches | Same, plus local compilation |
| **Auditability** | Standard workflow logs | Enhanced with agent reasoning logs |
## Next Steps and Resources
[Section titled “Next Steps and Resources”](#next-steps-and-resources)
* **[Quick Start](/gh-aw/setup/quick-start/)** - Create your first agentic workflow
* **[Security Best Practices](/gh-aw/introduction/architecture/)** - Deep dive into agentic security model
* **[Safe Outputs](/gh-aw/reference/safe-outputs/)** - Learn about validated GitHub operations
* **[Workflow Structure](/gh-aw/reference/workflow-structure/)** - Understand markdown workflow syntax
* **[Examples](/gh-aw/examples/scheduled/research-planning/)** - Real-world agentic workflow patterns
* **[Glossary](/gh-aw/reference/glossary/)** - Key terms and concepts
* **[GitHub Actions Documentation](https://docs.github.com/en/actions)** - Official reference
* **[Workflow Syntax](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)** - Complete YAML reference
* **[Security Hardening](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions)** - Security best practices
# Using Custom MCP Servers
> How to use Model Context Protocol (MCP) servers with GitHub Agentic Workflows to connect AI agents to external tools, databases, and services.
[Model Context Protocol](/gh-aw/reference/glossary/#mcp-model-context-protocol) (MCP) is a standard for AI tool integration, allowing agents to securely connect to external tools, databases, and services. GitHub Agentic Workflows includes built-in GitHub MCP integration (see [GitHub Tools](/gh-aw/reference/github-tools/)); this guide covers adding custom MCP servers for external services.
Caution
Custom MCP servers should be **read-only**. Write operations must go through [safe outputs](/gh-aw/reference/safe-outputs/) or [Custom Safe Outputs](/gh-aw/reference/custom-safe-outputs/). Ensure your MCP server implements authentication and authorization to prevent unauthorized write access.
## Manually Configuring a Custom MCP Server
[Section titled “Manually Configuring a Custom MCP Server”](#manually-configuring-a-custom-mcp-server)
Add MCP servers to your workflow’s frontmatter using the `mcp-servers:` section:
```aw
---
on: issues
permissions:
contents: read
mcp-servers:
microsoftdocs:
url: "https://learn.microsoft.com/api/mcp"
allowed: ["*"]
notion:
container: "mcp/notion"
env:
NOTION_TOKEN: "${{ secrets.NOTION_TOKEN }}"
allowed:
- "search_pages"
- "get_page"
- "get_database"
- "query_database"
---
# Your workflow content here
```
## Custom MCP Server Types
[Section titled “Custom MCP Server Types”](#custom-mcp-server-types)
### Stdio MCP Servers
[Section titled “Stdio MCP Servers”](#stdio-mcp-servers)
Execute commands with stdin/stdout communication for Python modules, Node.js scripts, and local executables:
```yaml
mcp-servers:
serena:
command: "uvx"
args: ["--from", "git+https://github.com/oraios/serena", "serena"]
allowed: ["*"]
```
### Docker Container MCP Servers
[Section titled “Docker Container MCP Servers”](#docker-container-mcp-servers)
Run containerized MCP servers with environment variables, volume mounts, and network restrictions:
```yaml
mcp-servers:
custom-tool:
container: "mcp/custom-tool:v1.0"
args: ["-v", "/host/data:/app/data"] # Volume mounts before image
entrypointArgs: ["serve", "--port", "8080"] # App args after image
env:
API_KEY: "${{ secrets.API_KEY }}"
allowed: ["tool1", "tool2"]
network:
allowed:
- defaults
- api.example.com
```
The `container` field generates `docker run --rm -i `.
### HTTP MCP Servers
[Section titled “HTTP MCP Servers”](#http-mcp-servers)
Remote MCP servers accessible via HTTP. Configure authentication using the `headers` field for static API keys, or the `auth` field for dynamic token acquisition:
```yaml
mcp-servers:
deepwiki:
url: "https://mcp.deepwiki.com/sse"
allowed:
- read_wiki_structure
- read_wiki_contents
- ask_question
authenticated-api:
url: "https://api.example.com/mcp"
headers:
Authorization: "Bearer ${{ secrets.API_TOKEN }}"
allowed: ["*"]
```
#### GitHub Actions OIDC Authentication
[Section titled “GitHub Actions OIDC Authentication”](#github-actions-oidc-authentication)
For MCP servers that accept GitHub Actions OIDC tokens, use the `auth` field instead of a static `headers` value. The gateway acquires a short-lived JWT from the GitHub Actions OIDC endpoint and injects it as an `Authorization: Bearer` header on every outgoing request.
```yaml
permissions:
id-token: write # required for OIDC token acquisition
mcp-servers:
my-secure-server:
url: "https://my-server.example.com/mcp"
auth:
type: github-oidc
audience: "https://my-server.example.com" # optional; defaults to the server URL
allowed: ["*"]
```
The `auth.type: github-oidc` field is only valid on HTTP servers. The MCP server is responsible for validating the token; the gateway acts as a token forwarder. See [MCP Gateway — Upstream Authentication](/gh-aw/reference/mcp-gateway/#76-upstream-authentication-oidc) for full specification details.
### Registry-based MCP Servers
[Section titled “Registry-based MCP Servers”](#registry-based-mcp-servers)
Reference MCP servers from the GitHub MCP registry (the `registry` field provides metadata for tooling):
```yaml
mcp-servers:
markitdown:
registry: https://api.mcp.github.com/v0/servers/microsoft/markitdown
container: "ghcr.io/microsoft/markitdown"
allowed: ["*"]
```
## MCP Tool Filtering
[Section titled “MCP Tool Filtering”](#mcp-tool-filtering)
Use `allowed:` to specify which tools are available, or `["*"]` to allow all:
```yaml
mcp-servers:
notion:
container: "mcp/notion"
allowed: ["search_pages", "get_page"] # or ["*"] to allow all
```
## Shared MCP Configurations
[Section titled “Shared MCP Configurations”](#shared-mcp-configurations)
Pre-configured MCP server specifications are available in [`.github/workflows/shared/mcp/`](https://github.com/github/gh-aw/tree/main/.github/workflows/shared/mcp) and can be copied or imported directly. Examples include:
| MCP Server | Import Path | Key Capabilities |
| ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Jupyter** | `shared/mcp/jupyter.md` | Execute code, manage notebooks, visualize data |
| **Drain3** | `shared/mcp/drain3.md` | Log pattern mining with 8 tools including `index_file`, `list_clusters`, `find_anomalies` |
| **Others** | `shared/mcp/*.md` | AST-Grep, Azure, Brave Search, Context7, DataDog, DeepWiki, Fabric RTI, MarkItDown, Microsoft Docs, Notion, Sentry, Serena, Server Memory, Slack, Tavily |
## Adding MCP Servers from the Registry
[Section titled “Adding MCP Servers from the Registry”](#adding-mcp-servers-from-the-registry)
Use `gh aw mcp add` to browse and add servers from the GitHub MCP registry (default: `https://api.mcp.github.com/v0`):
```bash
gh aw mcp add # List available servers
gh aw mcp add my-workflow makenotion/notion-mcp-server # Add server
gh aw mcp add my-workflow makenotion/notion-mcp-server --transport stdio # Specify transport
gh aw mcp add my-workflow makenotion/notion-mcp-server --tool-id my-notion # Custom tool ID
gh aw mcp add my-workflow server-name --registry https://custom.registry.com/v1 # Custom registry
```
## Debugging and Troubleshooting
[Section titled “Debugging and Troubleshooting”](#debugging-and-troubleshooting)
Inspect MCP configurations with CLI commands: `gh aw mcp inspect my-workflow` (add `--server --verbose` for details) or `gh aw mcp list-tools my-workflow`.
For advanced debugging, import `shared/mcp-debug.md` to access diagnostic tools and the `report_diagnostics_to_pull_request` custom safe-output.
**Common issues**: Connection failures (verify syntax, env vars, network) or tool not found (check toolsets configuration or `allowed` list with `gh aw mcp inspect`).
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [MCP Scripts](/gh-aw/reference/mcp-scripts/) - Define custom inline tools without external MCP servers
* [Tools](/gh-aw/reference/tools/) - Complete tools reference
* [CLI Commands](/gh-aw/setup/cli/) - CLI commands including `mcp inspect`
* [Imports](/gh-aw/reference/imports/) - Modularizing workflows with includes
* [Frontmatter](/gh-aw/reference/frontmatter/) - All configuration options
* [Workflow Structure](/gh-aw/reference/workflow-structure/) - Directory organization
* [Model Context Protocol Specification](https://github.com/modelcontextprotocol/specification)
* [GitHub MCP Server](https://github.com/github/github-mcp-server)
# MemoryOps
> Techniques for using cache-memory and repo-memory to build stateful workflows that track progress, share data, and compute trends
MemoryOps enables workflows to persist state across runs using `cache-memory` and `repo-memory`. Build workflows that remember their progress, resume after interruptions, share data between workflows, and avoid API throttling.
Use MemoryOps for incremental processing, trend analysis, multi-step tasks, and workflow coordination.
## How to Use These Patterns
[Section titled “How to Use These Patterns”](#how-to-use-these-patterns)
Tip
State your high-level goal in the workflow prompt and let the AI agent handle the implementation. The examples below are prompts you’d write — the agent generates the code automatically based on your memory configuration.
## Memory Types
[Section titled “Memory Types”](#memory-types)
### Cache Memory
[Section titled “Cache Memory”](#cache-memory)
Fast, ephemeral storage using GitHub Actions cache (7 days retention):
```yaml
tools:
cache-memory:
key: my-workflow-state
```
**Use for**: Temporary state, session data, short-term caching\
**Location**: `/tmp/gh-aw/cache-memory/`
### Repository Memory
[Section titled “Repository Memory”](#repository-memory)
Persistent, version-controlled storage in a dedicated Git branch:
```yaml
tools:
repo-memory:
branch-name: memory/my-workflow
file-glob: ["*.json", "*.jsonl"]
```
**Use for**: Historical data, trend tracking, permanent state\
**Location**: `/tmp/gh-aw/repo-memory/default/`
## Pattern 1: Exhaustive Processing
[Section titled “Pattern 1: Exhaustive Processing”](#pattern-1-exhaustive-processing)
Track progress through large datasets with todo/done lists to ensure complete coverage across multiple runs.
```markdown
Analyze all open issues in the repository. Track your progress in cache-memory
so you can resume if the workflow times out. Mark each issue as done after
processing it. Generate a final report with statistics.
```
The agent maintains a state file with items to process and completed items, updating it after each item so the workflow can resume if interrupted:
```json
{
"todo": [123, 456, 789],
"done": [101, 102],
"errors": [],
"last_run": 1705334400
}
```
Real examples: `.github/workflows/repository-quality-improver.md`, `.github/workflows/copilot-agent-analysis.md`
## Pattern 2: State Persistence
[Section titled “Pattern 2: State Persistence”](#pattern-2-state-persistence)
Save workflow checkpoints to resume long-running tasks that may timeout.
```markdown
Migrate 10,000 records from the old format to the new format. Process 500
records per run and save a checkpoint. Each run should resume from the last
checkpoint until all records are migrated.
```
The agent stores a checkpoint with the last processed position and resumes from it each run:
```json
{
"last_processed_id": 1250,
"batch_number": 13,
"total_migrated": 1250,
"status": "in_progress"
}
```
Real examples: `.github/workflows/daily-news.md`, `.github/workflows/cli-consistency-checker.md`
## Pattern 3: Shared Information
[Section titled “Pattern 3: Shared Information”](#pattern-3-shared-information)
Share data between workflows using repo-memory branches. A producer workflow stores data; consumers read it using the same branch name.
*Producer workflow:*
```markdown
Every 6 hours, collect repository metrics (issues, PRs, stars) and store them
in repo-memory so other workflows can analyze the data later.
```
*Consumer workflow:*
```markdown
Load the historical metrics from repo-memory and compute weekly trends.
Generate a trend report with visualizations.
```
Both workflows reference the same branch:
```yaml
tools:
repo-memory:
branch-name: memory/shared-data
```
Real examples: `.github/workflows/metrics-collector.md` (producer), trend analysis workflows (consumers)
## Pattern 4: Data Caching
[Section titled “Pattern 4: Data Caching”](#pattern-4-data-caching)
Cache API responses to avoid rate limits and reduce workflow time. The agent checks for fresh cached data before making API calls, using suggested TTLs: repository metadata (24h), contributor lists (12h), issues/PRs (1h), workflow runs (30m).
```markdown
Fetch repository metadata and contributor lists. Cache the data for 24 hours
to avoid repeated API calls. If the cache is fresh, use it. Otherwise, fetch
new data and update the cache.
```
Real examples: `.github/workflows/daily-news.md`
## Pattern 5: Trend Computation
[Section titled “Pattern 5: Trend Computation”](#pattern-5-trend-computation)
Store time-series data and compute trends, moving averages, and statistics. The agent appends new data points to a JSON Lines history file and computes trends using Python.
```markdown
Collect daily build times and test times. Store them in repo-memory as
time-series data. Compute 7-day and 30-day moving averages. Generate trend
charts showing whether performance is improving or declining over time.
```
Real examples: `.github/workflows/daily-code-metrics.md`, `.github/workflows/shared/charts-with-trending.md`
## Pattern 6: Multiple Memory Stores
[Section titled “Pattern 6: Multiple Memory Stores”](#pattern-6-multiple-memory-stores)
Use multiple memory instances for different lifecycles — cache-memory for temporary session data, separate repo-memory branches for metrics, configuration, and archives.
```markdown
Use cache-memory for temporary API responses during this run. Store daily
metrics in one repo-memory branch for trend analysis. Keep data schemas in
another branch. Archive full snapshots in a third branch with compression.
```
```yaml
tools:
cache-memory:
key: session-data # Fast, temporary
repo-memory:
- id: metrics
branch-name: memory/metrics # Time-series data
- id: config
branch-name: memory/config # Schema and metadata
- id: archive
branch-name: memory/archive # Compressed backups
```
## Best Practices
[Section titled “Best Practices”](#best-practices)
### Use JSON Lines for Time-Series Data
[Section titled “Use JSON Lines for Time-Series Data”](#use-json-lines-for-time-series-data)
Append-only format ideal for logs and metrics:
```bash
# Append without reading entire file
echo '{"date": "2024-01-15", "value": 42}' >> data.jsonl
```
### Include Metadata
[Section titled “Include Metadata”](#include-metadata)
Document your data structure:
```json
{
"dataset": "performance-metrics",
"schema": {
"date": "YYYY-MM-DD",
"value": "integer"
},
"retention": "90 days"
}
```
### Implement Data Rotation
[Section titled “Implement Data Rotation”](#implement-data-rotation)
Prevent unbounded growth:
```bash
# Keep only last 90 entries
tail -n 90 history.jsonl > history-trimmed.jsonl
mv history-trimmed.jsonl history.jsonl
```
### Validate State
[Section titled “Validate State”](#validate-state)
Check integrity before processing:
```bash
if [ -f state.json ] && jq empty state.json 2>/dev/null; then
echo "Valid state"
else
echo "Corrupt state, reinitializing..."
echo '{}' > state.json
fi
```
## Security Considerations
[Section titled “Security Considerations”](#security-considerations)
Memory stores are visible to anyone with repository access. Never store credentials, API tokens, PII, or secrets — only aggregate statistics and anonymized data.
```bash
# ✓ GOOD - Aggregate statistics
echo '{"open_issues": 42}' > metrics.json
# ✗ BAD - Individual user data
echo '{"user": "alice", "email": "alice@example.com"}' > users.json
```
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
**Cache not persisting**: Verify cache key is consistent across runs
**Repo memory not updating**: Check `file-glob` patterns match your files and files are within `max-file-size` limit
**Out of memory errors**: Process data in chunks instead of loading entirely, implement data rotation
**Merge conflicts**: Use JSON Lines format (append-only), separate branches per workflow, or add run ID to filenames
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [MCP Servers](/gh-aw/guides/mcps/) - Memory MCP server configuration
* [Deterministic Patterns](/gh-aw/guides/deterministic-agentic-patterns/) - Data preprocessing
* [Safe Outputs](/gh-aw/reference/custom-safe-outputs/) - Storing workflow outputs
* [Frontmatter Reference](/gh-aw/reference/frontmatter/) - Configuration options
# Network Configuration Guide
> Common network configurations for package registries, CDNs, and development tools
This guide provides practical examples for configuring network access in GitHub Agentic Workflows while maintaining security.
## Quick Start
[Section titled “Quick Start”](#quick-start)
Configure network access by adding ecosystem identifiers to the `network.allowed` list. Always include `defaults` for basic infrastructure:
```yaml
network:
allowed:
- defaults # Required: Basic infrastructure
- python # PyPI, conda (for Python projects)
- node # npm, yarn, pnpm (for Node.js projects)
- go # Go module proxy (for Go projects)
- containers # Docker Hub, GHCR (for container projects)
```
## Available Ecosystems
[Section titled “Available Ecosystems”](#available-ecosystems)
| Ecosystem | Includes | Use For |
| --------------- | ----------------------------------------- | ------------------------------------------------------- |
| `defaults` | Certificates, JSON schema, Ubuntu mirrors | All workflows (required) |
| `python` | PyPI, conda, pythonhosted.org | Python packages |
| `node` | npm, yarn, pnpm, Node.js | JavaScript/TypeScript |
| `go` | proxy.golang.org, sum.golang.org | Go modules |
| `containers` | Docker Hub, GHCR, Quay, GCR, MCR | Container images |
| `java` | Maven, Gradle | Java dependencies |
| `dotnet` | NuGet | .NET packages |
| `julia` | pkg.julialang.org, storage.julialang.net | Julia packages |
| `ruby` | RubyGems, Bundler | Ruby gems |
| `rust` | crates.io | Rust crates |
| `github` | githubusercontent.com | GitHub resources |
| `terraform` | HashiCorp registry | Terraform modules |
| `playwright` | Browser downloads | Web testing ([reference](/gh-aw/reference/playwright/)) |
| `linux-distros` | Debian, Ubuntu, Alpine | Linux packages |
## Common Configuration Patterns
[Section titled “Common Configuration Patterns”](#common-configuration-patterns)
```yaml
# Python project with containers
network:
allowed:
- defaults
- python
- containers
# Full-stack web development
network:
allowed:
- defaults
- node
- playwright
- github
# DevOps automation
network:
allowed:
- defaults
- terraform
- containers
- github
```
## Custom Domains
[Section titled “Custom Domains”](#custom-domains)
Add specific domains for your services. Both base domains and wildcard patterns are supported:
```yaml
network:
allowed:
- defaults
- python
- "api.example.com" # Matches api.example.com and subdomains
- "*.cdn.example.com" # Wildcard: matches any subdomain of cdn.example.com
```
**Wildcard pattern behavior:**
* `*.example.com` matches `sub.example.com`, `deep.nested.example.com`, and `example.com`
* Only single wildcards at the start are supported (e.g., `*.*.example.com` is invalid)
Tip
Both `example.com` and `*.example.com` match subdomains. Use wildcards when you want to explicitly document that subdomain access is expected.
## Protocol-Specific Filtering
[Section titled “Protocol-Specific Filtering”](#protocol-specific-filtering)
Restrict domains to specific protocols for enhanced security (Copilot engine with AWF firewall):
```yaml
engine: copilot
network:
allowed:
- defaults
- "https://secure.api.example.com" # HTTPS-only
- "http://legacy.internal.com" # HTTP-only
- "example.org" # Both protocols (default)
sandbox:
agent: awf # Firewall enabled
```
**Validation:** Invalid protocols (e.g., `ftp://`) are rejected at compile time.
See [Network Permissions - Protocol-Specific Filtering](/gh-aw/reference/network/#protocol-specific-domain-filtering) for complete details.
## Strict Mode and Ecosystem Identifiers
[Section titled “Strict Mode and Ecosystem Identifiers”](#strict-mode-and-ecosystem-identifiers)
Workflows use [strict mode](/gh-aw/reference/frontmatter/#strict-mode-strict) by default, which enforces ecosystem identifiers instead of individual domains for security. This applies to all engines.
```yaml
# ✗ Rejected in strict mode
network:
allowed:
- "pypi.org" # Error: use 'python' ecosystem instead
- "npmjs.org" # Error: use 'node' ecosystem instead
# ✓ Accepted in strict mode
network:
allowed:
- python # Ecosystem identifier
- node # Ecosystem identifier
```
### Error Messages
[Section titled “Error Messages”](#error-messages)
When strict mode rejects a domain that belongs to a known ecosystem, the error message suggests the ecosystem identifier:
```text
error: strict mode: network domains must be from known ecosystems (e.g., 'defaults',
'python', 'node') for all engines in strict mode. Custom domains are not allowed for
security. Did you mean: 'pypi.org' belongs to ecosystem 'python'?
```
When strict mode rejects a custom domain:
```text
error: strict mode: network domains must be from known ecosystems (e.g., 'defaults',
'python', 'node') for all engines in strict mode. Custom domains are not allowed for
security. Set 'strict: false' to use custom domains.
```
### Using Custom Domains
[Section titled “Using Custom Domains”](#using-custom-domains)
To use custom domains (domains not in known ecosystems), disable strict mode:
```yaml
---
strict: false # Required for custom domains
network:
allowed:
- python # Ecosystem identifier
- "api.example.com" # Custom domain (only allowed with strict: false)
---
```
**Security Note**: Custom domains bypass ecosystem validation. Only disable strict mode when necessary and ensure you trust the custom domains you allow.
## Security Best Practices
[Section titled “Security Best Practices”](#security-best-practices)
1. **Start minimal** - Only add ecosystems you actually use
2. **Use ecosystem identifiers** - Don’t list individual domains (use `python` instead of `pypi.org`, `files.pythonhosted.org`, etc.)
3. **Keep strict mode enabled** - Provides enhanced security validation (enabled by default)
4. **Add incrementally** - Start with `defaults`, add ecosystems as needed based on firewall denials
## Troubleshooting Firewall Blocking
[Section titled “Troubleshooting Firewall Blocking”](#troubleshooting-firewall-blocking)
View firewall activity with `gh aw logs --run-id ` to identify blocked domains:
```text
Firewall Log Analysis
Blocked Domains:
✗ registry.npmjs.org:443 (3 requests) → Add `node` ecosystem
✗ pypi.org:443 (2 requests) → Add `python` ecosystem
```
Common mappings: npm/Node.js → `node`, PyPI/Python → `python`, Docker → `containers`, Go modules → `go`.
## Advanced Options
[Section titled “Advanced Options”](#advanced-options)
Disable all external network access (engine communication still allowed):
```yaml
network: {}
```
View complete ecosystem domain lists in the [ecosystem domains source](https://github.com/github/gh-aw/blob/main/pkg/workflow/data/ecosystem_domains.json).
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Network Permissions Reference](/gh-aw/reference/network/) - Complete network configuration reference
* [Supported Languages & Ecosystems](/gh-aw/reference/supported-languages/) - Language-first overview of ecosystem identifiers
* [Playwright Reference](/gh-aw/reference/playwright/) - Browser automation and network requirements
* [Security Guide](/gh-aw/introduction/architecture/) - Security best practices
* [Troubleshooting](/gh-aw/troubleshooting/common-issues/) - Common issues and solutions
# Reusing Workflows
> How to reuse, add, share, update, and distribute workflows.
## Adding Workflows
[Section titled “Adding Workflows”](#adding-workflows)
You can add any existing workflow you have access to from external repositories.
Use the `gh aw add-wizard` command to add a workflow with interactive guidance:
```bash
gh aw add-wizard
```
For example, to add the `daily-repo-status` workflow from the `githubnext/agentics` repository:
```bash
# Full GitHub URL
gh aw add-wizard https://github.com/githubnext/agentics/blob/main/workflows/daily-repo-status.md
# Short form (for workflows in top-level workflows/ directory)
gh aw add-wizard githubnext/agentics/daily-repo-status
# Skip the API key prompt when a secret is already configured
gh aw add-wizard githubnext/agentics/daily-repo-status --skip-secret
```
This checks requirements, adds the workflow markdown file to your repository, and generates the corresponding YAML workflow. After adding, commit and push the changes to your repository.
The `--skip-secret` flag bypasses the interactive API key prompt. Use it when the required secret (e.g., `COPILOT_GITHUB_TOKEN`) is already configured at the organisation or repository level.
For non-interactive installation, use `gh aw add` with optional versioning. By default this looks in the `workflows/` directory, but you can specify an explicit path if needed:
```bash
gh aw add githubnext/agentics/ci-doctor # short form
gh aw add githubnext/agentics/ci-doctor@v1.0.0 # with version
gh aw add githubnext/agentics/workflows/ci-doctor.md # explicit path
```
Use `--name`, `--pr`, `--force`, `--engine`, or `--verbose` flags to customize installation. The `source` field is automatically added to workflow frontmatter for tracking origin and enabling updates.
When installing a workflow, `gh aw add` also automatically fetches:
* Workflows referenced in the workflow’s [`dispatch-workflow`](/gh-aw/reference/safe-outputs/#workflow-dispatch-dispatch-workflow) safe output.
* Files declared in the workflow’s [`resources:`](/gh-aw/reference/frontmatter/#resources-resources) frontmatter field (companion workflows, custom actions).
Note
Check carefully that the workflow comes from a trusted source and is appropriate for your use in your repository. Review the workflow’s content and understand what it does before adding it to your repository.
Note
Workflows marked with `private: true` in their frontmatter cannot be added to other repositories. Attempting to do so will fail with an error. See [Private Workflows](/gh-aw/reference/frontmatter/#private-workflows-private) for details.
## Using an Agent to Import and Adapt a Workflow
[Section titled “Using an Agent to Import and Adapt a Workflow”](#using-an-agent-to-import-and-adapt-a-workflow)
You can use a coding agent to import a workflow from another repository and adapt it for your own. The agent reads the source workflow, customizes repository-specific configuration (labels, assignees, branch names, permissions), and sets up the repository — including initialization if needed.
Tip
Use this approach when you want to significantly customize a workflow before using it. For straightforward imports without modification, use [`gh aw add`](#adding-workflows) or [`gh aw add-wizard`](#adding-workflows) instead.
### GitHub Web Interface
[Section titled “GitHub Web Interface”](#github-web-interface)
**If you have access to GitHub Copilot**, use one of these prompts in your repository to import and adapt a workflow from another repo. Each prompt also initializes the repository for GitHub Agentic Workflows if it has not been set up yet.
* Daily Status Report
```markdown
Initialize this repository for GitHub Agentic Workflows using https://raw.githubusercontent.com/github/gh-aw/main/install.md
Then import and adapt the daily-repo-status workflow from githubnext/agentics. The source is at https://github.com/githubnext/agentics/blob/main/workflows/daily-repo-status.md. Adapt any labels, team references, and output format to suit this repository.
```
* Issue Triage
```markdown
Initialize this repository for GitHub Agentic Workflows using https://raw.githubusercontent.com/github/gh-aw/main/install.md
Then import and adapt an issue triage workflow from github/gh-aw. Find a suitable issue triage workflow in that repository and adapt it: update the labels, assignee logic, and any repository-specific rules to match this project's conventions.
```
* CI Doctor
```markdown
Initialize this repository for GitHub Agentic Workflows using https://raw.githubusercontent.com/github/gh-aw/main/install.md
Then import and adapt the CI Doctor workflow from githubnext/agentics. The source is at https://github.com/githubnext/agentics/blob/main/workflows/ci-doctor.md. Adapt the workflow to match this repository's CI setup, branch naming, and issue labeling conventions.
```
Tip
On the first run in a new repository, the workflow may fail because secrets are not yet configured. The agentic workflow should detect missing tokens and open an issue with setup instructions.
### Coding Agent
[Section titled “Coding Agent”](#coding-agent)
Follow these steps to import and adapt a workflow using VSCode, Claude, Codex, or Copilot in your terminal.
1. **Start your coding agent** in the context of your repository.
2. **Enter the following prompt**, replacing `SOURCE_WORKFLOW`, `OWNER`, and `REPO` with the workflow you want to import:
```text
Initialize this repository for GitHub Agentic Workflows using https://raw.githubusercontent.com/github/gh-aw/main/install.md
Then import and adapt the SOURCE_WORKFLOW workflow from OWNER/REPO. The source is at https://github.com/OWNER/REPO/blob/main/workflows/SOURCE_WORKFLOW.md.
Adapt the workflow for this repository: update any labels, assignees, branch names, and permissions to match this project's structure. Keep the overall purpose and logic of the workflow intact.
```
You can add as much extra context, constraints, or customization goals after the last line as you need.
3. **Set up required secrets** if you haven’t done so already. See [Engines](/gh-aw/reference/engines/) for the secrets your chosen engine requires.
After the agent finishes, review the adapted workflow, merge the pull request, and trigger a run from the Actions tab or with `gh aw run`.
## Updating Workflows
[Section titled “Updating Workflows”](#updating-workflows)
When you add a workflow, a tracking `source:` entry remembers where it came from. You can keep workflows synchronized with their source repositories:
```bash
gh aw update # update all workflows
gh aw update ci-doctor # update specific workflow
gh aw update ci-doctor issue-triage # update multiple
```
Use `--major`, `--force`, `--no-merge`, `--engine`, or `--verbose` flags to control update behavior. Semantic versions (e.g., `v1.2.3`) update to latest compatible release within same major version. Branch references update to latest commit. SHA references update to the latest commit on the default branch. Updates use 3-way merge by default to preserve local changes; use `--no-merge` to replace with the upstream version. When merge conflicts occur, manually resolve conflict markers and run `gh aw compile`.
## Imports
[Section titled “Imports”](#imports)
Import reusable components using the `imports:` field in frontmatter. File paths are relative to the workflow location:
```yaml
---
on: issues
engine: copilot
imports:
- shared/common-tools.md
- shared/security-setup.md
- shared/mcp/tavily.md
---
```
During `gh aw add`, imports are expanded to track source repository (e.g., `shared/common-tools.md` becomes `githubnext/agentics/shared/common-tools.md@abc123def`).
Remote imports are automatically cached in `.github/aw/imports/` by commit SHA. This enables offline workflow compilation once imports have been downloaded. The cache is shared across different refs pointing to the same commit, reducing redundant downloads.
See [Imports Reference](/gh-aw/reference/imports/) for path formats, merge semantics, and field-specific behavior.
## Importing Agent Files
[Section titled “Importing Agent Files”](#importing-agent-files)
Agent files provide specialized AI instructions and behavior. See [Importing Copilot Copilot Agent Files](/gh-aw/reference/copilot-custom-agents/) for details on creating and importing agent files from external repositories.
## Example: Modular Workflow with Imports
[Section titled “Example: Modular Workflow with Imports”](#example-modular-workflow-with-imports)
Create a shared Model Context Protocol (MCP) server configuration in `.github/workflows/shared/mcp/tavily.md`:
```yaml
---
mcp-servers:
tavily:
url: "https://mcp.tavily.com/mcp/?tavilyApiKey=${{ secrets.TAVILY_API_KEY }}"
allowed: ["*"]
network:
allowed:
- mcp.tavily.com
---
```
Reference it in your workflow to include the Tavily MCP server alongside other tools:
```yaml
---
on:
issues:
types: [opened]
imports:
- shared/mcp/tavily.md
tools:
github:
toolsets: [issues]
permissions:
contents: read
---
# Research Agent
Perform web research using Tavily and respond to issues.
```
**Result**: The compiled workflow includes both the Tavily MCP server from the import and the GitHub tools from the main workflow, with network permissions automatically merged to allow access to both `mcp.tavily.com` and GitHub API endpoints.
## Specification Formats and Validation
[Section titled “Specification Formats and Validation”](#specification-formats-and-validation)
Workflow and import specifications require minimum 3 parts (owner/repo/path) for remote imports. Explicit paths must end with `.md`. Versions can be semantic tags (`@v1.0.0`), branches (`@develop`), or commit SHAs. Identifiers use alphanumeric characters with hyphens/underscores (cannot start/end with hyphen).
**Examples:**
* Repository: `owner/repo[@version]`
* Short workflow: `owner/repo/workflow[@version]` (adds `workflows/` prefix and `.md`)
* Explicit workflow: `owner/repo/path/to/workflow.md[@version]`
* Shared import: `owner/repo/shared/tools/config.md[@version]`
* Copilot agent file import: `owner/repo/.github/agents/agent-name.md[@version]`
* GitHub URL: `https://github.com/owner/repo/blob/main/workflows/ci-doctor.md`
* Raw URL: `https://raw.githubusercontent.com/owner/repo/refs/heads/main/workflows/ci-doctor.md`
## Best Practices
[Section titled “Best Practices”](#best-practices)
Use semantic versioning for stable workflows and agent files, branches for development, and commit SHAs for immutability.
**Related:** [CLI Commands](/gh-aw/setup/cli/) | [Workflow Structure](/gh-aw/reference/workflow-structure/) | [Frontmatter](/gh-aw/reference/frontmatter/) | [Imports](/gh-aw/reference/imports/) | [Copilot Agent Files](/gh-aw/reference/copilot-custom-agents/)
# Self-Hosted Runners
> How to configure the runs-on field to target self-hosted runners in agentic workflows.
Use the `runs-on` frontmatter field to target a self-hosted runner instead of the default `ubuntu-latest`.
Note
Runners must be Linux with Docker support. macOS and Windows are not supported.
Self-hosted runners must allow `sudo` for agentic workflows. This is a requirement to allow all GH-AW security features to be enabled. Specific technical needs are:
* AWF (Agentic Workflow Firewall) applies host-level `iptables` rules to the Linux kernel `DOCKER-USER` chain to enforce network egress filtering for all agent containers on the AWF bridge network. This outer security boundary requires root UID.
* Container-level `iptables`, Squid proxy ACLs, and capability drops add additional defense in depth, but they do not replace host-level filtering.
For these reasons, a non-sudo mode is not supported, including ARC configurations with `allowPrivilegeEscalation: false`.
## runs-on formats
[Section titled “runs-on formats”](#runs-on-formats)
**String** — single runner label:
```aw
---
on: issues
runs-on: self-hosted
---
```
**Array** — runner must have *all* listed labels (logical AND):
```aw
---
on: issues
runs-on: [self-hosted, linux, x64]
---
```
**Object** — named runner group, optionally filtered by labels:
```aw
---
on: issues
runs-on:
group: my-runner-group
labels: [linux, x64]
---
```
## Sharing configuration via imports
[Section titled “Sharing configuration via imports”](#sharing-configuration-via-imports)
`runs-on` must be set in each workflow — it is not merged from imports. Other settings like `network` and `tools` can be shared:
.github/workflows/shared/runner-config.md
```aw
---
network:
allowed:
- defaults
- private-registry.example.com
tools:
bash: {}
---
```
```aw
---
on: issues
imports:
- shared/runner-config.md
runs-on: [self-hosted, linux, x64]
---
Triage this issue.
```
## Configuring the detection job runner
[Section titled “Configuring the detection job runner”](#configuring-the-detection-job-runner)
When [threat detection](/gh-aw/reference/threat-detection/) is enabled, the detection job runs on the agent job’s runner by default. Override it with `safe-outputs.threat-detection.runs-on`:
```aw
---
on: issues
runs-on: [self-hosted, linux, x64]
safe-outputs:
create-issue: {}
threat-detection:
runs-on: ubuntu-latest
---
```
This is useful when your self-hosted runner lacks outbound internet access for AI detection, or when you want to run the detection job on a cheaper runner.
## Configuring the framework job runner
[Section titled “Configuring the framework job runner”](#configuring-the-framework-job-runner)
Framework jobs — activation, pre-activation, safe-outputs, unlock, APM, update\_cache\_memory, and push\_repo\_memory — default to `ubuntu-slim`. Use `runs-on-slim:` to override all of them at once:
```aw
---
on: issues
runs-on: [self-hosted, linux, x64]
runs-on-slim: self-hosted
safe-outputs:
create-issue: {}
---
```
Note
`runs-on` controls only the main agent job. `runs-on-slim` controls all framework/generated jobs. `safe-outputs.runs-on` still takes precedence over `runs-on-slim` for safe-output jobs specifically.
## Related documentation
[Section titled “Related documentation”](#related-documentation)
* [Frontmatter](/gh-aw/reference/frontmatter/#run-configuration-run-name-runs-on-runs-on-slim-timeout-minutes) — `runs-on` and `runs-on-slim` syntax reference
* [Imports](/gh-aw/reference/imports/) — importable fields and merge semantics
* [Threat Detection](/gh-aw/reference/threat-detection/) — detection job configuration
* [Network Access](/gh-aw/reference/network/) — configuring outbound network permissions
* [Sandbox](/gh-aw/reference/sandbox/) — container and Docker requirements
# Using Serena
> Configure the Serena MCP server for semantic code analysis and intelligent code editing in your agentic workflows.
This guide covers using [Serena](https://github.com/oraios/serena), a powerful coding agent toolkit that provides semantic code retrieval and editing capabilities to agentic workflows.
Danger
`tools.serena` has been removed. Use the `shared/mcp/serena.md` shared workflow instead (see [Migration](#migration-from-toolsserena) below). Workflows that still use `tools.serena` will fail to compile.
## What is Serena?
[Section titled “What is Serena?”](#what-is-serena)
Serena is an MCP server that enhances AI agents with IDE-like tools for semantic code analysis and manipulation. It supports **30+ programming languages** through Language Server Protocol (LSP) integration, enabling agents to find symbols, navigate relationships, edit at symbol level, and analyze code structure - all without reading entire files or performing text-based searches.
Tip
Serena excels at navigating and manipulating complex codebases, especially for large, well-structured projects where precise code navigation and editing are essential.
## Quick Start
[Section titled “Quick Start”](#quick-start)
### Recommended: Import shared workflow
[Section titled “Recommended: Import shared workflow”](#recommended-import-shared-workflow)
The preferred way to add Serena is to import the shared workflow, which configures the complete MCP server automatically:
```aw
---
on: issues
engine: copilot
permissions:
contents: read
imports:
- uses: shared/mcp/serena.md
with:
languages: ["go", "typescript"]
---
```
For Go-only workflows, use the convenience wrapper:
```aw
---
on: issues
engine: copilot
permissions:
contents: read
imports:
- shared/mcp/serena-go.md
---
```
### Example: Code Analysis
[Section titled “Example: Code Analysis”](#example-code-analysis)
```aw
---
engine: copilot
permissions:
contents: read
imports:
- uses: shared/mcp/serena.md
with:
languages: ["go"]
tools:
github:
toolsets: [default]
---
# Code Quality Analyzer
Analyze Go code for quality improvements:
1. Find all exported functions and check for missing documentation
2. Identify code patterns and suggest improvements
```
## Migration from `tools.serena`
[Section titled “Migration from tools.serena”](#migration-from-toolsserena)
Replace `tools.serena` with the equivalent import:
Before (removed)
```yaml
tools:
serena: ["go", "typescript"]
```
After (recommended)
```aw
imports:
- uses: shared/mcp/serena.md
with:
languages: ["go", "typescript"]
```
For Go-only workflows there is a shorthand:
```aw
imports:
- shared/mcp/serena-go.md
```
The shared workflow configures the full Serena MCP server (container image, entrypoint, workspace mount) explicitly. Compiling a workflow that still uses `tools.serena` now fails with an error:
```plaintext
'tools.serena' has been removed. Use the shared/mcp/serena.md workflow instead:
imports:
- uses: shared/mcp/serena.md
with:
languages: ["go", "typescript"]
```
## Language Support
[Section titled “Language Support”](#language-support)
Serena supports **30+ programming languages** through Language Server Protocol (LSP):
| Category | Languages |
| -------------- | --------------------------------------- |
| **Systems** | C, C++, Rust, Go, Zig |
| **JVM** | Java, Kotlin, Scala, Groovy (partial) |
| **Web** | JavaScript, TypeScript, Dart, Elm |
| **Dynamic** | Python, Ruby, PHP, Perl, Lua |
| **Functional** | Haskell, Elixir, Erlang, Clojure, OCaml |
| **Scientific** | R, Julia, MATLAB, Fortran |
| **Shell** | Bash, PowerShell |
| **Other** | C#, Swift, Nix, Markdown, YAML, TOML |
Note
Some language servers require additional dependencies. Most are automatically installed by Serena, but check the [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) documentation for specific requirements.
## Available Tools
[Section titled “Available Tools”](#available-tools)
Serena provides semantic code tools organized into three categories:
| Category | Tools |
| --------------------- | ------------------------------------------------------------------------------------------ |
| **Symbol Navigation** | `find_symbol`, `find_referencing_symbols`, `get_symbol_definition`, `list_symbols_in_file` |
| **Code Editing** | `replace_symbol_body`, `insert_after_symbol`, `insert_before_symbol`, `delete_symbol` |
| **Project Analysis** | `find_files`, `get_project_structure`, `analyze_imports` |
These tools enable agents to work at the **symbol level** rather than the file level, making code operations more precise and context-aware.
## Memory Configuration
[Section titled “Memory Configuration”](#memory-configuration)
Serena caches language server indexes for faster operations. Create the cache directory in your workflow:
```bash
mkdir -p /tmp/gh-aw/cache-memory/serena
```
Optionally configure cache-memory in frontmatter:
```yaml
tools:
cache-memory:
key: serena-analysis
```
## Usage Examples
[Section titled “Usage Examples”](#usage-examples)
### Find Unused Functions
[Section titled “Find Unused Functions”](#find-unused-functions)
```aw
---
engine: copilot
imports:
- shared/mcp/serena-go.md
tools:
github:
toolsets: [default]
---
# Find Unused Code
1. Configure memory: `mkdir -p /tmp/gh-aw/cache-memory/serena`
2. Use `find_symbol` and `find_referencing_symbols` to identify unused exports
3. Report findings
```
### Automated Refactoring
[Section titled “Automated Refactoring”](#automated-refactoring)
```aw
---
engine: claude
imports:
- uses: shared/mcp/serena.md
with:
languages: ["python"]
tools:
edit:
---
# Add Type Hints
1. Find functions without type hints
2. Add annotations using `replace_symbol_body`
3. Verify correctness
```
## Best Practices
[Section titled “Best Practices”](#best-practices)
Configure cache directory early (`mkdir -p /tmp/gh-aw/cache-memory/serena`) for faster operations. Prefer symbol-level operations (`replace_symbol_body`) over file-level edits. Combine Serena with other tools like `github`, `edit`, and `bash` for complete workflows. For large codebases, start with targeted analysis of specific packages before expanding scope.
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
**Language server not found:** Install required dependencies (e.g., `go install golang.org/x/tools/gopls@latest` for Go).
**Memory permission issues:** Ensure cache directory exists with proper permissions: `mkdir -p /tmp/gh-aw/cache-memory/serena && chmod 755 /tmp/gh-aw/cache-memory/serena`
**Slow initial analysis:** Expected behavior as language servers build indexes. Subsequent runs use cached data.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Imports Reference](/gh-aw/reference/imports/) - Full imports and `import-schema` syntax
* [Using MCPs](/gh-aw/guides/mcps/) - General MCP server configuration
* [Tools Reference](/gh-aw/reference/tools/) - Complete tools configuration
* [Getting Started with MCPs](/gh-aw/guides/getting-started-mcp/) - MCP introduction
## External Resources
[Section titled “External Resources”](#external-resources)
* [Serena GitHub Repository](https://github.com/oraios/serena) - Official repository
* [Serena Documentation](https://oraios.github.io/serena/) - Comprehensive user guide
* [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) - Supported languages and dependencies
* [Serena Tools Reference](https://oraios.github.io/serena/01-about/035_tools.html) - Complete tool documentation
# Upgrading Agentic Workflows
> Step-by-step guide to upgrade your repository to the latest version of agentic workflows, including updating extensions, applying codemods, compiling workflows, and validating changes.
This guide walks you through upgrading agentic workflows. `gh aw upgrade` handles the full process: updating the dispatcher agent file, migrating deprecated workflow syntax, and recompiling all workflows.
Tip
Agentic Upgrade
You can start an agent session in your repository on GitHub.com and use the command `/agent agentic-workflows Upgrade` to automatically upgrade your workflows.
Tip
Quick Upgrade
For most users, upgrading is a single command:
```bash
gh aw upgrade
```
This updates agent files, applies codemods, and compiles all workflows.
## Prerequisites
[Section titled “Prerequisites”](#prerequisites)
Before upgrading, ensure you have GitHub CLI (`gh`) v2.0.0+, the latest gh-aw extension, and a clean working directory in your Git repository. Verify with `gh --version`, `gh extension list | grep gh-aw`, and `git status`.
## Step 1: Upgrade the Extension
[Section titled “Step 1: Upgrade the Extension”](#step-1-upgrade-the-extension)
Upgrade the `gh aw` extension to get the latest features and codemods:
```bash
gh extension upgrade gh-aw
```
Tip
Working in GitHub Codespaces?
If the extension upgrade fails due to restricted permissions that prevent global npm installs, use the standalone installer instead:
```bash
curl -sL https://raw.githubusercontent.com/github/gh-aw/main/install-gh-aw.sh | bash
```
Check your version with `gh aw version` and compare against the [latest release](https://github.com/github/gh-aw/releases). If you encounter issues, try a clean reinstall with `gh extension remove gh-aw` followed by `gh extension install github/gh-aw`.
## Step 2: Backup Your Workflows
[Section titled “Step 2: Backup Your Workflows”](#step-2-backup-your-workflows)
Create a backup branch (`git checkout -b backup-before-upgrade`) before upgrading. Workflows are tracked in Git, so you can always revert with `git checkout backup-before-upgrade`.
## Step 3: Run the Upgrade Command
[Section titled “Step 3: Run the Upgrade Command”](#step-3-run-the-upgrade-command)
Run the upgrade command from your repository root:
```bash
gh aw upgrade
```
This command performs three main operations:
### 3.1 Updates Dispatcher Agent File
[Section titled “3.1 Updates Dispatcher Agent File”](#31-updates-dispatcher-agent-file)
Updates `.github/agents/agentic-workflows.agent.md` to the latest template. Workflow prompt files (`.github/aw/*.md`) are resolved directly from GitHub by the agent — they’re no longer managed by the CLI.
### 3.2 Applies Codemods to All Workflows
[Section titled “3.2 Applies Codemods to All Workflows”](#32-applies-codemods-to-all-workflows)
The upgrade automatically applies codemods to fix deprecated fields in all workflow files (`.github/workflows/*.md`):
| Codemod | What It Fixes | Example |
| ----------------------------------- | ---------------------------------------------------- | -------------------------------------------------- |
| **sandbox-false-to-agent-false** | Converts `sandbox: false` to `sandbox.agent: false` | `sandbox: false` → `sandbox: { agent: false }` |
| **network-firewall-migration** | Removes deprecated `network.firewall` field | Deletes `firewall: mandatory` |
| **mcp-scripts-mode-removal** | Removes deprecated `mcp-scripts.mode` field | Deletes `mode: auto` |
| **safe-inputs-to-mcp-scripts** | Renames `safe-inputs:` to `mcp-scripts:` | `safe-inputs:` → `mcp-scripts:` |
| **schedule-at-to-around-migration** | Converts `daily at TIME` to `daily around TIME` | `daily at 10:00` → `daily around 10:00` |
| **delete-schema-file** | Deletes deprecated schema file | Removes `.github/aw/schemas/agentic-workflow.json` |
| **delete-old-agents** | Deletes old `.agent.md` files moved to `.github/aw/` | Removes outdated agent files |
### 3.3 Compiles All Workflows
[Section titled “3.3 Compiles All Workflows”](#33-compiles-all-workflows)
The upgrade automatically compiles all workflows to generate or update `.lock.yml` files, ensuring they’re ready to run in GitHub Actions.
**Example output:**
```text
Updating agent file...
✓ Updated agent file
Applying codemods to all workflows...
Processing workflow: daily-team-status
✓ Applied schedule-at-to-around-migration
✓ Applied timeout-minutes-migration
Processing workflow: issue-triage
✓ Applied mcp-scripts-mode-removal
All workflows processed.
Compiling all workflows...
✓ Compiled 3 workflow(s)
✓ Upgrade complete
```
### Command Options
[Section titled “Command Options”](#command-options)
```bash
gh aw upgrade # updates agent files + codemods + compiles
gh aw upgrade -v # verbose output
gh aw upgrade --no-fix # skip codemods and compilation
gh aw upgrade --dir custom/workflows
```
Caution
Custom Workflow Directory
If you’re using a custom workflow directory (not `.github/workflows`), always specify it with `--dir`:
```bash
gh aw upgrade --dir path/to/workflows
```
## Step 4: Review the Changes
[Section titled “Step 4: Review the Changes”](#step-4-review-the-changes)
Run `git diff .github/workflows/` to verify the changes. Typical migrations include `sandbox: false` → `sandbox.agent: false`, `daily at` → `daily around`, and removal of deprecated `network.firewall` and `mcp-scripts.mode` fields.
## Step 5: Verify Compilation
[Section titled “Step 5: Verify Compilation”](#step-5-verify-compilation)
The upgrade automatically compiles workflows. To validate specific workflows, run `gh aw compile my-workflow --validate`. Common issues include invalid YAML syntax, deprecated fields (fix with `gh aw fix --write`), or incorrect schedule format. See the [schedule syntax reference](/gh-aw/reference/schedule-syntax/) for details.
## Step 6: Review Lock Files
[Section titled “Step 6: Review Lock Files”](#step-6-review-lock-files)
Verify that each `.md` workflow has a corresponding `.lock.yml` file with `git status | grep .lock.yml`. Never edit `.lock.yml` files directly-they’re auto-generated. Always edit the `.md` source and recompile.
## Step 7: Test Your Workflows
[Section titled “Step 7: Test Your Workflows”](#step-7-test-your-workflows)
Trigger a manual run with `gh aw run my-workflow` and monitor with `gh aw logs my-workflow`. Consider testing via a draft PR before merging to production.
## Step 8: Commit and Push
[Section titled “Step 8: Commit and Push”](#step-8-commit-and-push)
Stage and commit your changes:
```bash
git add .github/workflows/ .github/agents/
git commit -m "Upgrade agentic workflows to latest version"
git push origin main
```
Always commit both `.md` and `.lock.yml` files together — never add `.lock.yml` to `.gitignore`.
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
**Extension upgrade fails:** Try a clean reinstall with `gh extension remove gh-aw && gh extension install github/gh-aw`.
**Codemods not applied:** Manually apply with `gh aw fix --write -v`.
**Compilation errors:** Review errors with `gh aw compile my-workflow --validate` and fix YAML syntax in source files.
**Workflows not running:** Verify `.lock.yml` files are committed, check status with `gh aw status`, and confirm secrets are valid with `gh aw secrets bootstrap`.
**Breaking changes:** Revert with `git checkout backup-before-upgrade` and review [release notes](https://github.com/github/gh-aw/releases).
## Advanced Topics
[Section titled “Advanced Topics”](#advanced-topics)
**Upgrading across versions:** Review the [changelog](https://github.com/github/gh-aw/blob/main/CHANGELOG.md) for cumulative changes when upgrading across multiple releases.
**CI/CD automation:** Automate upgrades with a scheduled workflow that creates PRs. Always review automated upgrade PRs before merging.
See the [troubleshooting guide](/gh-aw/troubleshooting/common-issues/) if you run into issues.
# Web Search
> How to add web search capabilities to GitHub Agentic Workflows using Tavily MCP server.
This guide shows how to add web search to workflows using the Tavily Model Context Protocol (MCP) server, an AI-optimized search provider designed for LLM applications. While alternatives exist (Exa, SerpAPI, Brave Search), this guide focuses on Tavily configuration.
## Tavily Search
[Section titled “Tavily Search”](#tavily-search)
[Tavily](https://tavily.com/) provides AI-optimized search with structured JSON responses, news search capability, and fast response times through the [@tavily/mcp](https://github.com/tavily-ai/tavily-mcp) MCP server.
```aw
---
on: issues
engine: copilot
mcp-servers:
tavily:
command: npx
args: ["-y", "@tavily/mcp"]
env:
TAVILY_API_KEY: "${{ secrets.TAVILY_API_KEY }}"
allowed: ["search", "search_news"]
---
# Search and Respond
Search the web for information about: ${{ github.event.issue.title }}
Use the tavily search tool to find recent information.
```
**Setup:**
1. Sign up at [tavily.com](https://tavily.com/) and get your API key
2. Add as repository secret: `gh aw secrets set TAVILY_API_KEY --value ""`
[Tavily Terms of Service](https://tavily.com/terms)
Test your configuration with `gh aw mcp inspect `.
## Tool Discovery
[Section titled “Tool Discovery”](#tool-discovery)
To see available tools from the Tavily MCP server:
```bash
# Inspect the MCP server in your workflow
gh aw mcp inspect my-workflow --server tavily
# List tools with details
gh aw mcp list-tools tavily my-workflow --verbose
```
## Network Permissions
[Section titled “Network Permissions”](#network-permissions)
Agentic workflows require explicit network permissions for MCP servers:
```yaml
network:
allowed:
- defaults
- "*.tavily.com"
```
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [MCP Integration](/gh-aw/guides/mcps/) - Complete MCP server guide
* [Tools](/gh-aw/reference/tools/) - Tool configuration reference
* [AI Engines](/gh-aw/reference/engines/) - Engine capabilities and limitations
* [CLI Commands](/gh-aw/setup/cli/) - CLI commands including `mcp inspect`
* [Model Context Protocol Specification](https://github.com/modelcontextprotocol/specification)
* [Tavily MCP Server](https://github.com/tavily-ai/tavily-mcp)
* [Tavily Documentation](https://tavily.com/)
# Security Architecture
> Comprehensive security architecture overview for GitHub Agentic Workflows, including defense-in-depth mechanisms against rogue MCP servers and malicious agents.
GitHub Agentic Workflows implements a defense-in-depth security architecture that protects against untrusted Model Context Protocol (MCP) servers and compromised agents. This document provides an overview of our security model and visual diagrams of the key components.
## Security Model
[Section titled “Security Model”](#security-model)
Agentic Workflows (AW) adopts a layered approach that combines substrate-enforced isolation, declarative specification, and staged execution. Each layer enforces distinct security properties under different assumptions and constrains the impact of failures above it.
### Threat Model
[Section titled “Threat Model”](#threat-model)
We consider an adversary that may compromise untrusted user-level components, e.g., containers, and may cause them to behave arbitrarily within the privileges granted to them. The adversary may attempt to:
* Access or corrupt the memory or state of other components
* Communicate over unintended channels
* Abuse legitimate channels to perform unintended actions
* Confuse higher-level control logic by deviating from expected workflows
We assume the adversary does not compromise the underlying hardware or cryptographic primitives. Attacks exploiting side channels and covert channels are also out of scope.
***
### Layer 1: Substrate-Level Trust
[Section titled “Layer 1: Substrate-Level Trust”](#layer-1-substrate-level-trust)
AWs run on a GitHub Actions runner virtual machine (VM) and trust Actions’ hardware and kernel-level enforcement mechanisms, including the CPU, MMU, kernel, and container runtime. AWs also rely on three privileged containers: (1) a network firewall that is trusted to configure connectivity for other components via `iptables` and launch the agent container, (2) an API proxy that routes model traffic and may hold endpoint-specific credentials or routing configuration for supported engines, and (3) an MCP Gateway that is trusted to configure and spawn isolated MCP-server containers. Collectively, the substrate level ensures memory isolation between components, CPU and resource isolation, mediation of privileged operations and system calls, and explicit, kernel-enforced communication boundaries. These guarantees hold even if an untrusted user-level component is fully compromised and executes arbitrary code. Trust violations at the substrate level require vulnerabilities in the firewall, MCP Gateway, container runtime, kernel, hypervisor, or hardware. If this layer fails, higher-level security guarantees may not hold.
***
### Layer 2: Configuration-Level Trust
[Section titled “Layer 2: Configuration-Level Trust”](#layer-2-configuration-level-trust)
AW trusts declarative configuration artifacts, e.g., Action steps, network-firewall policies, MCP server configurations, and the toolchains that interpret them to correctly instantiate system structure and connectivity. The configuration level constrains which components are loaded, how components are connected, which communication channels are permitted, and what component privileges are assigned. Externally minted authentication tokens, e.g., agent API keys and GitHub access tokens, are a critical configuration input and are treated as imported capabilities that bound components’ external effects; declarative configuration controls their distribution, e.g., which tokens are loaded into which containers. Security violations arise due to misconfigurations, overly permissive specifications, and limitations of the declarative model. This layer defines what components exist and how they communicate, but it does not constrain how components use those channels over time.
***
### Layer 3: Plan-Level Trust
[Section titled “Layer 3: Plan-Level Trust”](#layer-3-plan-level-trust)
AW additionally relies on plan-level trust to constrain component behavior over time. At this layer, the trusted compiler decomposes a workflow into stages. For each stage, the plan specifies (1) which components are active and their permissions, (2) the data produced by the stage, and (3) how that data may be consumed by subsequent stages. In particular, plan-level trust ensures that important external side effects are explicit and undergo thorough vetting.
A primary instantiation of plan-level trust is the **SafeOutputs** subsystem. SafeOutputs is a set of trusted components that operate on external state. An agent can interact with read-only MCP servers, e.g., the GitHub MCP server, but externalized writes, such as creating GitHub pull requests, are buffered as artifacts by SafeOutputs rather than applied immediately. When the agent finishes, SafeOutputs’ buffered artifacts can be processed by a deterministic sequence of filters and analyses defined by configuration. These checks can include structural constraints, e.g., limiting the number of pull requests, policy enforcement, and automated sanitization to ensure that sensitive information such as authentication tokens are not exported. These filtered and transformed artifacts are passed to a subsequent stage in which they are externalized.
Security violations at the planning layer arise from incorrect plan construction, incomplete or overly permissive stage definitions, or errors in the enforcement of plan transitions. This layer does not protect against failures of substrate-level isolation or mis-allocation of permissions at credential-minting or configuration time. However, it limits the blast radius of a compromised component to the stage in which it is active and its influence on the artifacts passed to the next stage.
## Component Overview
[Section titled “Component Overview”](#component-overview)
The security architecture operates across multiple layers: compilation-time validation, runtime isolation, permission separation, network controls, and output sanitization. The following diagram illustrates the relationships between these components and the flow of data through the system.
```
flowchart TB
subgraph Input[" Input Layer"]
WF[/"Workflow (.md)"/]
IMPORTS[/"Imports & Includes"/]
EVENT[/"GitHub Event (Issue, PR, Comment)"/]
end
subgraph Compile[" Compilation-Time Security"]
SCHEMA["Schema Validation"]
EXPR["Expression Safety Check"]
PIN["Action SHA Pinning"]
SCAN["Security Scanners (actionlint, zizmor, poutine)"]
end
subgraph Runtime[" Runtime Security"]
PRE["Pre-Activation Role & Permission Checks"]
ACT["Activation Content Sanitization"]
AGENT["Agent Execution Read-Only Permissions"]
REDACT_MAIN["Secret Redaction Credential Protection"]
end
subgraph Isolation[" Isolation Layer"]
AWF["Agent Workflow Firewall Network Egress Control"]
PROXY["API Proxy Agent auth-token isolation"]
MCP["MCP Server Sandboxing Container Isolation"]
TOOL["Tool Allowlisting Explicit Permissions"]
end
subgraph Output[" Output Security"]
DETECT["Threat Detection AI-Powered Analysis"]
SAFE["Safe Outputs Permission Separation"]
SANITIZE["Output Sanitization Content Validation"]
end
subgraph Result["✓ Controlled Actions"]
ISSUE["Create Issue"]
PR["Create PR"]
COMMENT["Add Comment"]
end
WF --> SCHEMA
IMPORTS --> SCHEMA
SCHEMA --> EXPR
EXPR --> PIN
PIN --> SCAN
SCAN -->|".lock.yml"| PRE
EVENT --> ACT
PRE --> ACT
ACT --> AGENT
AGENT <--> AWF
AGENT <--> PROXY
AGENT <--> MCP
AGENT <--> TOOL
AGENT --> REDACT_MAIN
REDACT_MAIN --> DETECT
DETECT --> SAFE
SAFE --> SANITIZE
SANITIZE --> ISSUE
SANITIZE --> PR
SANITIZE --> COMMENT
```
## Safe Outputs: Permission Isolation
[Section titled “Safe Outputs: Permission Isolation”](#safe-outputs-permission-isolation)
The SafeOutputs subsystem enforces permission isolation by ensuring that agent execution never has direct write access to external state. The agent job runs with minimal read-only permissions, while write operations are deferred to separate jobs that execute only after the agent completes. This separation ensures that even a fully compromised agent cannot directly modify repository state.
```
flowchart LR
subgraph AgentJob["Agent Job Read-Only Permissions"]
AGENT["AI Agent Execution"]
OUTPUT[/"agent_output.json (Artifact)"/]
AGENT --> OUTPUT
end
subgraph Detection["Threat Detection Job"]
ANALYZE["Analyze for: • Secret Leaks • Malicious Patches"]
end
subgraph SafeJobs["Safe Output Jobs Write Permissions (Scoped)"]
direction TB
ISSUE["create_issue issues: write"]
COMMENT["add_comment issues: write"]
PR["create_pull_request contents: write pull-requests: write"]
LABEL["add_labels issues: write"]
end
subgraph GitHub["GitHub API"]
API["GitHub REST/GraphQL API"]
end
OUTPUT -->|"Download Artifact"| ANALYZE
ANALYZE -->|"✓ Approved"| SafeJobs
ANALYZE -->|"✗ Blocked"| BLOCKED["Workflow Fails"]
ISSUE --> API
COMMENT --> API
PR --> API
LABEL --> API
```
Tip
The SafeOutputs subsystem provides security by design: the agent never requires write permissions because all write operations are performed by separate, validated jobs with minimal scoped permissions.
## Agent Workflow Firewall (AWF)
[Section titled “Agent Workflow Firewall (AWF)”](#agent-workflow-firewall-awf)
The Agent Workflow Firewall (AWF) containerizes the agent, binds it to a Docker network, and uses iptables to redirect HTTP/HTTPS traffic through a Squid proxy container. The Squid proxy controls the agent’s egress traffic via a configurable domain allowlist to prevent data exfiltration and restrict compromised agents to permitted domains. The AWF setup process drops its iptables capabilities before launching the agent.
Containerizing an agent improves security by limiting its access to the host, but this may come at a cost. In particular, many coding agents expect full access to the host and break if containerized naively. To support agents that need more access to the host, AWF provides a more permissive ‘chroot mode’ that mounts a subset of host system directories read-only under ‘/host’, mounts the host’s HOME and ‘/tmp’ directories read-write, imports a subset of host environment variables like USER and PATH, and then launches the agent in a ‘/host’ chroot jail. This allows the agent to safely use host-installed binaries (Python, Node.js, Go, etc.) from their normal paths, while controlling access to the host network, environment variables, and other sensitive resources.
Thus, AWF separates two concerns:
* **Filesystem**: Controlled access to host binaries and runtimes via chroot
* **Network**: All traffic routed through proxy enforcing the domain allowlist
```
flowchart TB
subgraph Agent["AI Agent Process"]
COPILOT["Copilot CLI"]
WEB["WebFetch Tool"]
SEARCH["WebSearch Tool"]
end
subgraph Firewall["Agent Workflow Firewall (AWF)"]
WRAP["Process Wrapper"]
ALLOW["Domain Allowlist"]
LOG["Activity Logging"]
WRAP --> ALLOW
ALLOW --> LOG
end
subgraph Network["Network Layer"]
direction TB
ALLOWED_OUT["✓ Allowed Domains"]
BLOCKED_OUT["✗ Blocked Domains"]
end
subgraph Ecosystems["Ecosystem Bundles"]
direction TB
DEFAULTS["defaults certificates, JSON schema"]
PYTHON["python PyPI, Conda"]
NODE["node npm, npmjs.com"]
CUSTOM["Custom Domains api.example.com"]
end
COPILOT --> WRAP
WEB --> WRAP
SEARCH --> WRAP
ALLOW --> ALLOWED_OUT
ALLOW --> BLOCKED_OUT
DEFAULTS --> ALLOW
PYTHON --> ALLOW
NODE --> ALLOW
CUSTOM --> ALLOW
ALLOWED_OUT --> INTERNET[" Internet"]
BLOCKED_OUT --> DROP[" Dropped"]
```
**Configuration Example:**
```yaml
engine: copilot
network:
firewall: true
allowed:
- defaults # Basic infrastructure
- python # PyPI ecosystem
- node # npm ecosystem
- "api.example.com" # Custom domain
```
## MCP Gateway and Firewall Integration
[Section titled “MCP Gateway and Firewall Integration”](#mcp-gateway-and-firewall-integration)
When the MCP gateway is enabled, it operates in conjunction with AWF to ensure that MCP traffic remains contained within trusted boundaries. The gateway spawns isolated containers for MCP servers while AWF mediates all network egress, ensuring that agent-to-server communication traverses only approved channels.
```
flowchart LR
subgraph Host["Host machine"]
GATEWAY["gh-aw-mcpg\nDocker container\nHost port 80 maps to container port 8000"]
GH_MCP["GitHub MCP Server\nspawned via Docker socket"]
GATEWAY -->|"spawns"| GH_MCP
end
subgraph AWFNet["AWF network namespace"]
AGENT["Agent container\nCopilot CLI + MCP client\n172.30.0.20"]
PROXY["Squid proxy\n172.30.0.10"]
end
AGENT -->|"CONNECT host.docker.internal:80"| PROXY
PROXY -->|"allowed domain\n(host.docker.internal)"| GATEWAY
GATEWAY -->|"forwards to"| GH_MCP
```
**Architecture Summary**
1. AWF establishes an isolated network with a Squid proxy that enforces the workflow `network.allowed` list.
2. The agent container can only egress through Squid. To reach the gateway, it uses `host.docker.internal:80` (Docker’s host alias). This hostname must be included in the firewall’s allowed list.
3. The `gh-aw-mcpg` container publishes host port 80 mapped to container port 8000. It uses the Docker socket to spawn MCP server containers.
4. All MCP traffic remains within the host boundary: AWF restricts egress, and the gateway routes requests to sandboxed MCP servers.
5. When supported by an agent, AWF creates a trusted `api-proxy` that routes model traffic on the agent’s behalf while keeping that traffic behind AWF’s network controls. This proxy should not be treated as a separate caller-authentication boundary for arbitrary code already running inside the agent container.
## MCP Server Sandboxing
[Section titled “MCP Server Sandboxing”](#mcp-server-sandboxing)
MCP servers execute within isolated containers, enforcing substrate-level separation between the agent and each server instance. Tool filtering at the configuration level restricts which operations each server may expose, limiting the attack surface available to a compromised agent. This isolation ensures that even if an MCP server is compromised, it cannot access the memory or state of other components.
```
flowchart TB
subgraph Agent["AI Agent"]
ENGINE["AI Engine (Copilot, Claude, Codex)"]
end
subgraph MCPLayer["MCP Server Layer"]
direction TB
subgraph GitHub["GitHub MCP"]
GH_TOOLS["Enabled Tools: • issue_read • list_commits • search_code"]
GH_BLOCKED["Blocked Tools: • delete_repository • update_branch_protection"]
end
subgraph Custom["Custom MCP (Docker)"]
CONTAINER[" Isolated Container"]
NET["Network Allowlist"]
ENV["Env Var Injection"]
end
subgraph HTTP["HTTP MCP"]
ENDPOINT["HTTPS Endpoint"]
HEADERS["Secure Headers"]
end
end
subgraph Toolfilter["Tool Filtering"]
ALLOWED["allowed: [tool1, tool2]"]
DENIED["✗ Unlisted tools blocked"]
end
ENGINE <-->|"stdio/HTTP"| GitHub
ENGINE <-->|"stdio"| CONTAINER
ENGINE <-->|"HTTP"| ENDPOINT
ALLOWED --> GH_TOOLS
ALLOWED --> GH_BLOCKED
CONTAINER --> NET
CONTAINER --> ENV
ENDPOINT --> HEADERS
```
**Isolation Properties:**
* **Container Isolation**: Custom MCP servers run in Docker containers with no shared state
* **Network Controls**: Per-container domain allowlists enforced via Squid proxy
* **Tool Allowlisting**: Explicit `allowed:` lists restrict available operations
* **Secret Injection**: Secrets are passed via environment variables, never in configuration files
## Threat Detection Pipeline
[Section titled “Threat Detection Pipeline”](#threat-detection-pipeline)
The threat detection job is a sub-stage within the SafeOutputs subsystem. After the agent job completes and its outputs are buffered as artifacts, a separate detection job downloads these artifacts and invokes a prompted AI agent to analyze them for suspicious content. This detection agent operates with a security-focused system prompt and examines the agent’s outputs, patches, and execution context. The detection job runs in isolation from the original agent and has no access to write permissions; its sole responsibility is to emit a pass/fail verdict that gates the subsequent safe output jobs.
Detection checks include identification of secret leakage, malicious code patterns, and policy violations. If the detection agent identifies threats, the workflow terminates before any writes are externalized. Workflow authors can customize detection behavior by providing additional detection prompts or integrating external security scanners.
```
flowchart TB
subgraph Input["SafeOutputs Artifacts"]
JSON[/"agent_output.json (Buffered actions)"/]
PATCH[/"aw.patch (Git diff from agent)"/]
PROMPT[/"prompt.txt (Original workflow context)"/]
end
subgraph DetectionJob["Threat Detection Job"]
direction TB
DOWNLOAD["Download artifacts"]
AGENT["Detection Agent (Security-focused prompt)"]
subgraph Checks["Analysis Targets"]
SECRETS["Secret Leaks API keys, tokens Credentials in outputs"]
MALICIOUS["Malicious Patches Backdoors, vulnerabilities Suspicious modifications"]
POLICY["Policy Violations Scope violations Unauthorized operations"]
end
CUSTOM["Custom Detection Steps"]
end
subgraph Verdict["Verdict"]
SAFE_CHECK{{"Threats Detected?"}}
end
subgraph Outcome["Outcome"]
PROCEED["✓ Safe output jobs proceed"]
BLOCK["✗ Workflow fails No writes externalized"]
end
JSON --> DOWNLOAD
PATCH --> DOWNLOAD
PROMPT --> DOWNLOAD
DOWNLOAD --> AGENT
AGENT --> Checks
Checks --> CUSTOM
CUSTOM --> SAFE_CHECK
SAFE_CHECK -->|"No"| PROCEED
SAFE_CHECK -->|"Yes"| BLOCK
```
**Detection Job Properties:**
* **Isolated Execution**: The detection agent runs in a separate job with no write permissions and no access to the original agent’s runtime state
* **Prompted Analysis**: Detection uses the same AI engine as the workflow, but with a security-focused system prompt that instructs the agent to identify threats
* **Artifact-Based**: The detection agent only sees the buffered artifacts (outputs, patches, context), not live repository state
* **Blocking Verdict**: The detection job must complete successfully and emit a “safe” verdict before any safe output jobs execute
**Detection Mechanisms:**
* **AI Detection**: Default AI-powered analysis using the workflow engine with a security-focused detection prompt
* **Custom Steps**: Integration with security scanners (Semgrep, TruffleHog, LlamaGuard) via `threat-detection.steps` configuration
* **Custom Prompts**: Domain-specific detection instructions for specialized threat models via `threat-detection.prompt` configuration
**Configuration Example:**
```yaml
threat-detection:
prompt: |
Additionally check for:
- References to internal infrastructure URLs
- Attempts to modify CI/CD configuration files
- Changes to security-sensitive files (.github/workflows, package.json scripts)
steps:
- name: Run TruffleHog
run: trufflehog filesystem /tmp/gh-aw --only-verified
- name: Run Semgrep
run: semgrep scan /tmp/gh-aw/aw.patch --config=auto
```
## Compilation-Time Security
[Section titled “Compilation-Time Security”](#compilation-time-security)
AW enforces security constraints at compilation time through schema validation, expression allowlisting, and action pinning. The trusted compiler validates declarative configuration artifacts before they are deployed, rejecting misconfigurations and overly permissive specifications. This layer constrains what components may be loaded and how they may be connected, but it does not constrain runtime behavior.
```
flowchart TB
subgraph Source["Source Files"]
MD[/"workflow.md"/]
IMPORTS[/"imports/*.md"/]
end
subgraph Validation["Schema & Expression Validation"]
SCHEMA["JSON Schema Validation • Valid frontmatter fields • Correct types & formats"]
EXPR["Expression Safety • Allowlisted expressions only • No secrets in expressions"]
end
subgraph Pinning["Action Pinning"]
SHA["SHA Resolution actions/checkout@sha # v4"]
CACHE[/"actions-lock.json (Cached SHAs)"/]
end
subgraph Scanners["Security Scanners"]
ACTIONLINT["actionlint Workflow linting (includes shellcheck & pyflakes)"]
ZIZMOR["zizmor Security vulnerabilities Privilege escalation"]
POUTINE["poutine Supply chain risks Third-party actions"]
end
subgraph Strict["Strict Mode Enforcement"]
PERMS["✗ No write permissions"]
NETWORK["✓ Explicit network config"]
WILDCARD["✗ No wildcard domains"]
DEPRECATED["✗ No deprecated fields"]
end
subgraph Output["Compilation Output"]
LOCK[/".lock.yml (Validated Workflow)"/]
ERROR["✗ Compilation Error"]
end
MD --> SCHEMA
IMPORTS --> SCHEMA
SCHEMA --> EXPR
EXPR --> SHA
SHA <--> CACHE
SHA --> ACTIONLINT
ACTIONLINT --> ZIZMOR
ZIZMOR --> POUTINE
POUTINE --> Strict
Strict -->|"All Checks Pass"| LOCK
Strict -->|"Violation Found"| ERROR
```
**Compilation Commands:**
```bash
# Generate the lock file from the workflow frontmatter, which includes schema validation,
# expression safety checks, action pinning, and security scanning
gh aw compile
# Enable added security scanners for additional validation
gh aw compile --actionlint --zizmor --poutine
```
## Content Sanitization
[Section titled “Content Sanitization”](#content-sanitization)
User-generated content is sanitized before being passed to the agent. The sanitization pipeline applies a series of transformations to normalize potentially problematic content. This mechanism operates at the activation stage boundary, ensuring that untrusted input is processed before it is passed to the agent.
```
flowchart LR
subgraph Raw["Raw Event Content"]
TITLE["Issue Title"]
BODY["Issue/PR Body"]
COMMENT["Comment Text"]
end
subgraph Sanitization["Content Sanitization Pipeline"]
direction TB
MENTIONS["@mention Neutralization @user → `@user`"]
BOTS["Bot Trigger Protection fixes #123 → `fixes #123`"]
XML["XML/HTML Tag Conversion <script> → (script)"]
URI["URI Filtering Only HTTPS from trusted domains"]
SPECIAL["Special Character Handling Unicode normalization"]
LIMIT["Content Limits 0.5MB max, 65k lines"]
CONTROL["Control Character Removal ANSI escapes stripped"]
end
subgraph Safe["Sanitized Output"]
SAFE_TEXT["needs.activation.outputs.text ✓ Safe for AI consumption"]
end
TITLE --> MENTIONS
BODY --> MENTIONS
COMMENT --> MENTIONS
MENTIONS --> BOTS
BOTS --> XML
XML --> URI
URI --> SPECIAL
SPECIAL --> LIMIT
LIMIT --> CONTROL
CONTROL --> SAFE_TEXT
```
**Sanitization Properties:**
| Mechanism | Input | Output | Protection |
| --------------------------- | ------------------ | ------------------ | --------------------------------------- |
| **@mention Neutralization** | `@user` | `` `@user` `` | Prevents unintended user notifications |
| **Bot Trigger Protection** | `fixes #123` | `` `fixes #123` `` | Prevents automatic issue linking |
| **XML/HTML Tag Conversion** | ` → (script)alert('xss')(/script)
→ (img src=x onerror=...)
→ (!-- hidden comment --)
```
## Integrity Filtering
[Section titled “Integrity Filtering”](#integrity-filtering)
Integrity filtering controls which GitHub content an agent can access during a workflow run, based on **author trust** and **merge status** rather than push access alone. The MCP gateway intercepts tool calls and filters content below the configured `min-integrity` threshold before the AI engine sees it — items from blocked users or below the minimum trust level are removed transparently.
For public repositories, `min-integrity: approved` is applied automatically — restricting content to owners, members, and collaborators — even without additional authentication. The four configurable levels (`merged`, `approved`, `unapproved`, `none`) are cumulative from most to least restrictive. Individual users can be blocked unconditionally, and trusted reviewers can promote specific items via approval labels.
See [Integrity Filtering Reference](/gh-aw/reference/integrity/) for configuration options, integrity levels, and examples.
## Secret Redaction
[Section titled “Secret Redaction”](#secret-redaction)
Before workflow artifacts are uploaded, all files in the `/tmp/gh-aw` directory are scanned for secret values and redacted. This mechanism prevents accidental credential leakage through logs, outputs, or artifacts. Secret redaction executes unconditionally (with `if: always()`), ensuring that secrets are protected even if the workflow fails at an earlier stage.
```
flowchart LR
subgraph Sources["Secret Sources"]
YAML["Workflow YAML"]
ENV["Environment Variables"]
MCP_CONF["MCP Server Config"]
end
subgraph Collection["Secret Collection"]
SCAN["Scan for secrets.* patterns"]
EXTRACT["Extract secret names: SECRET_NAME_1 SECRET_NAME_2"]
end
subgraph Redaction["Secret Redaction Step"]
direction TB
FIND["Find files in /tmp/gh-aw (.txt, .json, .log, .md, .yml)"]
MATCH["Match exact secret values"]
REPLACE["Replace with masked value: abc***** (first 3 chars + asterisks)"]
end
subgraph Output["Safe Artifacts"]
LOGS["Redacted Logs"]
JSON_OUT["Sanitized JSON"]
PROMPT["Clean Prompt Files"]
end
YAML --> SCAN
ENV --> SCAN
MCP_CONF --> SCAN
SCAN --> EXTRACT
EXTRACT --> FIND
FIND --> MATCH
MATCH --> REPLACE
REPLACE --> LOGS
REPLACE --> JSON_OUT
REPLACE --> PROMPT
```
**Redaction Properties:**
* **Automatic Detection**: Scans workflow YAML for `secrets.*` patterns and collects all secret references
* **Exact String Matching**: Uses safe string matching (not regex) to prevent injection attacks
* **Partial Visibility**: Displays first 3 characters followed by asterisks for debugging without exposing full secrets
* **Custom Masking**: Supports additional custom secret masking steps via `secret-masking:` configuration
**Configuration Example:**
```yaml
secret-masking:
steps:
- name: Redact custom patterns
run: |
find /tmp/gh-aw -type f -exec sed -i 's/password123/REDACTED/g' {} +
```
Secret redaction executes with `if: always()` to ensure secrets are never leaked, even if the workflow fails at an earlier stage.
## Job Execution Flow
[Section titled “Job Execution Flow”](#job-execution-flow)
Workflow execution follows a strict dependency order that enforces security checks at each stage boundary. The plan-level decomposition ensures that each stage has explicit inputs and outputs, and that transitions between stages are mediated by validation steps.
```
flowchart TB
subgraph PreActivation["Pre-Activation Job"]
ROLE["Role Permission Check"]
DEADLINE["Stop-After Deadline"]
SKIP["Skip-If-Match Check"]
COMMAND["Command Position Validation"]
end
subgraph Activation["Activation Job"]
CONTEXT["Prepare Workflow Context"]
SANITIZE["Sanitize Event Text"]
LOCK_CHECK["Validate Lock File"]
end
subgraph Agent["Agent Job"]
CHECKOUT["Repository Checkout"]
RUNTIME["Runtime Setup (Node.js, Python)"]
CACHE_RESTORE["Cache Restore"]
MCP_START["Start MCP Containers"]
PROMPT["Generate Prompt"]
EXECUTE["Execute AI Engine"]
REDACT[" Secret Redaction"]
UPLOAD["Upload Output Artifact"]
CACHE_SAVE["Save Cache"]
end
subgraph Detection["Detection Job"]
DOWNLOAD_DETECT["Download Artifact"]
ANALYZE["AI + Custom Analysis"]
VERDICT["Security Verdict"]
end
subgraph SafeOutputs["Safe Output Jobs"]
CREATE_ISSUE["create_issue"]
ADD_COMMENT["add_comment"]
CREATE_PR["create_pull_request"]
end
subgraph Conclusion["Conclusion Job"]
AGGREGATE["Aggregate Results"]
SUMMARY["Generate Summary"]
end
ROLE --> DEADLINE
DEADLINE --> SKIP
SKIP --> COMMAND
COMMAND -->|"✓ Pass"| CONTEXT
COMMAND -->|"✗ Fail"| SKIP_ALL["Skip All Jobs"]
CONTEXT --> SANITIZE
SANITIZE --> LOCK_CHECK
LOCK_CHECK --> CHECKOUT
CHECKOUT --> RUNTIME
RUNTIME --> CACHE_RESTORE
CACHE_RESTORE --> MCP_START
MCP_START --> PROMPT
PROMPT --> EXECUTE
EXECUTE --> REDACT
REDACT --> UPLOAD
UPLOAD --> CACHE_SAVE
CACHE_SAVE --> DOWNLOAD_DETECT
DOWNLOAD_DETECT --> ANALYZE
ANALYZE --> VERDICT
VERDICT -->|"✓ Safe"| CREATE_ISSUE
VERDICT -->|"✓ Safe"| ADD_COMMENT
VERDICT -->|"✓ Safe"| CREATE_PR
VERDICT -->|"✗ Threat"| BLOCK_ALL["Block All Safe Outputs"]
CREATE_ISSUE --> AGGREGATE
ADD_COMMENT --> AGGREGATE
CREATE_PR --> AGGREGATE
AGGREGATE --> SUMMARY
```
## Observability
[Section titled “Observability”](#observability)
AW provides comprehensive observability through GitHub Actions runs and artifacts. Workflow artifacts preserve prompts, outputs, patches, and logs for post-hoc analysis. This observability layer supports debugging, security auditing, and cost monitoring without compromising runtime isolation.
```
flowchart TB
subgraph Workflow["Workflow Execution"]
RUN["GitHub Actions Run"]
JOBS["Job Logs"]
STEPS["Step Outputs"]
end
subgraph Artifacts["Workflow Artifacts"]
AGENT_OUT[/"agent_output.json AI decisions & actions"/]
PROMPT[/"prompt.txt Generated prompts"/]
PATCH[/"aw.patch Code changes"/]
LOGS[/"engine logs Token usage & timing"/]
FIREWALL[/"firewall logs Network requests"/]
end
subgraph CLI["CLI Tools"]
AW_LOGS["gh aw logs Download & analyze runs"]
AW_AUDIT["gh aw audit Investigate failures"]
AW_STATUS["gh aw status Workflow health"]
end
subgraph Insights["Observability Insights"]
COST[" Cost Tracking Token usage per run"]
DEBUG[" Debugging Step-by-step trace"]
SECURITY[" Security Audit Network & tool access"]
PERF[" Performance Duration & bottlenecks"]
end
RUN --> JOBS
JOBS --> STEPS
STEPS --> Artifacts
AGENT_OUT --> AW_LOGS
PROMPT --> AW_LOGS
PATCH --> AW_AUDIT
LOGS --> AW_LOGS
FIREWALL --> AW_AUDIT
AW_LOGS --> COST
AW_LOGS --> PERF
AW_AUDIT --> DEBUG
AW_AUDIT --> SECURITY
AW_STATUS --> DEBUG
```
**Observability Properties:**
* **Artifact Preservation**: All workflow outputs (prompts, patches, logs) are saved as downloadable artifacts
* **Cost Monitoring**: Token usage and costs across workflow runs are tracked via `gh aw logs`
* **Failure Analysis**: Failed runs can be investigated with `gh aw audit` to examine prompts, errors, and network activity
* **Firewall Logs**: All network requests made by the agent are logged for security auditing
* **Step Summaries**: Rich markdown summaries in GitHub Actions display agent decisions and outputs
**CLI Commands for Observability:**
```bash
# Download and analyze workflow run logs
gh aw logs
# Investigate a specific workflow run
gh aw audit
# Check workflow health and status
gh aw status
```
## Security Layers Summary
[Section titled “Security Layers Summary”](#security-layers-summary)
| Layer | Mechanism | Protection Against |
| ----------------- | ----------------------------------------------- | ----------------------------------------------------------- |
| **Substrate** | GitHub Actions runner (VM, kernel, hypervisor) | Memory corruption, privilege escalation, host escape |
| **Substrate** | Docker container runtime | Process isolation bypass, shared state access |
| **Substrate** | AWF network controls (iptables) | Data exfiltration, unauthorized API calls |
| **Substrate** | MCP sandboxing (container isolation) | Container escape, unauthorized tool access |
| **Configuration** | Schema validation, expression allowlist | Invalid configurations, unauthorized expressions |
| **Configuration** | Action SHA pinning | Supply chain attacks, tag hijacking |
| **Configuration** | Security scanners (actionlint, zizmor, poutine) | Privilege escalation, misconfigurations, supply chain risks |
| **Configuration** | Pre-activation checks (role/permission) | Unauthorized users, expired workflows |
| **Plan** | Integrity filtering (`min-integrity`) | Untrusted user input, context poisoning, social engineering |
| **Plan** | Content sanitization | @mention abuse, bot triggers |
| **Plan** | Secret redaction | Credential leakage in logs/artifacts |
| **Plan** | Threat detection | Malicious patches, secret leaks |
| **Plan** | Permission separation (SafeOutputs) | Direct write access abuse |
| **Plan** | Output sanitization | Content injection, XSS |
| **Plan** | Artifact preservation, CLI tools | Debugging failures, auditing security, cost tracking |
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Integrity Filtering](/gh-aw/reference/integrity/) - Author-trust and merge-status content filtering
* [Threat Detection Guide](/gh-aw/reference/threat-detection/) - Configuring threat analysis
* [Network Permissions](/gh-aw/reference/network/) - Network access control
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Output processing configuration
* [AI Engines](/gh-aw/reference/engines/) - Engine-specific security features
* [Compilation Process](/gh-aw/reference/compilation-process/) - Build-time security validation
* [CLI Commands](/gh-aw/setup/cli/) - Workflow management and observability tools
# How They Work
> Understanding the core concepts and architecture of GitHub Agentic Workflows, from compilation to execution
GitHub Agentic Workflows hosts coding agents in [GitHub Actions](https://docs.github.com/en/actions), to perform complex, multi-step tasks automatically. This enables [Continuous AI](https://githubnext.com/projects/continuous-ai) - systematic, automated application of AI to software collaboration.
## Workflow Structure
[Section titled “Workflow Structure”](#workflow-structure)
Each workflow contains [frontmatter](/gh-aw/reference/glossary/#frontmatter) (the YAML configuration section between `---` markers) and markdown instructions. The frontmatter defines [triggers](/gh-aw/reference/triggers/) (when the workflow runs), [permissions](/gh-aw/reference/permissions/) (what it can access), and [tools](/gh-aw/reference/tools/) (what capabilities the AI has), while the markdown contains natural language task descriptions. This declarative structure enables reliable, secure agentic programming by sandboxing AI capabilities and triggering at the right moments.
```aw
---
on: ...
permissions: ...
tools: ...
---
# Natural Language Instructions
Analyze this issue and provide helpful triage comments...
```
## AI Engines
[Section titled “AI Engines”](#ai-engines)
Workflows support **GitHub Copilot** (default), **Claude by Anthropic**, and **Codex**. Each [engine](/gh-aw/reference/engines/) (AI model/provider) interprets natural language instructions and executes them using configured tools and permissions.
## Tools and Model Context Protocol (MCP)
[Section titled “Tools and Model Context Protocol (MCP)”](#tools-and-model-context-protocol-mcp)
Workflows use [tools](/gh-aw/reference/tools/) through the **[Model Context Protocol](/gh-aw/reference/glossary/#mcp-model-context-protocol)** (MCP, a standardized protocol for connecting AI agents to external tools and services) for GitHub operations, external APIs, file operations, and custom integrations.
## Agentic vs. Traditional Workflows
[Section titled “Agentic vs. Traditional Workflows”](#agentic-vs-traditional-workflows)
**Traditional workflows** execute pre-programmed steps with fixed if/then logic. They do exactly what you tell them, every time, in the same way.
**[Agentic workflows](/gh-aw/reference/glossary/#agentic)** (workflows that have agency-the ability to make autonomous decisions) use AI to understand context, make decisions, and generate content by interpreting natural language instructions flexibly. They combine deterministic GitHub Actions infrastructure with AI-driven decision-making, adapting their behavior based on the specific situation they encounter.
## Security Design
[Section titled “Security Design”](#security-design)
Agentic workflows implement a defense-in-depth security architecture that protects against prompt injection, rogue MCP servers, and malicious agents. The architecture operates across multiple layers: compilation-time validation, runtime isolation, permission separation, network controls, and output sanitization.
```
flowchart LR
INPUT[" Input"] --> COMPILE[" Compile"]
COMPILE --> RUNTIME[" Runtime"]
RUNTIME --> ISOLATION[" Isolation"]
ISOLATION --> OUTPUT[" Output"]
OUTPUT --> ACTIONS["✓ Actions"]
```
Workflows run with minimal permissions (no write access by default), use tool allowlists, and process outputs through a [safety layer](/gh-aw/introduction/architecture/) before applying changes. Critical actions can require human approval. For detailed security documentation, see the [Security Architecture](/gh-aw/introduction/architecture/) page.
## MCP Scripts and Safe Outputs
[Section titled “MCP Scripts and Safe Outputs”](#mcp-scripts-and-safe-outputs)
* **[MCP Scripts](/gh-aw/reference/mcp-scripts/)** (custom inline tools) - Custom MCP tools defined inline in workflow frontmatter
* **[Safe outputs](/gh-aw/reference/safe-outputs/)** (validated GitHub operations) - Pre-approved actions the AI can request without write permissions
## Regenerating the Lock File
[Section titled “Regenerating the Lock File”](#regenerating-the-lock-file)
Use `gh aw compile` to generate [`.lock.yml` files](/gh-aw/reference/glossary/#workflow-lock-file-lockyml) from the frontmatter of the workflow `.md` files. The `.md` file is the editable source of truth, while `.lock.yml` is the compiled GitHub Actions workflow with security hardening. Commit both files.
## Continuous AI Patterns
[Section titled “Continuous AI Patterns”](#continuous-ai-patterns)
Enable [Continuous AI](https://githubnext.com/projects/continuous-ai) patterns like keeping documentation current, improving code quality incrementally, intelligently triaging issues and PRs, and automating code review.
## Best Practices
[Section titled “Best Practices”](#best-practices)
Start simple and iterate with clear, specific instructions. Test workflows using `gh aw compile --watch` and `gh aw run`, monitor costs with `gh aw logs`, and review AI-generated content before merging. Use [`safe outputs`](/gh-aw/reference/safe-outputs/) (pre-approved GitHub operations) for controlled creation of issues, comments, and PRs.
# About Workflows
> Understanding how GitHub Agentic Workflows transforms natural language into automated AI-powered workflows
## What are Agentic Workflows?
[Section titled “What are Agentic Workflows?”](#what-are-agentic-workflows)
**[Agentic workflows](/gh-aw/reference/glossary/#agentic-workflow)** are AI-powered automation that can understand context, make decisions, and take meaningful actions-all from natural language instructions you write in markdown.
Unlike traditional automation with fixed if-then rules, agentic workflows use coding agents (like Copilot CLI, Claude by Anthropic, or Codex) to:
* **Understand context**: Read your repository, issues, and pull requests to grasp the current situation
* **Make decisions**: Choose appropriate actions based on the context, not just predefined conditions
* **Adapt behavior**: Respond flexibly to different scenarios without requiring explicit programming for each case
## Coding agents, running with tools, in GitHub Actions
[Section titled “Coding agents, running with tools, in GitHub Actions”](#coding-agents-running-with-tools-in-github-actions)
With coding agents, you describe your automation needs in plain language. GitHub Agentic Workflows makes this possible by running natural language markdown files as agents in [GitHub Actions](https://github.com/features/actions) that are executed by AI coding agents (AI systems that execute your instructions).
Instead of writing intricate scripts to handle issue triage, code reviews, or release management, you simply describe what you want to happen. The AI agent understands your repository context, interprets the situation, and takes appropriate actions-all from a few lines of markdown.
Here’s a simple example:
```markdown
---
on: # Trigger: when to run
issues:
types: [opened]
permissions: read-all # Security: read-only by default
safe-outputs: # Allowed write operations
add-comment:
---
# Issue Clarifier
Analyze the current issue and ask for additional details if the issue is unclear.
```
The YAML section at the top is called [**frontmatter**](/gh-aw/reference/frontmatter/)-it configures when the workflow runs and what it can do. The markdown body contains your natural language instructions. See [Workflow Structure](/gh-aw/reference/workflow-structure/) for details.
The `gh aw compile` command this markdown file into a hardened [GitHub Actions Workflow](https://docs.github.com/en/actions/concepts/workflows-and-actions/workflows#about-workflows) [`.lock.yml` file](/gh-aw/reference/glossary/#workflow-lock-file-lockyml) (the compiled workflow that GitHub Actions runs) that embeds the frontmatter and loads the markdown body at runtime. This runs an AI agent in a containerized environment whenever a new issue is opened.
[Compilation](/gh-aw/reference/glossary/#compilation) (converting markdown to GitHub Actions YAML) validates your configuration, applies security hardening, and generates the final workflow file that GitHub Actions can execute. Think of it like compiling code-you write human-friendly markdown, the compiler produces machine-ready YAML.
The AI agent reads your repository context, understands the issue content, and takes appropriate actions - all defined in natural language rather than complex code.
Workflows use read-only permissions by default, with write operations only allowed through sanitized [`safe-outputs`](/gh-aw/reference/safe-outputs/) (validated GitHub operations) that enable creating issues, comments, and PRs without giving the AI direct write access. Access can be gated to team members only, ensuring AI agents operate within controlled boundaries.
More sample workflows can be found in the [Agentics collection](https://github.com/githubnext/agentics).
# Presentation Slides
> View the GitHub Agentic Workflows presentation slides
View the GitHub Agentic Workflows presentation slides to learn about the evolution from CI/CD to Continuous AI, how agentic workflows enable AI automation in natural language, security features, and real-world examples.
[Open Slides](/gh-aw/slides/)
[Download PDF](/gh-aw/slides/github-agentic-workflows.pdf)
## Walkthroughs
[Section titled “Walkthroughs”](#walkthroughs)
### DeepResearch
[Section titled “DeepResearch”](#deepresearch)
* DeepResearch
* Discussion Miner
*
* Issue Monster
* Copilot
### Version Updater
[Section titled “Version Updater”](#version-updater)
*
* Issue Monster
* Copilot
### Workflow Skill Extractor
[Section titled “Workflow Skill Extractor”](#workflow-skill-extractor)
* Report
* Plan (Human)
* Copilot
### Agent Persona Exploration
[Section titled “Agent Persona Exploration”](#agent-persona-exploration)
* Persona Simulator
* Plan
* Issue Monster
* Copilot
### Q - the Agent optimizer
[Section titled “Q - the Agent optimizer”](#q---the-agent-optimizer)
*
*
### Multi Resolution Web Tester
[Section titled “Multi Resolution Web Tester”](#multi-resolution-web-tester)
*
*
### Release notes
[Section titled “Release notes”](#release-notes)
*
### Issues as Spec
[Section titled “Issues as Spec”](#issues-as-spec)
* Community
* Copilot
### Report Assign Fix
[Section titled “Report Assign Fix”](#report-assign-fix)
* AW self reported failure
* Copilot
# CentralRepoOps
> Operate and roll out changes across many repositories from a single private control repository.
Caution
**Experimental:** CentralRepoOps is still experimental! Things may break, change, or be removed without deprecation at any time.
CentralRepoOps is a [MultiRepoOps](/gh-aw/patterns/multi-repo-ops/) deployment variant where a single private repository acts as a control plane for large-scale operations across many repositories.
Use this pattern for organization-wide rollouts, phased adoption (pilot waves first), central governance, and security-aware prioritization across tens or hundreds of repositories. Each orchestrator run delivers consistent policy gates, controlled fan-out (`max`), and a complete decision trail — without pushing `main` changes to individual target repositories.
## Example: Dependabot Rollout (Orchestrator + Worker)
[Section titled “Example: Dependabot Rollout (Orchestrator + Worker)”](#example-dependabot-rollout-orchestrator--worker)
This pattern maps directly to your Dependabot rollout pair:
* `dependabot-rollout-orchestrator.md` decides *where* to roll out next.
* `dependabot-rollout.md` executes *how* to configure each target repository.
### Orchestrator (central control)
[Section titled “Orchestrator (central control)”](#orchestrator-central-control)
Let’s say you want to roll out a new Dependabot configuration across 100 repositories. This example shows you how to do this based on a small subset.
Navigate to your central repository and create a workflow file `.github/workflows/dependabot-rollout-orchestrator.md` with the following contents:
```aw
---
on:
schedule:
- cron: '0 9 * * 1'
tools:
github:
github-token: ${{ secrets.GH_AW_READ_ORG_TOKEN }}
toolsets: [repos]
safe-outputs:
dispatch-workflow:
workflows: [dependabot-rollout]
max: 5
---
# Dependabot Rollout Orchestrator
Categorize and orchestrate Dependabot rollout across repositories.
**Target repos**: All repos in the organization
## Task
1. **Filter** - Parse repos (from input or variable), check each for existing `.github/dependabot.yml`, keep only repos without it
2. **Categorize** - Read repo contents to assess complexity:
- Simple: Single package.json, <50 dependencies, standard structure
- Complex: Multiple package.json files, >100 deps, or multiple ecosystems
- Conflicting: Has Renovate config or custom update scripts
- Security: Open security alerts or public with dependencies
3. **Prioritize** - Order repos by rollout preference: simple → security → complex → conflicting
4. **Dispatch** - Dispatch `dependabot-rollout` worker for every prioritized repository
5. **Summarize** - Report total candidates, categorization breakdown, selected repos with rationale
```
Compile this workflow to generate the lock file: `gh aw compile`. Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new?name=GH_AW_READ_ORG_TOKEN\&description=GitHub+Agentic+Workflows+-+Org+read+access\&contents=read) `GH_AW_READ_ORG_TOKEN` (this link pre-fills the token name, description, and Contents: Read permission) with the organization as an owner, select “All repositories” (or allowlist of specific repos), and grant Repository permission: `Contents: Read-only`. Add this into your Actions repository secrets. This gives the orchestrator read access to all candidate repositories.
### Worker (cross-repository execution)
[Section titled “Worker (cross-repository execution)”](#worker-cross-repository-execution)
Next, create the worker workflow `.github/workflows/dependabot-rollout.md` in your central repository that will operate on each target repository via checkout:
````aw
---
on:
workflow_dispatch:
inputs:
target_repo:
description: 'Target repository (owner/repo format)'
required: true
type: string
run-name: Dependabot rollout for ${{ github.event.inputs.target_repo }}
concurrency:
group: gh-aw-${{ github.workflow }}-${{ github.event.inputs.target_repo }}
engine:
id: copilot
concurrency:
group: gh-aw-copilot-${{ github.workflow }}-${{ github.event.inputs.target_repo }}
checkout:
repository: ${{ github.event.inputs.target_repo }}
github-token: ${{ secrets.ORG_REPO_CHECKOUT_TOKEN }}
current: true
permissions:
contents: read
issues: read
pull-requests: read
tools:
github:
github-token: ${{ secrets.GH_AW_READ_ORG_TOKEN }}
toolsets: [repos]
safe-outputs:
github-token: ${{ secretsGH_AW_CROSS_REPO_PAT }}
create-pull-request:
target-repo: ${{ github.event.inputs.target_repo }}
title-prefix: '[dependabot] '
max: 1
create-issue:
target-repo: ${{ github.event.inputs.target_repo }}
title-prefix: '[dependabot-config] '
max: 1
---
# Intelligent Dependabot Configuration
You are creating a **customized** Dependabot configuration based on analyzing this specific repository.
**Target Repository**: ${{ github.event.inputs.target_repo }}
## Why AI is Required
You must analyze the repository structure and create an intelligent, customized configuration - not a generic template.
## Step 1: Analyze Repository
**Check for conflicts:**
- Does `.github/dependabot.yml` already exist? → Stop, create issue explaining it exists
- Does `.github/renovate.json` or `renovate.json` exist? → Create issue about migrating from Renovate
- Are there custom dependency update scripts? → Create issue suggesting Dependabot alternative
**Analyze package manager complexity:**
For **npm** (if package.json exists):
- Count total dependencies (dependencies + devDependencies)
- Check for monorepo: Are there multiple package.json files in subdirectories?
- Simple: <20 dependencies, single package.json
- Complex: >100 dependencies OR monorepo structure
For **Python** (requirements.txt, setup.py, pyproject.toml):
- Count dependencies
- Check for multiple requirement files
For **Go** (go.mod):
- Note if present
For **GitHub Actions** (.github/workflows/*.yml):
- Count workflow files
**Security context:**
- Use GitHub tools to check for open security alerts
- If critical alerts exist, prioritize security updates
## Step 2: Create Customized Configuration
Based on your analysis, create an appropriate config:
### Simple Repository (<20 npm deps, no monorepo)
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily" # Low complexity = more frequent
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
```
### Complex Repository (>100 deps OR security alerts)
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly" # High complexity = less frequent
groups:
production:
patterns: ["*"]
exclude-patterns: ["@types/*", "@jest/*"]
dev-dependencies:
patterns: ["@types/*", "@jest/*", "eslint*"]
```
### Monorepo (multiple package.json)
```yaml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/packages/frontend"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/packages/backend"
schedule:
interval: "weekly"
```
## Step 3: Deliver Configuration
**If config is straightforward (no Renovate conflict):**
- Create `.github/dependabot.yml` with your customized config
- Create pull request with:
- Title: "[dependabot] Add customized Dependabot configuration"
- Body explaining: dependency count, why weekly vs daily, grouping strategy, etc.
**If Renovate detected:**
- Create issue explaining migration benefits and proposed config
- Include generated config in issue body
**If no package managers found:**
- Create issue: "No supported package managers detected"
## Key: Explain Your Reasoning
In the PR/issue body, explain **why** you chose this specific configuration (not a generic template).
````
Compile this workflow to generate the lock file: `gh aw compile`. Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new?name=ORG_REPO_CHECKOUT_TOKEN\&description=GitHub+Agentic+Workflows+-+Checkout+token\&contents=write\&actions=write) `ORG_REPO_CHECKOUT_TOKEN` (this link pre-fills the token name, description, and permissions) with the organization as an owner, select “All repositories” (or allowlist of specific repos), and grant Repository permission: `Contents: Read & write`, `Actions: Read & write`. This allows the worker to check out the target repository.
Also create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new?name=REPO_SAFE_OUTPUTS_TOKEN\&description=GitHub+Agentic+Workflows+-+Safe+outputs+token\&contents=write\&issues=write\&pull_requests=write) `REPO_SAFE_OUTPUTS_TOKEN` (this link pre-fills the token name, description, and permissions) with the organization as an owner, select “All repositories” (or allowlist of specific repos), and grant Repository permission: `Contents: Write`, `Issues: Write`, `Pull Requests: Write`. This allows the worker to create pull requests and issues in the target repository based on the orchestrator’s instructions.
After the setup is complete, you can run the orchestrator with `workflow_dispatch` (`target_repos`) or let the schedule trigger run automatically.
## Richer Triggers with a Trigger File
[Section titled “Richer Triggers with a Trigger File”](#richer-triggers-with-a-trigger-file)
Embedding a `schedule:` trigger directly in the orchestrator is the simplest setup, but it limits the orchestrator to time-based execution only. A **trigger file** — a plain, hand-authored GitHub Actions workflow — solves this by separating the trigger definition from the agent logic:
* The compiled orchestrator exposes a `workflow_call` trigger.
* A stable, rarely-changing `.yml` file defines the actual GitHub events that kick off the run.
* The trigger file calls the compiled orchestrator via `workflow_call`, forwarding any inputs and secrets.
This means you can update when and why the orchestrator runs — reacting to a label, a repository push, a security alert, or a manual dispatch — without touching or recompiling the agentic workflow.
### Add `workflow_call` to the Orchestrator
[Section titled “Add workflow\_call to the Orchestrator”](#add-workflow_call-to-the-orchestrator)
Extend the orchestrator’s `on:` section with `workflow_call` and declare any inputs you want callers to pass:
```aw
---
on:
schedule: weekly on monday
workflow_call:
inputs:
reason:
description: "Why this run was triggered (label name, event type, etc.)"
type: string
default: "scheduled"
tools:
github:
github-token: ${{ secrets.GH_AW_READ_ORG_TOKEN }}
toolsets: [repos]
safe-outputs:
dispatch-workflow:
workflows: [dependabot-rollout]
max: 5
---
# Dependabot Rollout Orchestrator
...
```
Compile the workflow after adding `workflow_call`: `gh aw compile`.
### Create the Stable Trigger File
[Section titled “Create the Stable Trigger File”](#create-the-stable-trigger-file)
Add a plain GitHub Actions workflow alongside the compiled orchestrator. This file is written by hand, committed once, and rarely needs to change:
.github/workflows/central-ops-trigger.yml
```yaml
name: Central Ops Trigger
on:
# Trigger when a repository is labeled for Dependabot rollout
issues:
types: [labeled]
# Trigger on any push to main (e.g. config change)
push:
branches: [main]
# Allow manual runs with context
workflow_dispatch:
inputs:
reason:
description: "Reason for manual trigger"
required: false
default: "manual"
jobs:
trigger:
uses: ./.github/workflows/dependabot-rollout-orchestrator.lock.yml
with:
reason: ${{ github.event_name }}
secrets: inherit
```
Note
The trigger file references the compiled **lock file** (`*.lock.yml`), not the markdown source. Recompiling the orchestrator regenerates the lock file in place; the trigger file does not need to change.
Tip
Use `secrets: inherit` to forward all repository secrets to the called workflow automatically. If you prefer explicit control, list each secret under `secrets:` in the `uses` block.
### Calling the Orchestrator from Another Repository
[Section titled “Calling the Orchestrator from Another Repository”](#calling-the-orchestrator-from-another-repository)
The trigger file can also live in a **different repository** — for example, inside each target repo — and call back into the orchestrator in the central control repository. This lets individual repositories decide *when* to request a rollout without requiring direct access to the central repo.
.github/workflows/request-dependabot-rollout.yml
```yaml
name: Request Dependabot Rollout
on:
# Trigger when a maintainer labels the repo for rollout
issues:
types: [labeled]
workflow_dispatch:
jobs:
trigger:
# Call the orchestrator workflow in the central control repo
uses: my-org/central-ops/.github/workflows/dependabot-rollout-orchestrator.lock.yml@main
with:
reason: "${{ github.event_name }} in ${{ github.repository }}"
secrets:
GH_AW_READ_ORG_TOKEN: ${{ secrets.GH_AW_READ_ORG_TOKEN }}
```
### Trade-offs: Schedule Only vs Trigger File
[Section titled “Trade-offs: Schedule Only vs Trigger File”](#trade-offs-schedule-only-vs-trigger-file)
| | Schedule only | Trigger file + `workflow_call` |
| ------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------- |
| **Setup** | Single file, no extra config | Two files (orchestrator + trigger file) |
| **Trigger flexibility** | Cron/schedule only | Any GitHub event (issues, push, PRs, labels…) |
| **Change trigger without recompile** | No — trigger is embedded in the agentic workflow | Yes — edit the plain `.yml` trigger file |
| **Pass event context to agent** | Not possible | Yes — via `workflow_call` inputs |
| **Stability** | Trigger changes on every recompile | Trigger file stays fixed across recompiles |
| **When to use** | Simple recurring jobs with no event dependency | Jobs that should react to repository activity or need flexible scheduling |
The schedule-only approach is perfectly fine for a standalone nightly or weekly orchestrator. Move to the trigger file pattern when you need to react to repository events, pass extra context to the agent, or decouple trigger changes from the compilation cycle.
## Cross-Repository Trigger File
[Section titled “Cross-Repository Trigger File”](#cross-repository-trigger-file)
[]()
A trigger file can live in a **different repository** (for example, in each application repo) and call back into the agentic workflow hosted in a central platform repo. This pattern is useful for multi-tenant platforms where each application repo triggers a shared agentic workflow.
.github/workflows/platform-relay.yml (in application repo)
```yaml
name: Platform Relay
on:
issue_comment:
types: [created]
jobs:
relay:
uses: my-org/platform-repo/.github/workflows/platform-gateway.lock.yml@main
with:
issue_number: ${{ github.event.issue.number }}
source_repo: ${{ github.repository }}
secrets: inherit
```
### Repository Visibility
[Section titled “Repository Visibility”](#repository-visibility)
The callee (platform) repository must meet one of these requirements:
* **Public** — accessible to anyone
* **Internal** — accessible within the organization
* **Private with Actions access** — in repository **Settings → Actions → General**, under *Access*, select “Accessible from repositories in the \[organization] organization”
### Secrets Configuration
[Section titled “Secrets Configuration”](#secrets-configuration)
`COPILOT_GITHUB_TOKEN` must be configured in the **caller** repository’s secrets. When using `secrets: inherit`, all caller secrets are forwarded to the platform workflow automatically. This means:
* Premium Copilot requests bill to the **caller’s** token, not the platform’s
* Each application team manages their own `COPILOT_GITHUB_TOKEN`
* The platform repo does not need to hold tokens for all callers
### How It Works
[Section titled “How It Works”](#how-it-works)
When the compiler detects `workflow_call` in the `on:` section, it generates a cross-repo-aware checkout step in the activation job. A `resolve-host-repo` step inspects `GITHUB_WORKFLOW_REF` at runtime to determine whether the executing workflow lives in a different repository than the one that triggered the event. When a cross-repo invocation is detected, the activation job checks out the **platform repo’s** `.github` folder — where the workflow markdown and runtime imports live — rather than the caller’s repository.
This handles both direct `workflow_call` events and event-driven relays (for example, a trigger file that listens for `issue_comment` and then calls `workflow_call`) because `GITHUB_WORKFLOW_REF` always contains the path of the currently executing workflow file regardless of the triggering event.
### Cross-Organization Setup
[Section titled “Cross-Organization Setup”](#cross-organization-setup)
The setup above works when the caller and callee repositories are in the **same organization** (the `GITHUB_TOKEN` can access internal repos within the org). When the platform repo is in a **different organization**, the caller’s `GITHUB_TOKEN` cannot check out the platform repo’s files, producing an error such as:
```plaintext
fatal: repository 'https://github.com/other-org/platform-repo/' not found
```
Use `inlined-imports: true` on the platform workflow to make the lock file self-contained. All imported content is embedded into the `.lock.yml` at compile time and no cross-organization checkout is needed at runtime:
```aw
---
on:
workflow_call:
engine: copilot
inlined-imports: true
imports:
- shared/common-tools.md
- shared/security-setup.md
---
# Platform Gateway Workflow
Workflow instructions here.
```
After adding `inlined-imports: true`, recompile and commit the updated `.lock.yml`:
```bash
gh aw compile platform-gateway
git add .github/workflows/platform-gateway.lock.yml
git commit -m "compile: embed imports for cross-org workflow_call"
git push
```
Note
With `inlined-imports: true`, any change to an imported file requires recompiling the workflow to take effect. See [Self-Contained Lock Files](/gh-aw/reference/imports/#self-contained-lock-files-inlined-imports-true) for full details and trade-offs.
## Best Practices
[Section titled “Best Practices”](#best-practices)
* Keep orchestrator permissions narrow; delegate repo-specific writes to workers.
* Use safe output limits (`max`) and explicit target workflow allowlists.
* Add correlation IDs to worker dispatch inputs for tracking.
## Related Patterns
[Section titled “Related Patterns”](#related-patterns)
* **[MultiRepoOps](/gh-aw/patterns/multi-repo-ops/)** - Cross-repository automation capability
* **[Cross-Repository Operations](/gh-aw/reference/cross-repository/)** - Checkout and target-repo configuration
* **[Orchestration](/gh-aw/patterns/orchestration/)** - Generic orchestrator/worker dispatch pattern
* **[SideRepoOps](/gh-aw/patterns/side-repo-ops/)** - Isolated control-plane setup
# ChatOps
> Interactive automation triggered by slash commands (/review, /deploy) in issues and PRs - human-in-the-loop workflows
ChatOps brings automation into GitHub conversations through command triggers that respond to slash commands in issues, pull requests, and comments. Team members can trigger workflows by typing commands like `/review` or `/deploy` directly in discussions.
## When to Use ChatOps
[Section titled “When to Use ChatOps”](#when-to-use-chatops)
* **Interactive code reviews** - `/review` to analyze PR changes on demand
* **On-demand deployments** - `/deploy staging` when you’re ready
* **Assisted analysis** - `/analyze` for specific investigations
* **Team collaboration** - Shared commands everyone can use
```aw
---
on:
slash_command:
name: review
events: [pull_request_comment] # Only respond to /review in PR comments
permissions:
contents: read
pull-requests: read
safe-outputs:
create-pull-request-review-comment:
max: 5
add-comment:
---
# Code Review Assistant
When someone types /review in a pull request comment, perform a thorough analysis of the changes.
Examine the diff for potential bugs, security vulnerabilities, performance implications, code style issues, and missing tests or documentation.
Create specific review comments on relevant lines of code and add a summary comment with overall observations and recommendations.
```
When someone types `/review`, the AI analyzes code changes and posts review comments. The agent runs with read-only permissions while [safe-outputs](/gh-aw/reference/safe-outputs/) (validated GitHub operations) handle write operations securely.
## Filtering Command Events
[Section titled “Filtering Command Events”](#filtering-command-events)
Command triggers respond to all comment contexts by default. Use the `events:` field to restrict where commands activate:
```aw
---
on:
slash_command:
name: triage
events: [issues, issue_comment] # Only in issue bodies and issue comments
---
# Issue Triage Bot
This command only responds when mentioned in issues, not in pull requests.
```
**Supported event identifiers:**
* `issues` - Issue bodies (opened, edited, reopened)
* `issue_comment` - Comments on issues only (excludes PR comments)
* `pull_request_comment` - Comments on pull requests only (excludes issue comments)
* `pull_request` - Pull request bodies (opened, edited, reopened)
* `pull_request_review_comment` - Pull request review comments
* `*` - All comment-related events (default when `events:` is omitted)
**Note**: Both `issue_comment` and `pull_request_comment` map to GitHub Actions’ `issue_comment` event but with automatic filtering to distinguish between issue comments and PR comments. This provides precise control over where your commands are active.
## Security and Access Control
[Section titled “Security and Access Control”](#security-and-access-control)
ChatOps workflows restrict execution to users with admin, maintainer, or write permissions by default. Permission checks happen at runtime, canceling workflows for unauthorized users.
Customize access with the `roles:` configuration. Use `roles: [admin, maintainer]` for stricter control. Avoid `roles: all` in public repositories as any authenticated user could trigger workflows.
## Accessing Context Information
[Section titled “Accessing Context Information”](#accessing-context-information)
Access sanitized event context through `steps.sanitized.outputs.text`:
```aw
# Reference the sanitized text in your workflow:
Analyze this content: "${{ steps.sanitized.outputs.text }}"
```
Sanitization filters unauthorized mentions, malicious links, and excessive content while preserving essential information.
**Security**: Treat user-provided content as untrusted. Design workflows to resist prompt injection attempts in issue descriptions, comments, or pull request content.
## Example Workflows
[Section titled “Example Workflows”](#example-workflows)
Sample ChatOps workflows demonstrate command-triggered automation patterns:
* **[Grumpy Code Reviewer](https://github.com/github/gh-aw/blob/main/.github/workflows/grumpy-reviewer.md)** - Triggered by `/grumpy` on PR comments, reviews code changes with a grumpy senior developer personality, identifying code quality issues and posting specific review comments. Uses cache memory to track previous reviews and avoid duplicate feedback.
# DailyOps
> Scheduled workflows for incremental daily improvements - small automated changes that compound over time
DailyOps workflows automate incremental progress toward large goals through small, scheduled daily changes. Work happens automatically in manageable pieces that are easy to review and integrate.
## When to Use DailyOps
[Section titled “When to Use DailyOps”](#when-to-use-dailyops)
* **Continuous improvement** - Daily code quality improvements
* **Progressive migrations** - Gradually update dependencies or patterns
* **Documentation maintenance** - Keep docs fresh with daily updates
* **Technical debt** - Chip away at issues one small PR at a time
## The DailyOps Pattern
[Section titled “The DailyOps Pattern”](#the-dailyops-pattern)
### Scheduled Execution
[Section titled “Scheduled Execution”](#scheduled-execution)
Workflows run on weekday schedules (avoiding weekends) with `workflow_dispatch` enabled for manual testing:
```aw
---
on:
schedule:
- cron: "0 2 * * 1-5" # Weekdays only (no short syntax available)
workflow_dispatch:
---
```
### Phased Approach
[Section titled “Phased Approach”](#phased-approach)
Work proceeds through three phases with maintainer approval between each:
1. **Research** - Analyze state, create discussion with findings
2. **Configuration** - Define steps, create config PR
3. **Execution** - Make improvements, verify, create draft PRs
### Progress Tracking
[Section titled “Progress Tracking”](#progress-tracking)
Use GitHub discussions to maintain continuity across runs. The workflow creates a discussion (if none exists) and adds progress comments on subsequent runs:
```aw
safe-outputs:
create-discussion:
title-prefix: "${{ github.workflow }}"
category: "ideas"
```
The [`safe-outputs:`](/gh-aw/reference/safe-outputs/) (validated GitHub operations) configuration lets the AI request discussion creation without requiring write permissions.
### Discussion Comments
[Section titled “Discussion Comments”](#discussion-comments)
For workflows that post updates to an existing discussion, use `add-comment` with `discussion: true` and a specific `target` discussion number:
```aw
safe-outputs:
add-comment:
target: "4750"
discussion: true
```
This pattern is ideal for daily status posts, recurring reports, or community updates. The [daily-fact.md](https://github.com/github/gh-aw/blob/main/.github/workflows/daily-fact.md) workflow demonstrates this by posting daily facts about the repository to a pinned discussion thread.
### Persistent Memory
[Section titled “Persistent Memory”](#persistent-memory)
Enable `cache-memory` to maintain state at `/tmp/gh-aw/cache-memory/` across runs, useful for tracking progress, storing metrics, and building knowledge bases over time:
```aw
tools:
cache-memory: true
```
## Common DailyOps Workflows
[Section titled “Common DailyOps Workflows”](#common-dailyops-workflows)
This repository implements several DailyOps workflows demonstrating different use cases:
* **daily-fact.md** - Posts daily facts about the repository to a discussion thread
* **daily-test-improver.md** - Systematically adds tests to improve coverage incrementally
* **daily-perf-improver.md** - Identifies and implements performance optimizations
* **daily-doc-updater.md** - Keeps documentation synchronized with merged code changes
* **daily-team-status** (from [agentics](https://github.com/githubnext/agentics)) - Creates daily team status reports with activity summaries
* **daily-repo-chronicle.md** - Produces newspaper-style repository updates
* **daily-firewall-report.md** - Analyzes and reports on firewall activity
All follow the phased approach with discussions for tracking and draft pull requests for review.
## Implementation Guide
[Section titled “Implementation Guide”](#implementation-guide)
1. **Define Goal** - Identify ongoing goal (test coverage, performance, docs sync)
2. **Design Workflow** - Set weekday schedule, configure `safe-outputs` for discussions/PRs
3. **Research Phase** - Analyze state, create discussion, wait for approval
4. **Config Phase** - Create config files, test, submit PR, wait for approval
5. **Execute Daily** - Make small improvements, verify, create draft PRs, update discussion
## Related Patterns
[Section titled “Related Patterns”](#related-patterns)
* **IssueOps** - Trigger workflows from issue creation or comments
* **ChatOps** - Trigger workflows from slash commands in comments
* **LabelOps** - Trigger workflows when labels change on issues or pull requests
* **Planning Workflow** - Use `/plan` command to split large discussions into actionable work items, then assign sub-tasks to Copilot for execution
DailyOps complements these patterns by providing scheduled automation that doesn’t require manual triggers.
# DataOps
> Deterministic data extraction in steps, followed by agentic analysis and reporting
DataOps combines deterministic data extraction with agentic analysis: shell commands in `steps:` reliably collect and prepare data (fast, cacheable, reproducible), then the AI agent reads the results and generates insights. Use this pattern for data aggregation, report generation, trend analysis, and auditing.
## The DataOps Pattern
[Section titled “The DataOps Pattern”](#the-dataops-pattern)
### Basic Structure
[Section titled “Basic Structure”](#basic-structure)
```aw
---
on:
schedule: daily
workflow_dispatch:
steps:
- name: Collect data
run: |
# Deterministic data extraction
gh api ... > /tmp/gh-aw/data.json
safe-outputs:
create-discussion:
category: "reports"
---
# Analysis Workflow
Analyze the data at `/tmp/gh-aw/data.json` and create a summary report.
```
## Example: PR Activity Summary
[Section titled “Example: PR Activity Summary”](#example-pr-activity-summary)
This workflow collects statistics from recent pull requests and generates a weekly summary:
```aw
---
name: Weekly PR Summary
description: Summarizes pull request activity from the last week
on:
schedule: weekly
workflow_dispatch:
permissions:
contents: read
pull-requests: read
engine: copilot
strict: true
network:
allowed:
- defaults
- github
safe-outputs:
create-discussion:
title-prefix: "[weekly-summary] "
category: "announcements"
max: 1
close-older-discussions: true
tools:
bash: ["*"]
steps:
- name: Fetch recent pull requests
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p /tmp/gh-aw/pr-data
# Fetch last 100 PRs with key metadata
gh pr list \
--repo "${{ github.repository }}" \
--state all \
--limit 100 \
--json number,title,state,author,createdAt,mergedAt,closedAt,additions,deletions,changedFiles,labels \
> /tmp/gh-aw/pr-data/recent-prs.json
echo "Fetched $(jq 'length' /tmp/gh-aw/pr-data/recent-prs.json) PRs"
- name: Compute summary statistics
run: |
cd /tmp/gh-aw/pr-data
# Generate statistics summary
jq '{
total: length,
merged: [.[] | select(.state == "MERGED")] | length,
open: [.[] | select(.state == "OPEN")] | length,
closed: [.[] | select(.state == "CLOSED")] | length,
total_additions: [.[].additions] | add,
total_deletions: [.[].deletions] | add,
total_files_changed: [.[].changedFiles] | add,
authors: [.[].author.login] | unique | length,
top_authors: ([.[].author.login] | group_by(.) | map({author: .[0], count: length}) | sort_by(-.count) | .[0:5])
}' recent-prs.json > stats.json
echo "Statistics computed:"
cat stats.json
timeout-minutes: 10
---
# Weekly Pull Request Summary
Analyze the prepared data:
- `/tmp/gh-aw/pr-data/recent-prs.json` - Last 100 PRs with full metadata
- `/tmp/gh-aw/pr-data/stats.json` - Pre-computed statistics
Create a discussion summarizing: total PRs, merge rate, code changes (+/- lines), top contributors, and any notable trends. Keep it concise and factual.
```
## Data Caching
[Section titled “Data Caching”](#data-caching)
For workflows that run frequently or process large datasets, use caching to avoid redundant API calls:
```aw
---
cache:
- key: pr-data-${{ github.run_id }}
path: /tmp/gh-aw/pr-data
restore-keys: |
pr-data-
steps:
- name: Check cache and fetch only new data
run: |
if [ -f /tmp/gh-aw/pr-data/recent-prs.json ]; then
echo "Using cached data"
else
gh pr list --limit 100 --json ... > /tmp/gh-aw/pr-data/recent-prs.json
fi
---
```
## Advanced: Multi-Source Data
[Section titled “Advanced: Multi-Source Data”](#advanced-multi-source-data)
Combine data from multiple sources before analysis:
```aw
---
steps:
- name: Fetch PR data
run: gh pr list --json ... > /tmp/gh-aw/prs.json
- name: Fetch issue data
run: gh issue list --json ... > /tmp/gh-aw/issues.json
- name: Fetch workflow runs
run: gh run list --json ... > /tmp/gh-aw/runs.json
- name: Combine into unified dataset
run: |
jq -s '{prs: .[0], issues: .[1], runs: .[2]}' \
/tmp/gh-aw/prs.json \
/tmp/gh-aw/issues.json \
/tmp/gh-aw/runs.json \
> /tmp/gh-aw/combined.json
---
# Repository Health Report
Analyze the combined data at `/tmp/gh-aw/combined.json` covering:
- Pull request velocity and review times
- Issue response rates and resolution times
- CI/CD success rates and flaky tests
```
## Best Practices
[Section titled “Best Practices”](#best-practices)
* **Keep steps deterministic** - Same inputs should produce the same outputs; avoid randomness or time-dependent logic.
* **Pre-compute aggregations** - Use `jq`, `awk`, or Python to compute statistics upfront, reducing agent token usage.
* **Structure data clearly** - Output JSON with clear field names; include a summary file alongside raw data.
* **Document data locations** - Tell the agent where to find the data and what format to expect.
* **Use safe outputs** - Discussions are ideal for reports (support threading and reactions).
## Additional Resources
[Section titled “Additional Resources”](#additional-resources)
* [Steps Reference](/gh-aw/reference/frontmatter/#custom-steps-steps) - Shell step configuration
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Validated GitHub operations
* [Cache Memory](/gh-aw/reference/cache-memory/) - Caching data between runs
* [DailyOps](/gh-aw/patterns/daily-ops/) - Scheduled improvement workflows
# DispatchOps
> Manually trigger and test agentic workflows with custom inputs using workflow_dispatch
DispatchOps enables manual workflow execution via the GitHub Actions UI or CLI, perfect for on-demand tasks, testing, and workflows that need human judgment about timing. The `workflow_dispatch` trigger lets you run workflows with custom inputs whenever needed.
Use DispatchOps for research tasks, operational commands, testing workflows during development, debugging production issues, or any task that doesn’t fit a schedule or event trigger.
## How Workflow Dispatch Works
[Section titled “How Workflow Dispatch Works”](#how-workflow-dispatch-works)
Workflows with `workflow_dispatch` can be triggered manually rather than waiting for events like issues, pull requests, or schedules.
### Basic Syntax
[Section titled “Basic Syntax”](#basic-syntax)
Add `workflow_dispatch:` to the `on:` section in your workflow frontmatter:
```yaml
on:
workflow_dispatch:
```
### With Input Parameters
[Section titled “With Input Parameters”](#with-input-parameters)
Define inputs to customize workflow behavior at runtime:
```yaml
on:
workflow_dispatch:
inputs:
topic:
description: 'Research topic'
required: true
type: string
priority:
description: 'Task priority'
required: false
type: choice
options:
- low
- medium
- high
default: medium
deploy_target:
description: 'Deployment environment'
required: false
type: environment
default: staging
```
Supported input types: `string` (text), `boolean` (checkbox), `choice` (dropdown), `environment` (GitHub environments dropdown).
### Environment Input Type
[Section titled “Environment Input Type”](#environment-input-type)
The `environment` type populates automatically from repository Settings → Environments, returning the selected name as a string. A `default` may be specified (must match an existing environment name). Unlike `choice`, no `options` list is needed.
```yaml
on:
workflow_dispatch:
inputs:
target_env:
description: 'Deployment target'
required: true
type: environment
default: staging
```
```markdown
Deploy to the ${{ github.event.inputs.target_env }} environment.
```
**Note:** The `environment` type does not enforce protection rules. To require approval gates, reviewers, or wait timers, use the `manual-approval:` field (see [Environment Approval Gates](#environment-approval-gates) below).
## Security Model
[Section titled “Security Model”](#security-model)
### Permission Requirements
[Section titled “Permission Requirements”](#permission-requirements)
Manual workflow execution respects the same security model as other triggers:
* **Repository permissions** - User must have write access or higher to trigger workflows
* **Role-based access** - Use the `roles:` field to restrict who can run workflows:
```yaml
on:
workflow_dispatch:
roles: [admin, maintainer]
```
* **Bot authorization** - Use the `bots:` field to allow specific bot accounts:
```yaml
on:
workflow_dispatch:
bots: ["dependabot[bot]", "github-actions[bot]"]
```
### Fork Protection
[Section titled “Fork Protection”](#fork-protection)
Unlike issue/PR triggers, `workflow_dispatch` only executes in the repository where it’s defined-forks cannot trigger workflows in the parent repository. This provides inherent protection against fork-based attacks.
### Environment Approval Gates
[Section titled “Environment Approval Gates”](#environment-approval-gates)
Require manual approval before execution using GitHub environment protection rules:
```yaml
on:
workflow_dispatch:
manual-approval: production
```
Configure approval rules, required reviewers, and wait timers in repository Settings → Environments. See [GitHub’s environment documentation](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) for setup details.
## Running Workflows from GitHub.com
[Section titled “Running Workflows from GitHub.com”](#running-workflows-from-githubcom)
### Via Actions Tab
[Section titled “Via Actions Tab”](#via-actions-tab)
1. Navigate to your repository on GitHub.com
2. Click the **Actions** tab
3. Select the workflow from the left sidebar
4. Click the **Run workflow** dropdown button
5. Select the branch to run from (default: main)
6. Fill in any required inputs
7. Click the **Run workflow** button
The workflow will execute immediately, and you can watch progress in the Actions tab.
### Finding Runnable Workflows
[Section titled “Finding Runnable Workflows”](#finding-runnable-workflows)
Only workflows with `workflow_dispatch:` appear in the “Run workflow” dropdown. If your workflow isn’t listed:
* Verify `workflow_dispatch:` exists in the `on:` section
* Ensure the workflow has been compiled and pushed to GitHub
* Check that the `.lock.yml` file exists in `.github/workflows/`
## Running Workflows with CLI
[Section titled “Running Workflows with CLI”](#running-workflows-with-cli)
The `gh aw run` command provides a faster way to trigger workflows from the command line.
### Basic Usage
[Section titled “Basic Usage”](#basic-usage)
```bash
gh aw run workflow
```
This matches workflows by filename prefix, validates `workflow_dispatch:`, and returns the run URL immediately.
### With Input Parameters
[Section titled “With Input Parameters”](#with-input-parameters-1)
Pass inputs using the `--raw-field` or `-f` flag in `key=value` format:
```bash
gh aw run research --raw-field topic="quantum computing"
```
```bash
gh aw run scout \
--raw-field topic="AI safety research" \
--raw-field priority=high
```
### Wait for Completion
[Section titled “Wait for Completion”](#wait-for-completion)
Monitor workflow execution and wait for results:
```bash
gh aw run research --raw-field topic="AI agents" --wait
```
`--wait` monitors progress in real-time and exits with a success/failure code on completion.
### Additional Options
[Section titled “Additional Options”](#additional-options)
```bash
gh aw run research --ref feature-branch # Run from specific branch
gh aw run workflow --repo owner/repository # Run in another repository
gh aw run research --raw-field topic="AI" --verbose # Verbose output
```
## Declaring and Referencing Inputs
[Section titled “Declaring and Referencing Inputs”](#declaring-and-referencing-inputs)
### Declaring Inputs in Frontmatter
[Section titled “Declaring Inputs in Frontmatter”](#declaring-inputs-in-frontmatter)
```yaml
on:
workflow_dispatch:
inputs:
analysis_depth:
description: 'How deep should the analysis go?'
required: true
type: choice
options:
- surface
- detailed
- comprehensive
default: detailed
include_examples:
description: 'Include code examples in the report'
required: false
type: boolean
default: true
max_results:
description: 'Maximum number of results to return'
required: false
type: string
default: '10'
```
### Referencing Inputs in Markdown
[Section titled “Referencing Inputs in Markdown”](#referencing-inputs-in-markdown)
Access input values using GitHub Actions expression syntax:
```aw
---
on:
workflow_dispatch:
inputs:
topic:
description: 'Research topic'
required: true
type: string
depth:
description: 'Analysis depth'
type: choice
options:
- brief
- detailed
default: brief
permissions:
contents: read
safe-outputs:
create-discussion:
---
# Research Assistant
Research the following topic: "${{ github.event.inputs.topic }}"
Analysis depth requested: ${{ github.event.inputs.depth }}
Provide a ${{ github.event.inputs.depth }} analysis with key findings and recommendations.
```
Reference inputs with `${{ github.event.inputs.INPUT_NAME }}`—values are interpolated at compile time throughout the workflow.
### Conditional Logic Based on Inputs
[Section titled “Conditional Logic Based on Inputs”](#conditional-logic-based-on-inputs)
Use Handlebars conditionals to change behavior based on input values:
```markdown
{{#if (eq github.event.inputs.include_code "true")}}
Include actual code snippets in your analysis.
{{else}}
Describe code patterns without including actual code.
{{/if}}
{{#if (eq github.event.inputs.priority "high")}}
URGENT: Prioritize speed over completeness.
{{/if}}
```
## Development Pattern: Branch Testing
[Section titled “Development Pattern: Branch Testing”](#development-pattern-branch-testing)
### Testing Workflow Changes
[Section titled “Testing Workflow Changes”](#testing-workflow-changes)
When developing workflows in a feature branch, add `workflow_dispatch:` for testing before merging to main:
```bash
# 1. Develop in feature branch
git checkout -b feature/improve-workflow
# Edit .github/workflows/research.md and add workflow_dispatch
# 2. Test in isolation first
gh aw trial ./research.md --raw-field topic="test query"
# 3. For in-repo testing, temporarily push to main
git checkout main
git cherry-pick
git push origin main
# 4. Test from your branch
git checkout feature/improve-workflow
gh aw run research --ref feature/improve-workflow
# 5. Iterate, then create PR when satisfied
gh pr create --title "Improve workflow"
```
The workflow runs with your branch’s code and state. Safe outputs (issues, PRs, comments) are created in your branch context. Use [trial mode](/gh-aw/patterns/trial-ops/) for completely isolated testing without affecting the production repository.
## Common Use Cases
[Section titled “Common Use Cases”](#common-use-cases)
**On-demand research:** Add a `topic` string input and trigger with `gh aw run research --raw-field topic="AI safety"` when needed.
**Manual operations:** Use a `choice` input with predefined operations (cleanup, sync, audit) to execute specific tasks on demand.
**Testing and debugging:** Add `workflow_dispatch` to event-triggered workflows (issues, PRs) with optional test URL inputs to test without creating real events.
**Scheduled workflow testing:** Combine `schedule` with `workflow_dispatch` to test scheduled workflows immediately rather than waiting for the cron schedule.
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
**Workflow not listed in GitHub UI:** Verify `workflow_dispatch:` exists in the `on:` section, compile the workflow (`gh aw compile workflow`), and push both `.md` and `.lock.yml` files. The Actions page may need a refresh.
**“Workflow not found” error:** Use the filename without `.md` extension (`research` not `research.md`). Ensure the workflow exists in `.github/workflows/` and has been compiled.
**“Workflow cannot be run” error:** Add `workflow_dispatch:` to the `on:` section, recompile, and verify the `.lock.yml` includes the trigger before pushing.
**Permission denied:** Verify write access to the repository and check the `roles:` field in workflow frontmatter. For organization repos, confirm your org role.
**Inputs not appearing:** Check YAML syntax and indentation (2 spaces) in `workflow_dispatch.inputs`. Ensure input types are valid (`string`, `boolean`, `choice`, `environment`), then recompile and push.
**Wrong branch context:** Specify the branch explicitly with `--ref branch-name` in CLI or select the correct branch in the GitHub UI dropdown before running.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Manual Workflows Example](/gh-aw/examples/manual/) - Example manual workflows
* [Triggers Reference](/gh-aw/reference/triggers/) - Complete trigger syntax including workflow\_dispatch
* [TrialOps](/gh-aw/patterns/trial-ops/) - Testing workflows in isolation
* [CLI Commands](/gh-aw/setup/cli/) - Complete gh aw run command reference
* [Templating](/gh-aw/reference/templating/) - Using expressions and conditionals
* [Security Best Practices](/gh-aw/introduction/architecture/) - Securing workflow execution
* [Quick Start](/gh-aw/setup/quick-start/) - Getting started with agentic workflows
# IssueOps
> Automate issue triage, categorization, and responses when issues are opened - fully automated issue management
IssueOps transforms GitHub issues into automation triggers that analyze, categorize, and respond to issues automatically. Use it for auto-triage, smart routing, initial responses, and quality checks. GitHub Agentic Workflows makes this natural through issue triggers and [safe-outputs](/gh-aw/reference/safe-outputs/) that handle automated responses securely without write permissions for the main AI job.
When issues are created, workflows activate automatically. The AI analyzes content and provides intelligent responses through automated comments.
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
safe-outputs:
add-comment:
max: 2
---
# Issue Triage Assistant
Analyze new issue content and provide helpful guidance. Examine the title and description for bug reports needing information, feature requests to categorize, questions to answer, or potential duplicates. Respond with a comment guiding next steps or providing immediate assistance.
```
This creates an intelligent triage system that responds to new issues with contextual guidance.
## Safe Output Architecture
[Section titled “Safe Output Architecture”](#safe-output-architecture)
IssueOps workflows use the `add-comment` safe output to ensure secure comment creation with minimal permissions. The main job runs with `contents: read` while comment creation happens in a separate job with `issues: write` permissions, automatically sanitizing AI content and preventing spam:
```yaml
safe-outputs:
add-comment:
max: 3 # Optional: allow multiple comments (default: 1)
target: "triggering" # Default: comment on the triggering issue/PR
```
## Accessing Issue Context
[Section titled “Accessing Issue Context”](#accessing-issue-context)
Access sanitized issue content through `steps.sanitized.outputs.text`, which combines title and description while removing security risks (@mentions, URIs, injections):
```yaml
Analyze this issue: "${{ steps.sanitized.outputs.text }}"
```
## Common IssueOps Patterns
[Section titled “Common IssueOps Patterns”](#common-issueops-patterns)
### Automated Bug Report Triage
[Section titled “Automated Bug Report Triage”](#automated-bug-report-triage)
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
safe-outputs:
add-labels:
allowed: [bug, needs-info, enhancement, question, documentation] # Restrict to specific labels
max: 2 # Maximum 2 labels per issue
---
# Bug Report Triage
Analyze new issues and add appropriate labels: "bug" (with repro steps), "needs-info" (missing details), "enhancement" (features), "question" or "documentation" (help/docs). Maximum 2 labels from the allowed list.
```
## Organizing Work with Sub-Issues
[Section titled “Organizing Work with Sub-Issues”](#organizing-work-with-sub-issues)
Break large work into agent-ready tasks using parent-child issue hierarchies. Create hierarchies with the `parent` field and temporary IDs, or link existing issues with `link-sub-issue`:
```aw
---
on:
command:
name: plan
safe-outputs:
create-issue:
title-prefix: "[task] "
max: 6
---
# Planning Assistant
Create a parent tracking issue, then sub-issues linked via parent field:
{"type": "create_issue", "temporary_id": "aw_abc123", "title": "Feature X", "body": "Tracking issue"}
{"type": "create_issue", "parent": "aw_abc123", "title": "Task 1", "body": "First task"}
```
Tip
Hide sub-issues Filter sub-issues from `/issues` with `no:parent-issue`: `/issues?q=no:parent-issue`
Assign sub-issues to Copilot with `assignees: copilot` for parallel execution.
# LabelOps
> Workflows triggered by label changes - automate actions when specific labels are added or removed
LabelOps uses GitHub labels as workflow triggers, metadata, and state markers. GitHub Agentic Workflows supports two distinct approaches to label-based triggers: `label_command` for command-style one-shot activation, and `names:` filtering for persistent label-state awareness.
## Label Command Trigger
[Section titled “Label Command Trigger”](#label-command-trigger)
The `label_command` trigger treats a label as a one-shot command: applying the label fires the workflow, and the label is **automatically removed** so it can be re-applied to re-trigger. This is the right choice when you want a label to mean “do this now” rather than “this item has this property.”
```aw
---
on:
label_command: deploy
permissions:
contents: read
safe-outputs:
add-comment:
max: 1
---
# Deploy Preview
A `deploy` label was applied to this pull request. Build and deploy a preview environment and post the URL as a comment.
The matched label name is available as `${{ needs.activation.outputs.label_command }}` if needed to distinguish between multiple label commands.
```
After activation the `deploy` label is removed from the pull request, so a reviewer can apply it again to trigger another deployment without any cleanup step.
### Syntax
[Section titled “Syntax”](#syntax)
`label_command` accepts a shorthand string, a map with a single name, or a map with multiple names and an optional `events` restriction:
```yaml
# Shorthand — fires on issues, pull_request, and discussion
on: "label-command deploy"
# Map with a single name
on:
label_command: deploy
# Restrict to specific event types
on:
label_command:
name: deploy
events: [issues, pull_request]
# Multiple label names
on:
label_command:
names: [deploy, redeploy]
events: [pull_request]
# Keep label after activation (persistent state, not one-shot command)
on:
label_command:
name: in-review
remove_label: false
```
The `remove_label` field (boolean, default `true`) controls whether the matched label is removed after the workflow activates. Set it to `false` when the label represents a persistent state rather than a transient command — for example, to mark that an item is currently being processed without consuming the label. When `remove_label: false`.
The compiler generates `issues`, `pull_request`, and/or `discussion` events with `types: [labeled]`, filtered to the named labels. It also adds a `workflow_dispatch` trigger with an `item_number` input so you can test the workflow manually without applying a real label.
### Accessing the matched label
[Section titled “Accessing the matched label”](#accessing-the-matched-label)
The label that triggered the workflow is exposed as an output of the activation job:
```plaintext
${{ needs.activation.outputs.label_command }}
```
This is useful when a workflow handles multiple label commands and needs to branch on which one was applied.
### Combining with slash commands
[Section titled “Combining with slash commands”](#combining-with-slash-commands)
`label_command` can be combined with `slash_command:` in the same workflow. The two triggers are OR’d — the workflow activates when either condition is met:
```yaml
on:
slash_command: deploy
label_command:
name: deploy
events: [pull_request]
```
This lets a workflow be triggered both by a `/deploy` comment and by applying a `deploy` label, sharing the same agent logic.
## Label Filtering
[Section titled “Label Filtering”](#label-filtering)
Use `names:` filtering when you want the workflow to run whenever a label is present on an item and the label should remain attached. This is suitable for monitoring label state rather than reacting to a transient command.
GitHub Agentic Workflows allows you to filter `labeled` and `unlabeled` events to trigger only for specific label names using the `names` field:
```aw
---
on:
issues:
types: [labeled]
names: [bug, critical, security]
permissions:
contents: read
actions: read
safe-outputs:
add-comment:
max: 1
---
# Critical Issue Handler
When a critical label is added to an issue, analyze the severity and provide immediate triage guidance.
Check the issue for:
- Impact scope and affected users
- Reproduction steps
- Related dependencies or systems
- Recommended priority level
Respond with a comment outlining next steps and recommended actions.
```
This workflow activates only when the `bug`, `critical`, or `security` labels are added to an issue, not for other label changes. The labels remain on the issue after the workflow runs.
### Choosing between `label_command` and `names:` filtering
[Section titled “Choosing between label\_command and names: filtering”](#choosing-between-label_command-and-names-filtering)
| | `label_command` | `names:` filtering |
| --------------- | ----------------------------------- | -------------------------------- |
| Label lifecycle | Removed automatically after trigger | Stays on the item |
| Re-triggerable | Yes — reapply the label | Only on the next `labeled` event |
| Typical use | ”Do this now” commands | State-based routing |
| Supported items | Issues, pull requests, discussions | Issues, pull requests |
### Label Filter Syntax
[Section titled “Label Filter Syntax”](#label-filter-syntax)
The `names` field accepts a single label (`names: urgent`) or an array (`names: [priority, needs-review, blocked]`). It works with both `issues` and `pull_request` events, and the field is compiled into a conditional `if` expression in the final workflow YAML.
## Common LabelOps Patterns
[Section titled “Common LabelOps Patterns”](#common-labelops-patterns)
| Pattern | Trigger Labels | Agent Response |
| ----------------------- | -------------------------- | -------------------------------------------------------- |
| **Priority Escalation** | `P0`, `critical`, `urgent` | Analyze severity, notify leads, provide SLA guidance |
| **Label-Based Triage** | `needs-triage`, `triaged` | Suggest categorization, priority, affected components |
| **Security Automation** | Security labels | Check disclosure risks, trigger review process |
| **Release Management** | Release labels | Analyze timeline, identify blockers, draft release notes |
## AI-Powered LabelOps
[Section titled “AI-Powered LabelOps”](#ai-powered-labelops)
* **Automatic Label Suggestions**: Analyze issues and apply labels for type, priority, and component. Use `safe-outputs.add-labels.allowed` to restrict which labels can be applied automatically.
* **Component Auto-Labeling**: Identify affected components from file paths, APIs, and UI elements, then apply relevant component labels.
* **Label Consolidation**: Schedule audits to identify duplicate, unused, and inconsistently named labels.
## Best Practices
[Section titled “Best Practices”](#best-practices)
* Use specific label names (`ready-for-review` not `ready`) to avoid unintended triggers.
* Document label meanings in a LABELS.md file or GitHub label descriptions.
* Limit automation scope with opt-in labels like `automation-enabled`.
* Use safe outputs for all write operations to maintain security.
## Additional Resources
[Section titled “Additional Resources”](#additional-resources)
* [Trigger Events](/gh-aw/reference/triggers/) - Complete trigger configuration including label filtering
* [IssueOps](/gh-aw/patterns/issue-ops/) - Learn about issue-triggered workflows
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Secure output handling
* [Frontmatter Reference](/gh-aw/reference/frontmatter/) - Complete workflow configuration options
# Projects & Monitoring
> Use GitHub Projects + safe-outputs to track and monitor workflow work items and progress.
Use this pattern when you want a durable “source of truth” for what your agentic workflows discovered, decided, and did.
## What this pattern is
[Section titled “What this pattern is”](#what-this-pattern-is)
* **Projects** are the dashboard: a GitHub Projects v2 board holds issues/PRs and custom fields.
* **Monitoring** is the behavior: workflows continuously add/update items, and periodically post status updates.
## Building blocks
[Section titled “Building blocks”](#building-blocks)
### 1) Track items with `update-project`
[Section titled “1) Track items with update-project”](#1-track-items-with-update-project)
Enable the safe output and point it at your project URL:
```yaml
safe-outputs:
update-project:
project: https://github.com/orgs/myorg/projects/123
max: 10
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
```
* Adds issues/PRs to the board and updates custom fields.
* Can also create views and custom fields when configured.
See the full reference: [/reference/safe-outputs/#project-board-updates-update-project](/gh-aw/reference/safe-outputs/#project-board-updates-update-project)
### 2) Post run summaries with `create-project-status-update`
[Section titled “2) Post run summaries with create-project-status-update”](#2-post-run-summaries-with-create-project-status-update)
Use project status updates to communicate progress and next steps:
```yaml
safe-outputs:
create-project-status-update:
project: https://github.com/orgs/myorg/projects/123
max: 1
github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}
```
This is useful for scheduled workflows (daily/weekly) or orchestrator workflows.
See the full reference: [/reference/safe-outputs/#project-status-updates-create-project-status-update](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update)
### 3) Correlate work with a Tracker Id field
[Section titled “3) Correlate work with a Tracker Id field”](#3-correlate-work-with-a-tracker-id-field)
If you want to correlate multiple runs, add a custom field like **Tracker Id** (text) and populate it from your workflow prompt/output (for example, a run ID, issue number, or “initiative” key).
## Run failure issues
[Section titled “Run failure issues”](#run-failure-issues)
When a workflow run fails, the system automatically posts a failure notification on the triggering issue or pull request. To track failures as searchable GitHub issues, enable `create-issue` in `safe-outputs`:
```yaml
safe-outputs:
create-issue:
title-prefix: "[failed] "
labels: [automation, failed]
```
The issue body includes the workflow name, run URL, and failure status, making it easy to find and triage recurring failures.
### Grouping failures as sub-issues
[Section titled “Grouping failures as sub-issues”](#grouping-failures-as-sub-issues)
When multiple workflow runs fail, the `group-reports` option links each failure report as a sub-issue under a shared parent issue titled “\[aw] Failed runs”. This is useful for scheduled or high-frequency workflows where failures can accumulate.
```yaml
safe-outputs:
create-issue:
title-prefix: "[failed] "
labels: [automation, failed]
group-reports: true # Group failure reports under a shared parent issue (default: false)
```
When `group-reports` is enabled:
* A parent “\[aw] Failed runs” issue is automatically created and managed.
* Each failure run report is linked as a sub-issue under the parent.
* Up to 64 sub-issues are tracked per parent issue.
See the full reference: [/reference/safe-outputs/#group-reports-group-reports](/gh-aw/reference/safe-outputs/#group-reports-group-reports)
## No-op run reports
[Section titled “No-op run reports”](#no-op-run-reports)
When an agent determines that no action is needed (for example, no issues were found), it outputs a no-op message. By default, this message is posted as a comment on the triggering issue or pull request, keeping a visible record of runs that intentionally did nothing.
To disable posting no-op messages as issue comments:
```yaml
safe-outputs:
create-issue:
noop:
report-as-issue: false # Disable posting noop messages as issue comments
```
No-op messages still appear in the workflow step summary even when `report-as-issue` is `false`.
To disable the no-op output entirely:
```yaml
safe-outputs:
create-issue:
noop: false # Disable noop output completely
```
See the full reference: [/reference/safe-outputs/#no-op-logging-noop](/gh-aw/reference/safe-outputs/#no-op-logging-noop)
## Operational monitoring
[Section titled “Operational monitoring”](#operational-monitoring)
Use `gh aw status` to see which workflows are enabled and their latest run state.
For deeper investigation, the audit commands are the primary monitoring tool for agentic workflows:
* `gh aw audit ` — single-run report with tool usage, MCP failures, firewall activity, and cost metrics
* `gh aw audit diff ` — compare two runs to detect behavioral regressions or new network accesses
* `gh aw logs --format markdown [workflow]` — cross-run security and performance report for trend monitoring
```bash
# Audit the most recent run
gh aw audit 12345678
# Compare two runs for regressions
gh aw audit diff 12345678 12345679
# Trend report across the last 10 runs of a workflow
gh aw logs my-workflow --format markdown --count 10
```
Tip
Use `gh aw logs --format markdown` inside a scheduled workflow agent to automate trend monitoring and surface cost or security regressions without manual intervention.
See [Audit Commands](/gh-aw/reference/audit/) for full flag documentation, and [CLI Reference](/gh-aw/setup/cli/) for all available commands.
# MultiRepoOps
> Coordinate agentic workflows across multiple GitHub repositories with automated issue tracking, feature synchronization, and organization-wide enforcement
MultiRepoOps extends operational automation patterns (IssueOps, ChatOps, etc.) across multiple GitHub repositories. Using cross-repository safe outputs and secure authentication, MultiRepoOps enables coordinating work between related projects-creating tracking issues in central repos, synchronizing features to sub-repositories, and enforcing organization-wide policies-all through AI-powered workflows.
## When to Use MultiRepoOps
[Section titled “When to Use MultiRepoOps”](#when-to-use-multirepoops)
* **Feature synchronization** - Propagate changes from main repositories to sub-repos or forks
* **Hub-and-spoke tracking** - Centralize issue tracking across component repositories
* **Organization-wide enforcement** - Roll out security patches, policy updates, or dependency changes across all repos
* **Monorepo alternatives** - Coordinate packages or services living in separate repositories
* **Upstream/downstream workflows** - Sync features between upstream dependencies and downstream consumers
## How It Works
[Section titled “How It Works”](#how-it-works)
MultiRepoOps workflows use the `target-repo` parameter on safe outputs to create issues, pull requests, and comments in external repositories. Combined with GitHub API toolsets for querying remote repos and proper authentication (PAT or GitHub App tokens), workflows can coordinate complex multi-repository operations automatically.
```aw
---
on:
issues:
types: [opened, labeled]
permissions:
contents: read
actions: read
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
target-repo: "org/tracking-repo"
title-prefix: "[component-a] "
labels: [tracking, multi-repo]
---
# Cross-Repo Issue Tracker
When issues are created in component repositories, automatically create tracking issues in the central coordination repo.
Analyze the issue and create a tracking issue that:
- Links back to the original component issue
- Summarizes the problem and impact
- Tags relevant teams across the organization
- Provides context for cross-component coordination
```
## Authentication for Cross-Repo Access
[Section titled “Authentication for Cross-Repo Access”](#authentication-for-cross-repo-access)
Cross-repository operations require authentication beyond the default `GITHUB_TOKEN`, which is scoped to the current repository only.
### Personal Access Token (PAT)
[Section titled “Personal Access Token (PAT)”](#personal-access-token-pat)
Configure a Personal Access Token with access to target repositories:
```yaml
safe-outputs:
github-token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
create-issue:
target-repo: "org/tracking-repo"
```
**Required Permissions:**
The PAT needs permissions **only on target repositories** where you want to create resources, not on the source repository where the workflow runs.
* Repository access to target repos (public or private)
* `contents: write`, `issues: write`, `pull-requests: write` (depending on operations)
Tip
Security Best Practice If you only need to read from one repo and write to another, scope your PAT to have read access on the source and write access only on target repositories.
### GitHub App Installation Token
[Section titled “GitHub App Installation Token”](#github-app-installation-token)
For enhanced security, use GitHub Apps with automatic token revocation. GitHub App tokens provide per-job minting, automatic revocation after job completion, fine-grained permissions, and better attribution than long-lived PATs.
See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication) for complete configuration including specific repository scoping and org-wide access.
## Common MultiRepoOps Patterns
[Section titled “Common MultiRepoOps Patterns”](#common-multirepoops-patterns)
### Hub-and-Spoke Issue Tracking
[Section titled “Hub-and-Spoke Issue Tracking”](#hub-and-spoke-issue-tracking)
Central repository aggregates issues from multiple component repositories:
```text
Component Repo A ──┐
Component Repo B ──┼──> Central Tracker
Component Repo C ──┘
```
Each component workflow creates tracking issues in the central repo using `target-repo` parameter.
### Upstream-to-Downstream Sync
[Section titled “Upstream-to-Downstream Sync”](#upstream-to-downstream-sync)
Main repository propagates changes to downstream repositories:
```text
Main Repo ──> Sub-Repo Alpha
──> Sub-Repo Beta
──> Sub-Repo Gamma
```
Use cross-repo pull requests with `create-pull-request` safe output and `target-repo` configuration.
### Organization-Wide Coordination
[Section titled “Organization-Wide Coordination”](#organization-wide-coordination)
Single workflow creates issues across multiple repositories:
```text
Control Workflow ──> Repo 1 (tracking issue)
──> Repo 2 (tracking issue)
──> Repo 3 (tracking issue)
```
Agent generates multiple tracking issues with different `target-repo` values (up to configured `max` limit).
## Cross-Repository Safe Outputs
[Section titled “Cross-Repository Safe Outputs”](#cross-repository-safe-outputs)
Most safe output types support the `target-repo` parameter for cross-repository operations. **Without `target-repo`, these safe outputs operate on the repository where the workflow is running.**
| Safe Output | Cross-Repo Support | Example Use Case |
| ---------------------- | ------------------ | -------------------------------------- |
| `create-issue` | ✓ | Create tracking issues in central repo |
| `add-comment` | ✓ | Comment on issues in other repos |
| `update-issue` | ✓ | Update issue status across repos |
| `add-labels` | ✓ | Label issues in target repos |
| `create-pull-request` | ✓ | Create PRs in downstream repos |
| `create-discussion` | ✓ | Create discussions in any repo |
| `create-agent-session` | ✓ | Create tasks in target repos |
| `update-release` | ✓ | Update release notes across repos |
## Teaching Agents Multi-Repo Access
[Section titled “Teaching Agents Multi-Repo Access”](#teaching-agents-multi-repo-access)
Enable GitHub toolsets to allow agents to query multiple repositories:
```yaml
tools:
github:
toolsets: [repos, issues, pull_requests, actions]
github-token: ${{ secrets.CROSS_REPO_PAT }} # Required for cross-repo reading
```
Caution
When reading from repositories other than the workflow’s repository, you must configure additional authentication. The default `GITHUB_TOKEN` only has access to the current repository. Use a PAT, GitHub App token, or the magic secret `GH_AW_GITHUB_MCP_SERVER_TOKEN`. See [GitHub Tools Reference](/gh-aw/reference/cross-repository/#cross-repository-reading) for details.
Agent instructions can reference remote repositories:
```markdown
Search for open issues in org/upstream-repo related to authentication.
Check the latest release notes from org/dependency-repo.
Compare code structure between this repo and org/reference-repo.
```
## Deterministic Multi-Repo Workflows
[Section titled “Deterministic Multi-Repo Workflows”](#deterministic-multi-repo-workflows)
For direct repository access without agent involvement, use an AI engine with custom steps:
```aw
---
engine:
id: claude
steps:
- name: Checkout main repo
uses: actions/checkout@v6
with:
path: main-repo
- name: Checkout secondary repo
uses: actions/checkout@v6
with:
repository: org/secondary-repo
token: ${{ secrets.GH_AW_CROSS_REPO_PAT }}
path: secondary-repo
- name: Compare and sync
run: |
# Deterministic sync logic
rsync -av main-repo/shared/ secondary-repo/shared/
cd secondary-repo
git add .
git commit -m "Sync from main repo"
git push
---
# Deterministic Feature Sync
Workflow that directly checks out multiple repos and synchronizes files.
```
## Example Workflows
[Section titled “Example Workflows”](#example-workflows)
Explore detailed MultiRepoOps examples:
* **[Feature Synchronization](/gh-aw/examples/multi-repo/feature-sync/)** - Sync code changes from main repo to sub-repositories
* **[Cross-Repo Issue Tracking](/gh-aw/examples/multi-repo/issue-tracking/)** - Hub-and-spoke tracking architecture
## Best Practices
[Section titled “Best Practices”](#best-practices)
* **Authentication**: Use GitHub Apps for automatic token revocation; scope PATs minimally to required repositories; store tokens as GitHub secrets
* **Workflow design**: Set appropriate `max` limits; use meaningful title prefixes and consistent labels
* **Error handling**: Handle rate limits and permission failures; monitor workflow execution across repositories
* **Testing**: Start with public repositories, pilot a small subset, and verify configurations before full rollout
## Related Patterns
[Section titled “Related Patterns”](#related-patterns)
* **[IssueOps](/gh-aw/patterns/issue-ops/)** - Single-repo issue automation
* **[ChatOps](/gh-aw/patterns/chat-ops/)** - Command-driven workflows
* **[Orchestration](/gh-aw/patterns/orchestration/)** - Multi-issue initiative coordination
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Cross-Repository Operations](/gh-aw/reference/cross-repository/) - Checkout and target-repo configuration
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Complete safe output configuration
* [GitHub Tools](/gh-aw/reference/github-tools/) - GitHub API toolsets
* [Security Best Practices](/gh-aw/introduction/architecture/) - Authentication and token security
* [Reusing Workflows](/gh-aw/guides/packaging-imports/) - Sharing workflows across repos
# Orchestration
> Coordinate multiple agentic workflows using workflow dispatch or reusable workflow calls (orchestrator/worker pattern).
Use this pattern when one workflow (the **orchestrator**) needs to fan out work to one or more **worker** workflows.
## The orchestrator/worker pattern
[Section titled “The orchestrator/worker pattern”](#the-orchestratorworker-pattern)
* **Orchestrator**: decides what to do next, splits work into units, dispatches workers.
* **Worker(s)**: do the concrete work (triage, code changes, analysis) with scoped permissions/tools.
* **Optional monitoring**: both orchestrator and workers can update a GitHub Project board for visibility.
## Dispatch workers with `dispatch-workflow`
[Section titled “Dispatch workers with dispatch-workflow”](#dispatch-workers-with-dispatch-workflow)
Allow dispatching specific workflows via GitHub’s `workflow_dispatch` API:
```yaml
safe-outputs:
dispatch-workflow:
workflows: [repo-triage-worker, dependency-audit-worker]
max: 10
```
During compilation, gh-aw validates the target workflows exist and support `workflow_dispatch`. Workers receive a JSON payload and run asynchronously as independent workflow runs.
See [`dispatch-workflow` safe output](/gh-aw/reference/safe-outputs/#workflow-dispatch-dispatch-workflow).
## Call workers with `call-workflow`
[Section titled “Call workers with call-workflow”](#call-workers-with-call-workflow)
Call reusable workflows (`workflow_call`) via compile-time fan-out—no API call at runtime:
```yaml
safe-outputs:
call-workflow:
workflows: [spring-boot-bugfix, frontend-dep-upgrade]
max: 1
```
The compiler validates that each worker declares `workflow_call`, generates a typed MCP tool per worker from its inputs, and emits a conditional `uses:` job. At runtime the worker whose name the agent selected executes as part of the same workflow run—preserving `github.actor` and billing attribution.
See [`call-workflow` safe output](/gh-aw/reference/safe-outputs/#workflow-call-call-workflow).
## Choosing between the two approaches
[Section titled “Choosing between the two approaches”](#choosing-between-the-two-approaches)
Use `call-workflow` when actor attribution matters, workers must finish before the orchestrator concludes, or you want zero API overhead. Use `dispatch-workflow` when workers should run asynchronously, outlive the parent run, or need `workflow_dispatch` inputs.
## Passing correlation IDs
[Section titled “Passing correlation IDs”](#passing-correlation-ids)
If your workers need shared context, pass an explicit input such as `tracker_id` (string) and include it in worker outputs (e.g., writing it into a Project custom field).
See also: [Monitoring](/gh-aw/patterns/monitoring/)
# ProjectOps
> Automate GitHub Projects with agentic routing, field updates, and controlled write operations
ProjectOps helps teams run project operations with less manual upkeep.
It builds on [GitHub Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects), which provides the core planning and tracking layer for issues and pull requests, and adds support for judgment-heavy decisions.
ProjectOps reads project state with GitHub tools and applies changes through [safe-outputs](/gh-aw/reference/safe-outputs/). It is most useful when you need context-aware routing and field updates. For simple, rule-based transitions, [built-in automations](https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/using-the-built-in-automations) are usually enough.
In practice, this gives teams faster triage decisions, cleaner board state, stronger planning signals across related issues and pull requests, and more decision-ready status updates.
## Prerequisites
[Section titled “Prerequisites”](#prerequisites)
1. **A Project board** and copy the project URL. See [Creating a project](https://docs.github.com/en/issues/planning-and-tracking-with-projects/creating-projects/creating-a-project#creating-a-project).
2. **A Project token** (PAT or GitHub App token). See [Project Token Authentication](#project-token-authentication).
3. **A field contract** (for example: Status, Priority, Team, Iteration, Target Date). See [Understanding fields](https://docs.github.com/en/issues/planning-and-tracking-with-projects/understanding-fields).
## Project Token Authentication
[Section titled “Project Token Authentication”](#project-token-authentication)
Project operations need additional authentication because the default `GITHUB_TOKEN` is repository-scoped and cannot access Projects APIs for read/write project operations.
### User-owned Projects
[Section titled “User-owned Projects”](#user-owned-projects)
If your project is user-owned, use a PAT and store it as a repository secret.
* Use a [classic PAT](https://github.com/settings/tokens/new).
* Required scopes:
* `project`
* `repo` (if private repositories are involved)
### Organization-owned Projects
[Section titled “Organization-owned Projects”](#organization-owned-projects)
If your project is organization-owned, use a fine-grained PAT or a GitHub App token and store it as a repository secret.
* Use a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new?name=GH_AW_WRITE_PROJECT_TOKEN\&description=GitHub+Agentic+Workflows+-+Projects+authentication\&contents=read\&issues=read\&pull_requests=read).
* Configure:
* Resource owner: select the organization this project belongs to.
* Repository access: select the repositories that will run the workflow.
* Repository permissions: `Contents: Read`, and optionally `Issues: Read` / `Pull requests: Read` (or `Read and write`).
* Organization permissions: `Projects: Read` (or `Read and write`).
You can also use a GitHub App token if your organization standardizes on App-based auth. For organization projects, make sure the app has **Organization Projects: Read and write** permission. See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication).
### Recommended secret layout
[Section titled “Recommended secret layout”](#recommended-secret-layout)
Use separate read and write tokens so you can enforce least privilege:
* `GH_AW_READ_PROJECT_TOKEN` for `tools.github` + `projects` toolset.
* `GH_AW_WRITE_PROJECT_TOKEN` for safe-output writes like `update-project`.
```bash
gh aw secrets set GH_AW_READ_PROJECT_TOKEN --value ""
gh aw secrets set GH_AW_WRITE_PROJECT_TOKEN --value ""
```
## How it works
[Section titled “How it works”](#how-it-works)
A practical way to adopt ProjectOps is to start with read-only MCP/GitHub analysis, then gradually add targeted write operations as workflow confidence and policy maturity increase.
ProjectOps combines two capability layers:
* **GitHub tools (`tools.github` + `projects` toolset)** for reading and analyzing project state.
* **Safe outputs** for controlled write operations, including:
* **[`update-project`](/gh-aw/reference/safe-outputs/#project-board-updates-update-project)** — use when you want to add issues/PRs to a project or update fields (status, priority, owner, dates, custom values).
* **[`create-project-status-update`](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update)** — use when you want a stakeholder-facing summary in the project Updates tab (weekly health, blockers, risks, next decisions).
* **[`create-project`](/gh-aw/reference/safe-outputs/#project-creation-create-project)** — use when automation needs to bootstrap a new board for an initiative or team.
* **[`add-comment`](/gh-aw/reference/safe-outputs/#comment-creation-add-comment)** — use when you want to explain routing decisions or request missing info on the triggering issue/PR.
Let’s look at examples of these in action, starting with the [Project Board Summarizer](#project-board-summarizer) (read-only analysis), then moving to controlled write operations with the [Project Board Maintainer](#project-board-maintainer) example.
## Examples
[Section titled “Examples”](#examples)
### Project Board Summarizer
[Section titled “Project Board Summarizer”](#project-board-summarizer)
Let’s start with a simple agentic workflow that reviews project board state and generates a summary without applying any changes.
```aw
---
on:
schedule:
- cron: "0 14 * * 1"
permissions:
contents: read
actions: read
tools:
github:
github-token: ${{ secrets.GH_AW_READ_PROJECT_TOKEN }}
toolsets: [default, projects]
---
# Project Board Summarizer
Review [project 1](https://github.com/orgs/my-mona-org/projects/1).
Return only:
- New this week
- Blocked + why
- Stale/inconsistent fields
- Top 3 human actions
Read-only. Do not update the project.
```
Our project board might look like this:

Running the agentic workflow generates a concise summary of project status. We can find this in the GitHub Actions agent run output:

### Project Board Maintainer
[Section titled “Project Board Maintainer”](#project-board-maintainer)
Let’s write an agentic workflow that applies changes to a project board based on issue content and context. This workflow will run on new issues, analyze the issue and project state, and decide whether to add the issue to the project board and how to set key fields.
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
tools:
github:
github-token: ${{ secrets.GH_AW_READ_PROJECT_TOKEN }}
toolsets: [default, projects]
safe-outputs:
update-project:
github-token: ${{ secrets.GH_AW_WRITE_PROJECT_TOKEN }}
project: https://github.com/orgs/my-mona-org/projects/1
max: 1
add-comment:
max: 1
---
# Intelligent Issue Triage
Analyze each new issue in this repository and decide whether it belongs on the project board.
Set structured fields only from allowed values:
- Status: Needs Triage | Proposed | In Progress | Blocked
- Priority: Low | Medium | High
- Team: Platform | Docs | Product
Post a short comment on the issue explaining your routing decision and any uncertainty.
```
Once this workflow is compiled and running, it will automatically triage new issues with controlled write operations to the project board and issue comments.
Let’s create a new issue to see this in action:

The Project Board Maintainer analyzes the issue content and context, then decides to add it to the project board with specific field values (for example, Status: Proposed, Priority: Medium, Team: Docs). It also posts a comment on the issue explaining the decision and any uncertainty.

## Best practices
[Section titled “Best practices”](#best-practices)
In production, keep the loop simple: issue arrives, agent classifies and proposes/sets fields, safe outputs apply allowed writes, and humans review high-impact changes and exceptions.
* **Auto-apply** low-risk hygiene (add item, set initial status/team).
* **Suggest-only** commitments (priority/date/iteration changes).
* **Always gate** cross-team or cross-repo impact.
* Use `max` caps, allowlists, and explicit approvals to control writes.
* Keep single-select values exact to avoid field drift.
* If you only need simple event-based transitions, prefer [built-in GitHub Project workflows](https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/using-the-built-in-automations).
## Related documentation
[Section titled “Related documentation”](#related-documentation)
* **[Project Token Authentication](/gh-aw/patterns/project-ops/#project-token-authentication)**
* **[Safe Outputs Reference](/gh-aw/reference/safe-outputs/)**
* **[Projects & Monitoring](/gh-aw/patterns/monitoring/)**
* **[IssueOps](/gh-aw/patterns/issue-ops/)**
# ResearchPlanAssignOps
> Orchestrate deep research, structured planning, and automated assignment to drive AI-powered development cycles from insight to merged PR
ResearchPlanAssignOps is a four-phase development pattern that moves from automated discovery to merged code with human control at every decision point. A research agent surfaces insights, a planning agent converts them into actionable issues, a coding agent implements the work, and a human reviews and merges.
## The Four Phases
[Section titled “The Four Phases”](#the-four-phases)
```plaintext
Research → Plan → Assign → Merge
```
Each phase produces a concrete artifact consumed by the next, and every transition is a human checkpoint.
### Phase 1: Research
[Section titled “Phase 1: Research”](#phase-1-research)
A scheduled workflow investigates the codebase from a specific angle and publishes its findings as a GitHub discussion. The discussion is the contract between the research phase and everything that follows—it contains the analysis, recommendations, and context a planner needs.
The [`go-fan`](https://github.com/github/gh-aw/blob/main/.github/workflows/go-fan.md) workflow is a live example: it runs each weekday, picks one Go dependency, compares current usage against upstream best practices, and creates a `[go-fan]` discussion under the `audits` category.
```aw
---
name: Go Fan
on:
schedule:
- cron: "0 7 * * 1-5"
workflow_dispatch:
engine: claude
safe-outputs:
create-discussion:
title-prefix: "[go-fan] "
category: "audits"
max: 1
close-older-discussions: true
tools:
cache-memory: true
github:
toolsets: [default]
---
Analyze today's Go dependency. Compare current usage in this
repository against upstream best practices and recent releases.
Save a summary to scratchpad/mods/ and create a discussion
with findings and improvement recommendations.
```
The research agent uses `cache-memory` to track which modules have been reviewed so it rotates through them systematically across runs.
### Phase 2: Plan
[Section titled “Phase 2: Plan”](#phase-2-plan)
After reading the research discussion, a developer triggers the `/plan` command on it. The [`plan`](https://github.com/github/gh-aw/blob/main/.github/workflows/plan.md) workflow reads the discussion, extracts concrete work items, and creates up to five sub-issues grouped under a parent tracking issue.
```plaintext
/plan focus on the quick wins and API simplifications
```
The planner formats each sub-issue for a coding agent: a clear objective, the files to touch, step-by-step implementation guidance, and acceptance criteria. Issues are tagged `[plan]` and `ai-generated`.
Tip
The `/plan` command accepts inline guidance. Steer it toward high-priority findings or away from lower-priority ones before it generates issues.
### Phase 3: Assign
[Section titled “Phase 3: Assign”](#phase-3-assign)
With well-scoped issues in hand, the developer [assigns them to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) for automated implementation. Copilot opens a pull request and posts progress updates as it works.
Issues can be assigned individually through the GitHub UI, or pre-assigned in bulk via an orchestrator workflow:
```aw
---
name: Auto-assign plan issues to Copilot
on:
issues:
types: [labeled]
engine: copilot
safe-outputs:
assign-to-user:
target: "*"
add-comment:
target: "*"
---
When an issue is labeled `plan` and has no assignee,
assign it to Copilot and add a comment indicating
automated assignment.
```
For multi-issue plans, assignments can run in parallel—Copilot works independently on each issue and opens separate PRs.
### Phase 4: Merge
[Section titled “Phase 4: Merge”](#phase-4-merge)
Copilot’s pull request is reviewed by a human maintainer. The maintainer checks correctness, runs tests, and merges. The tracking issue created in Phase 2 closes automatically when all sub-issues are resolved.
## End-to-End Example
[Section titled “End-to-End Example”](#end-to-end-example)
The following trace shows the full cycle using `go-fan` as the research driver.
**Monday 7 AM** — `go-fan` runs and creates a discussion:
> **\[go-fan] Go Module Review: spf13/cobra**
>
> Current usage creates a new `Command` per invocation. cobra v1.8 introduced `SetContext` for propagating cancellation. Quick wins: pass context through subcommands, use `PersistentPreRunE` for shared setup.
**Monday afternoon** — Developer reads the discussion and types:
```plaintext
/plan
```
The planner creates a parent tracking issue `[plan] cobra improvements` with three sub-issues:
* `[plan] Pass context through subcommands using cobra SetContext`
* `[plan] Refactor shared setup into PersistentPreRunE`
* `[plan] Add context cancellation tests`
**Monday afternoon** — Developer assigns the first two issues to Copilot. Both open PRs within minutes.
**Tuesday** — Developer reviews PRs, requests a minor change on one, approves the other. Both merge by end of day. The tracking issue closes.
## Workflow Configuration Patterns
[Section titled “Workflow Configuration Patterns”](#workflow-configuration-patterns)
### Research: produce one discussion per run
[Section titled “Research: produce one discussion per run”](#research-produce-one-discussion-per-run)
```aw
safe-outputs:
create-discussion:
expires: 1d
category: "research"
max: 1
close-older-discussions: true
```
`close-older-discussions: true` prevents discussion accumulation—only the latest finding stays open for the planner.
### Research: maintain memory across runs
[Section titled “Research: maintain memory across runs”](#research-maintain-memory-across-runs)
```aw
tools:
cache-memory: true
```
Use `cache-memory` to track state between scheduled runs—which items have been reviewed, trend data, or historical baselines.
### Plan: issue grouping
[Section titled “Plan: issue grouping”](#plan-issue-grouping)
```aw
safe-outputs:
create-issue:
expires: 2d
title-prefix: "[plan] "
labels: [plan, ai-generated]
max: 5
group: true
```
`group: true` creates a parent tracking issue automatically. Do not create the parent manually—the workflow handles it.
### Assign: pre-assign via `assignees`
[Section titled “Assign: pre-assign via assignees”](#assign-pre-assign-via-assignees)
For research workflows that produce self-contained, well-scoped issues, skip the manual plan phase and assign directly:
```aw
safe-outputs:
create-issue:
title-prefix: "[fix] "
labels: [ai-generated]
assignees: copilot
```
The `duplicate-code-detector` workflow uses this approach—duplication fixes are narrow enough that a planning phase adds no value.
## When to Use ResearchPlanAssignOps
[Section titled “When to Use ResearchPlanAssignOps”](#when-to-use-researchplanassignops)
This pattern fits when:
* The scope of work is unknown until analysis runs
* Issues need human prioritization before implementation
* Research findings vary in quality (some runs find nothing actionable)
* Multiple work items can be executed in parallel
Prefer a simpler pattern when:
* The work is already well-defined (use [IssueOps](/gh-aw/patterns/issue-ops/))
* Issues can go directly to Copilot without review (use the `assignees: copilot` shortcut in your research workflow)
* Work spans multiple repositories (use [MultiRepoOps](/gh-aw/patterns/multi-repo-ops/))
## Existing Workflows
[Section titled “Existing Workflows”](#existing-workflows)
| Phase | Workflow | Description |
| -------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Research | [`go-fan`](https://github.com/github/gh-aw/blob/main/.github/workflows/go-fan.md) | Daily Go dependency analysis with best-practice comparison |
| Research | [`copilot-cli-deep-research`](https://github.com/github/gh-aw/blob/main/.github/workflows/copilot-cli-deep-research.md) | Weekly analysis of Copilot CLI feature usage |
| Research | [`static-analysis-report`](https://github.com/github/gh-aw/blob/main/.github/workflows/static-analysis-report.md) | Daily security scan with clustered findings |
| Research | [`duplicate-code-detector`](https://github.com/github/gh-aw/blob/main/.github/workflows/duplicate-code-detector.md) | Daily semantic duplication analysis (auto-assigns) |
| Plan | [`plan`](https://github.com/github/gh-aw/blob/main/.github/workflows/plan.md) | `/plan` slash command—converts issues or discussions into sub-issues |
| Assign | GitHub UI / workflow | [Assign issues to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) for automated PR creation |
## Related Patterns
[Section titled “Related Patterns”](#related-patterns)
* **[TaskOps](/gh-aw/patterns/task-ops/)** — Detailed breakdown of the three-phase Research → Plan → Assign strategy with configuration guidance
* **[Orchestration](/gh-aw/patterns/orchestration/)** — Fan out work across multiple worker workflows
* **[DailyOps](/gh-aw/patterns/daily-ops/)** — Scheduled incremental improvements without a separate planning phase
* **[DispatchOps](/gh-aw/patterns/dispatch-ops/)** — Manually triggered research and one-off investigations
# SideRepoOps
> The simple, no-friction way to get started with reporting agents - use a separate repository to run agentic workflows that target your main codebase
SideRepoOps is a development pattern where you run agentic workflows from a separate “side” repository that targets your main codebase. This keeps AI-generated issues, comments, and workflow runs isolated from your main repository, providing cleaner separation between automation infrastructure and your production code.
## When to Use SideRepoOps
[Section titled “When to Use SideRepoOps”](#when-to-use-siderepoops)
SideRepoOps is ideal when you’re new to agentic workflows and want a low-risk way to experiment — no changes needed to your main repository, AI-generated issues stay separate from organic development, and sensitive automation logic remains in a private repository. Use it for workflow experimentation, centralized automation across multiple repositories, or managing workflows for repositories you don’t directly control.
## How It Differs from MultiRepoOps
[Section titled “How It Differs from MultiRepoOps”](#how-it-differs-from-multirepoops)
While [MultiRepoOps](/gh-aw/patterns/multi-repo-ops/) runs workflows **from** your main repository that create resources **in** other repositories, SideRepoOps inverts this pattern:
| Pattern | Workflow Location | Target Repository | Use Case |
| ---------------- | ------------------ | ------------------ | ---------------------------------------------------- |
| **MultiRepoOps** | Main repository | Other repositories | Coordinate work across related projects |
| **SideRepoOps** | Separate side repo | Main repository | Isolate automation infrastructure from main codebase |
**Example Architecture:**
```text
┌─────────────────┐ ┌──────────────────┐
│ Side Repo │ │ Main Repo │
│ (workflows) │ ────────>│ (target code) │
│ │ Uses │ │
│ - automation/ │ PAT │ - src/ │
│ - .github/ │ │ - tests/ │
│ workflows/ │ │ - docs/ │
└─────────────────┘ └──────────────────┘
```
Tip
Testing with TrialOps Before deploying SideRepoOps workflows to production, use [TrialOps](/gh-aw/patterns/trial-ops/) to test them in isolated trial repositories. This lets you validate behavior and iterate on prompts without creating real issues in your repositories.
## Setup Requirements
[Section titled “Setup Requirements”](#setup-requirements)
### 1. Create the Side Repository
[Section titled “1. Create the Side Repository”](#1-create-the-side-repository)
Create a new repository (public or private) to host your agentic workflows. No code is required - just workflows.
```bash
gh repo create my-org/my-project-automation --private
gh repo clone my-org/my-project-automation
cd my-project-automation
```
### 2. Configure Personal Access Token (PAT)
[Section titled “2. Configure Personal Access Token (PAT)”](#2-configure-personal-access-token-pat)
Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new?name=GH_AW_MAIN_REPO_TOKEN\&description=GitHub+Agentic+Workflows+-+Cross-repository+access\&contents=read\&issues=write\&pull_requests=write) (this link pre-fills the token name, description, and permissions) with repository access to your main repository and grant these permissions: **Contents** (Read), **Issues** (Read+Write), **Pull requests** (Read+Write), and **Metadata** (Read).
For classic PATs, use the `repo` scope. Store the token as a secret:
```bash
gh aw secrets set GH_AW_MAIN_REPO_TOKEN --value "YOUR_PAT_HERE"
```
Tip
Security Best Practice Use fine-grained PATs scoped to specific repositories. Set expiration dates and rotate tokens regularly.
### 3. Enable GitHub Actions
[Section titled “3. Enable GitHub Actions”](#3-enable-github-actions)
Ensure GitHub Actions is enabled in your side repository settings.
## Workflow Configuration
[Section titled “Workflow Configuration”](#workflow-configuration)
### Basic SideRepoOps Workflow
[Section titled “Basic SideRepoOps Workflow”](#basic-siderepoops-workflow)
Create a workflow in your side repository that targets the main repository:
```aw
---
on:
workflow_dispatch:
inputs:
task_description:
description: "What should the agent work on?"
required: true
engine: copilot
permissions:
contents: read
safe-outputs:
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}
create-issue:
target-repo: "my-org/main-repo"
title-prefix: "[automation] "
labels: [automation, ai-generated]
create-pull-request:
target-repo: "my-org/main-repo"
base-branch: main
tools:
github:
mode: remote
toolsets: [repos, issues, pull_requests]
---
# Side Repository Automation
You are running from a separate automation repository and need to work on the main codebase.
**Target Repository**: my-org/main-repo
**Task**: {{inputs.task_description}}
**Instructions**:
1. Use GitHub tools to explore the main repository (search code, review issues/PRs, check documentation)
2. Complete the task by creating issues or PRs with clear descriptions and appropriate labels
3. All resources should include "[automation]" prefix, link to context, and have labels: automation, ai-generated
Remember: The workflow runs in the automation repo, but all outputs go to the main repo.
```
### Scheduled Monitoring from Side Repo
[Section titled “Scheduled Monitoring from Side Repo”](#scheduled-monitoring-from-side-repo)
Run scheduled checks on your main repository:
```aw
---
on: weekly on monday
engine: copilot
permissions:
contents: read
safe-outputs:
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}
create-issue:
target-repo: "my-org/main-repo"
max: 5
labels: [weekly-check, automation]
tools:
github:
mode: remote
toolsets: [repos, issues, pull_requests, actions]
---
# Weekly Repository Health Check
Analyze the main repository and create issues for any concerns.
**Target Repository**: my-org/main-repo
Check for stale PRs (>30 days), failed CI runs on main, outdated dependencies with security advisories, documentation gaps, and high-complexity code needing refactoring.
Create issues for significant findings with clear problem descriptions, links to relevant code/PRs, suggested next steps, and priority labels.
```
## GitHub Tools Configuration
[Section titled “GitHub Tools Configuration”](#github-tools-configuration)
When workflows run in a side repository, you must enable GitHub tools with `mode: remote` to access the main repository:
```yaml
tools:
github:
mode: remote # Required for cross-repo access
toolsets: [repos, issues, pull_requests]
```
Available toolsets: **repos** (files, code, commits, releases), **issues** (list/search/read), **pull\_requests** (list/search/read), **actions** (workflow runs/artifacts), and **context** (repository metadata).
Note
GitHub tools with `mode: local` (Docker-based) can only access the repository where the workflow is running. Always use `mode: remote` for SideRepoOps.
## Private Repository Access
[Section titled “Private Repository Access”](#private-repository-access)
For private repositories, your PAT must have explicit repository access with appropriate permission scopes (contents, issues, pull\_requests):
```yaml
safe-outputs:
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }} # Required for private repos
create-issue:
target-repo: "my-org/private-main-repo"
tools:
github:
mode: remote
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }} # Explicit token for tools
toolsets: [repos, issues, pull_requests]
```
Caution
The default `GITHUB_TOKEN` provided by GitHub Actions cannot access other repositories. You **must** use a PAT with appropriate permissions for SideRepoOps.
## Common Patterns
[Section titled “Common Patterns”](#common-patterns)
### Triage from Side Repository
[Section titled “Triage from Side Repository”](#triage-from-side-repository)
Run triage workflows on main repository issues:
```aw
---
on: every 6h
safe-outputs:
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}
add-labels:
target-repo: "my-org/main-repo"
add-comment:
target-repo: "my-org/main-repo"
tools:
github:
mode: remote
toolsets: [issues]
---
# Triage Main Repository Issues
Find unlabeled issues in my-org/main-repo and add appropriate labels.
```
### Code Quality Monitoring
[Section titled “Code Quality Monitoring”](#code-quality-monitoring)
Monitor main repository for quality issues:
```aw
---
on: weekly on monday
safe-outputs:
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}
create-issue:
target-repo: "my-org/main-repo"
labels: [code-quality, automation]
max: 10
tools:
github:
mode: remote
toolsets: [repos, pull_requests]
---
# Weekly Code Quality Review
Analyze recent commits and PRs in my-org/main-repo for:
- Code complexity issues
- Missing test coverage
- Outdated dependencies
- Security vulnerabilities
Create issues for significant findings.
```
### Documentation Sync
[Section titled “Documentation Sync”](#documentation-sync)
Keep documentation synchronized from side repository:
```aw
---
on:
workflow_dispatch:
inputs:
docs_path:
description: "Path to documentation folder"
default: "docs/"
safe-outputs:
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}
create-pull-request:
target-repo: "my-org/main-repo"
base-branch: main
title-prefix: "[docs] "
tools:
github:
mode: remote
toolsets: [repos]
---
# Documentation Synchronization
Review documentation in {{inputs.docs_path}} of my-org/main-repo.
Create a PR with suggested improvements.
```
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
### Authentication Failures
[Section titled “Authentication Failures”](#authentication-failures)
If you see “Resource not accessible by integration” errors, verify your PAT has access to the target repository, check permissions include required scopes, ensure the PAT hasn’t expired, and confirm `github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}` is configured (not `GITHUB_TOKEN`).
### GitHub Tools Not Working
[Section titled “GitHub Tools Not Working”](#github-tools-not-working)
If the agent cannot read files from the main repository, use `mode: remote` for GitHub tools and provide an explicit token if the main repo is private:
```yaml
tools:
github:
mode: remote
github-token: ${{ secrets.GH_AW_MAIN_REPO_TOKEN }}
toolsets: [repos]
```
### Issues Created in Wrong Repository
[Section titled “Issues Created in Wrong Repository”](#issues-created-in-wrong-repository)
Always specify `target-repo` in safe outputs. Without it, safe outputs default to the repository where the workflow runs:
```yaml
safe-outputs:
create-issue:
target-repo: "my-org/main-repo"
```
### Unwanted Timeline Items
[Section titled “Unwanted Timeline Items”](#unwanted-timeline-items)
If automation creates unwanted cross-references in your main repository’s timelines (e.g., `#123` references creating “mentioned in…” entries), use `allowed-github-references` to control reference escaping:
```yaml
safe-outputs:
allowed-github-references: [] # Escape all references
create-issue:
target-repo: "my-org/main-repo"
```
This prevents GitHub from auto-linking issue numbers and creating timeline entries. See [Text Sanitization](/gh-aw/reference/safe-outputs/#text-sanitization-allowed-domains-allowed-github-references) for details.
## Advanced Topics
[Section titled “Advanced Topics”](#advanced-topics)
### Multi-Target SideRepoOps
[Section titled “Multi-Target SideRepoOps”](#multi-target-siderepoops)
Manage multiple main repositories from one side repository:
```aw
---
on:
workflow_dispatch:
inputs:
target_repo:
description: "Target repository (owner/repo)"
required: true
task:
description: "Task description"
required: true
safe-outputs:
github-token: ${{ secrets.GH_AW_MULTI_REPO_PAT }}
create-issue:
target-repo: ${{ inputs.target_repo }} # Dynamic target
---
# Multi-Repository Automation
Work on user-specified repository: {{inputs.target_repo}}
```
### Using GitHub Apps
[Section titled “Using GitHub Apps”](#using-github-apps)
For enhanced security, use GitHub Apps instead of PATs.
See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication) for complete configuration including repository scoping options.
### Bidirectional Sync
[Section titled “Bidirectional Sync”](#bidirectional-sync)
Create workflows in main repository that report back to side repository:
**In main-repo:**
```yaml
on:
issues:
types: [opened, labeled]
safe-outputs:
github-token: ${{ secrets.GH_AW_SIDE_REPO_TOKEN }}
add-comment:
target-repo: "my-org/automation-repo"
```
This creates a feedback loop where the side repository tracks automation effectiveness.
## Related
[Section titled “Related”](#related)
**Patterns**: [MultiRepoOps](/gh-aw/patterns/multi-repo-ops/) · [Orchestration](/gh-aw/patterns/orchestration/) · [IssueOps](/gh-aw/patterns/issue-ops/)
**Reference**: [Cross-Repository Operations](/gh-aw/reference/cross-repository/) · [Safe Outputs](/gh-aw/reference/safe-outputs/) · [GitHub Tools](/gh-aw/reference/github-tools/) · [Authentication](/gh-aw/reference/auth/) · [Reusing Workflows](/gh-aw/guides/packaging-imports/)
# SpecOps
> Maintain and propagate W3C-style specifications using agentic workflows
SpecOps is a pattern for maintaining formal specifications using agentic workflows. It leverages the [`w3c-specification-writer` agent](https://github.com/github/gh-aw/blob/main/.github/agents/w3c-specification-writer.agent.md) to create W3C-style specifications with RFC 2119 keywords (MUST, SHALL, SHOULD, MAY) and automatically propagates changes to consuming implementations across repositories.
## How SpecOps Works
[Section titled “How SpecOps Works”](#how-specops-works)
1. **Update specification** — Trigger a workflow with the `w3c-specification-writer` agent to edit the spec document (RFC 2119 keywords, version bump, change log).
2. **Review changes** — Approve the specification pull request.
3. **Propagate automatically** — On merge, workflows detect updates and create PRs in consuming repositories (like [gh-aw-mcpg](https://github.com/github/gh-aw-mcpg)) to maintain compliance.
4. **Verify compliance** — Test generation workflows update compliance test suites against the new requirements.
## Update Specifications
[Section titled “Update Specifications”](#update-specifications)
Create a workflow to update specifications using the [`w3c-specification-writer` agent](https://github.com/github/gh-aw/blob/main/.github/agents/w3c-specification-writer.agent.md):
```yaml
---
name: Update MCP Gateway Spec
on:
workflow_dispatch:
inputs:
change_description:
description: 'What needs to change in the spec?'
required: true
type: string
engine: copilot
strict: true
safe-outputs:
create-pull-request:
title-prefix: "[spec] "
labels: [documentation, specification]
tools:
edit:
bash:
---
# Specification Update Workflow
Update the MCP Gateway specification using the w3c-specification-writer agent.
**Change Request**: ${{ inputs.change_description }}
## Your Task
1. Review the current specification at `docs/src/content/docs/reference/mcp-gateway.md`
2. Apply the requested changes following W3C conventions:
- Use RFC 2119 keywords (MUST, SHALL, SHOULD, MAY)
- Update version number (major/minor/patch)
- Add entry to Change Log section
- Update Status of This Document if needed
3. Ensure changes maintain clear conformance requirements, testable specifications, and complete examples
4. Create a pull request with the updated specification
```
## Propagate Changes
[Section titled “Propagate Changes”](#propagate-changes)
After specification updates merge, automatically propagate changes to consuming repositories:
```yaml
---
name: Propagate Spec Changes
on:
push:
branches:
- main
paths:
- 'docs/src/content/docs/reference/mcp-gateway.md'
engine: copilot
strict: true
safe-outputs:
create-pull-request:
title-prefix: "[spec-update] "
labels: [dependencies, specification]
tools:
github:
toolsets: [repos, pull_requests]
edit:
bash:
---
# Specification Propagation Workflow
The MCP Gateway specification has been updated. Propagate changes to consuming repositories.
## Consuming Repositories
- **gh-aw-mcpg**: Update implementation compliance, schemas, and tests
- **gh-aw**: Update MCP gateway validation and documentation
## Your Task
1. Read the latest specification version and change log
2. Identify breaking changes and new requirements
3. For each consuming repository:
- Update implementation to match spec
- Run tests to verify compliance
- Create pull request with changes
4. Create tracking issue linking all PRs
```
## Specification Structure
[Section titled “Specification Structure”](#specification-structure)
W3C-style specifications require: Abstract, Status, Introduction, Conformance, numbered technical sections with RFC 2119 keywords, Compliance testing, References, and a Change log.
**Example RFC 2119 usage**:
```markdown
## 3. Gateway Configuration
The gateway MUST validate all configuration fields before startup.
The gateway SHOULD log validation errors with field names.
The gateway MAY cache validated configurations.
```
See the [`w3c-specification-writer` agent](https://github.com/github/gh-aw/blob/main/.github/agents/w3c-specification-writer.agent.md) for a complete template and guidelines.
## Semantic Versioning
[Section titled “Semantic Versioning”](#semantic-versioning)
| Bump | When |
| ----------------- | --------------------------------- |
| **Major (X.0.0)** | Breaking changes |
| **Minor (0.Y.0)** | New features, backward-compatible |
| **Patch (0.0.Z)** | Bug fixes, clarifications |
The [MCP Gateway Specification](/gh-aw/reference/mcp-gateway/) is a live example — maintained by the `layout-spec-maintainer` workflow and implemented in [gh-aw-mcpg](https://github.com/github/gh-aw-mcpg).
## Related Patterns
[Section titled “Related Patterns”](#related-patterns)
* **[MultiRepoOps](/gh-aw/patterns/multi-repo-ops/)** — Cross-repository coordination
# TaskOps Strategy
> Scaffold AI-powered code improvements with research agents, planning agents, and copilot execution while keeping developers in control
The TaskOps strategy is a scaffolded approach to using AI agents for systematic code improvements. This strategy keeps developers in the driver’s seat by providing clear decision points at each phase while leveraging AI agents to handle the heavy lifting of research, planning, and implementation.
## How TaskOps Works
[Section titled “How TaskOps Works”](#how-taskops-works)
The strategy follows three distinct phases:
### Phase 1: Research
[Section titled “Phase 1: Research”](#phase-1-research)
A research agent (typically scheduled daily or weekly) investigates the repository under a specific angle and generates a comprehensive report. Using advanced Model Context Protocol (MCP) tools for deep analysis (static analysis, logging data, semantic search), it examines the codebase from a specific perspective and creates a detailed discussion or issue with findings, recommendations, and supporting data. Cache memory maintains historical context to track trends over time.
### Phase 2: Plan
[Section titled “Phase 2: Plan”](#phase-2-plan)
The developer reviews the research report to determine if worthwhile improvements were identified. If the findings merit action, the developer invokes a planner agent to convert the research into specific, actionable issues. The planner splits complex work into smaller, focused tasks optimized for copilot agent success, formatting each issue with clear objectives, file paths, acceptance criteria, and implementation guidance.
### Phase 3: Assign
[Section titled “Phase 3: Assign”](#phase-3-assign)
The developer reviews the generated issues and decides which ones to execute. Approved issues are [assigned to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) for automated implementation and can be executed sequentially or in parallel depending on dependencies. Copilot creates a pull request with the implementation for developer review and merging.
## When to Use TaskOps
[Section titled “When to Use TaskOps”](#when-to-use-taskops)
Use this strategy when code improvements require systematic investigation before action, work needs to be broken down for optimal AI agent execution, or when research findings may vary in priority and require developer oversight at each phase.
## Example: Static Analysis → Plan → Fix
[Section titled “Example: Static Analysis → Plan → Fix”](#example-static-analysis--plan--fix)
**Research Phase**: [`static-analysis-report.md`](https://github.com/github/gh-aw/blob/main/.github/workflows/static-analysis-report.md)
Runs daily to scan all agentic workflows with security tools (zizmor, poutine, actionlint), creating a comprehensive security discussion with clustered findings by tool and issue type, severity assessment, fix prompts, and historical trends.
**Plan Phase**: Developer reviews the security discussion and uses the `/plan` command to convert high-priority findings into issues.
**Assign Phase**: Developer [assigns generated issues to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) for automated fixes.
## Example: Duplicate Code Detection → Plan → Refactor
[Section titled “Example: Duplicate Code Detection → Plan → Refactor”](#example-duplicate-code-detection--plan--refactor)
**Research Phase**: [`duplicate-code-detector.md`](https://github.com/github/gh-aw/blob/main/.github/workflows/duplicate-code-detector.md)
Runs daily using Serena MCP for semantic code analysis to identify exact, structural, and functional duplication. Creates one issue per distinct pattern (max 3 per run) that are [assigned to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) (via `assignees: copilot` in workflow config) since duplication fixes are typically straightforward.
**Plan Phase**: Since issues are already well-scoped, the plan phase is implicit in the research output.
**Assign Phase**: Issues are created and [assigned to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot) (via `assignees: copilot`) for automated refactoring.
## Customization
[Section titled “Customization”](#customization)
Adapt the TaskOps strategy by customizing the research focus (static analysis, performance metrics, documentation quality, security, code duplication, test coverage), frequency (daily, weekly, on-demand), report format (discussions vs issues), planning approach (automatic vs manual), and assignment method (pre-assign via `assignees: copilot` in workflow config, [manual assignment through GitHub UI](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot), or mixed).
## Limitations
[Section titled “Limitations”](#limitations)
The three-phase approach takes longer than direct execution and requires developers to review research reports and generated issues. Research agents may flag issues that don’t require action (false positives), and multiple phases require workflow coordination and clear handoffs. Research agents often need specialized MCPs (Serena, Tavily, etc.).
## Related Strategies
[Section titled “Related Strategies”](#related-strategies)
* **[Orchestration](/gh-aw/patterns/orchestration/)**: Coordinate multiple TaskOps cycles toward a shared goal
* **[Threat Detection](/gh-aw/reference/threat-detection/)**: Continuous monitoring without planning phase
* **[Custom Safe Outputs](/gh-aw/reference/custom-safe-outputs/)**: Create custom actions for plan phase
# TrialOps
> Test and validate agentic workflows in isolated trial repositories before deploying to production
TrialOps uses temporary trial repositories for safely validating and iterating on workflows before deployment to target repositories. The `trial` command creates isolated private repos where workflows execute and capture safe outputs (issues, PRs, comments) without affecting your actual codebase.
## How Trial Mode Works
[Section titled “How Trial Mode Works”](#how-trial-mode-works)
```bash
gh aw trial githubnext/agentics/weekly-research
```
The CLI creates a temporary private repository (default: `gh-aw-trial`), installs and executes the workflow via `workflow_dispatch`. Results are saved locally in `trials/weekly-research.DATETIME-ID.json`, in the trial repository on GitHub, and summarized in the console.
## Repository Modes
[Section titled “Repository Modes”](#repository-modes)
| Mode | Flag | Description |
| ------- | ---------------------------------- | ----------------------------------------------------------------- |
| Default | (none) | `github.repository` points to your repo; outputs go to trial repo |
| Direct | `--repo myorg/test-repo` | Runs in specified repo; creates real issues/PRs there |
| Logical | `--logical-repo myorg/target-repo` | Simulates running against specified repo; outputs in trial repo |
| Clone | `--clone-repo myorg/real-repo` | Clones repo contents so workflows can analyze actual code |
## Basic Usage
[Section titled “Basic Usage”](#basic-usage)
### Dry-Run Mode
[Section titled “Dry-Run Mode”](#dry-run-mode)
Preview what would happen without executing workflows or creating repositories:
```bash
gh aw trial ./my-workflow.md --dry-run
```
### Single Workflow
[Section titled “Single Workflow”](#single-workflow)
```bash
gh aw trial githubnext/agentics/weekly-research # From GitHub
gh aw trial ./my-workflow.md # Local file
```
### Multiple Workflows
[Section titled “Multiple Workflows”](#multiple-workflows)
Compare workflows side-by-side with combined results:
```bash
gh aw trial githubnext/agentics/daily-plan githubnext/agentics/weekly-research
```
Outputs: individual result files plus `trials/combined-results.DATETIME.json`.
### Repeated Trials
[Section titled “Repeated Trials”](#repeated-trials)
Test consistency by running multiple times:
```bash
gh aw trial githubnext/agentics/my-workflow --repeat 3
```
### Custom Trial Repository
[Section titled “Custom Trial Repository”](#custom-trial-repository)
```bash
gh aw trial githubnext/agentics/my-workflow --host-repo my-custom-trial
gh aw trial ./my-workflow.md --host-repo . # Use current repo
```
## Advanced Patterns
[Section titled “Advanced Patterns”](#advanced-patterns)
### Issue Context
[Section titled “Issue Context”](#issue-context)
Provide issue context for issue-triggered workflows:
```bash
gh aw trial githubnext/agentics/triage-workflow \
--trigger-context "https://github.com/myorg/repo/issues/123"
```
### Append Instructions
[Section titled “Append Instructions”](#append-instructions)
Test workflow responses to additional constraints without modifying the source:
```bash
gh aw trial githubnext/agentics/my-workflow \
--append "Focus on security issues and create detailed reports."
```
### Cleanup Options
[Section titled “Cleanup Options”](#cleanup-options)
```bash
gh aw trial ./my-workflow.md --delete-host-repo-after # Delete after completion
gh aw trial ./my-workflow.md --force-delete-host-repo-before # Clean slate before running
```
## Understanding Trial Results
[Section titled “Understanding Trial Results”](#understanding-trial-results)
Results are saved in `trials/*.json` with workflow runs, issues, PRs, and comments viewable in the trial repository’s Actions and Issues tabs.
**Result file structure:**
```json
{
"workflow_name": "weekly-research",
"run_id": "12345678",
"safe_outputs": {
"issues_created": [{
"number": 5,
"title": "Research quantum computing trends",
"url": "https://github.com/user/gh-aw-trial/issues/5"
}]
},
"agentic_run_info": {
"duration_seconds": 45,
"token_usage": 2500
}
}
```
**Success indicators:** Green checkmark, expected outputs created, no errors in logs.
**Common issues:**
* **Workflow dispatch failed** - Add `workflow_dispatch` trigger
* **No safe outputs** - Configure safe outputs in workflow
* **Permission errors** - Verify API keys
* **Timeout** - Use `--timeout 60` (minutes)
## Comparing Multiple Workflows
[Section titled “Comparing Multiple Workflows”](#comparing-multiple-workflows)
Run multiple workflows to compare quality, quantity, performance, and consistency:
```bash
gh aw trial v1.md v2.md v3.md --repeat 2
cat trials/combined-results.*.json | jq '.results[] | {workflow: .workflow_name, issues: .safe_outputs.issues_created | length}'
```
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [SideRepoOps](/gh-aw/patterns/side-repo-ops/) - Run workflows from separate repositories
* [MultiRepoOps](/gh-aw/patterns/multi-repo-ops/) - Coordinate across multiple repositories
* [Orchestration](/gh-aw/patterns/orchestration/) - Orchestrate multi-issue initiatives
* [CLI Commands](/gh-aw/setup/cli/) - Complete CLI reference
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Configuration options
* [Workflow Triggers](/gh-aw/reference/triggers/) - Including workflow\_dispatch
* [Security Best Practices](/gh-aw/introduction/architecture/) - Authentication and security
# Assign to Copilot
> Programmatically assign GitHub Copilot coding agent to issues and pull requests
This page describes how to programmatically assign the [GitHub Copilot coding agent](https://docs.github.com/en/copilot/concepts/agents/coding-agent/about-coding-agent) to issues or pull requests using the `assign-to-agent` safe output. This automates the [standard GitHub workflow for assigning issues to Copilot](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr#assigning-an-issue-to-copilot).
## When to Use
[Section titled “When to Use”](#when-to-use)
Use `assign-to-agent` when you need to programmatically assign Copilot coding agent to **existing** issues or PRs through workflow automation.
If you’re creating new issues and want to assign Copilot coding agent immediately, use `assignees: copilot` in your [`create-issue`](/gh-aw/reference/safe-outputs/#issue-creation-create-issue) configuration instead.
## Configuration
[Section titled “Configuration”](#configuration)
```yaml
safe-outputs:
assign-to-agent:
name: "copilot" # default agent (default: "copilot")
model: "claude-opus-4.6" # default AI model (default: "auto")
custom-agent: "agent-id" # default custom agent ID (optional)
custom-instructions: "..." # default custom instructions (optional)
allowed: [copilot] # restrict to specific agents (optional)
max: 1 # max assignments (default: 1)
target: "triggering" # "triggering" (default), "*", or number
target-repo: "owner/repo" # where the issue lives (cross-repository)
pull-request-repo: "owner/repo" # where the PR should be created (may differ from issue repo)
allowed-pull-request-repos: [owner/repo1, owner/repo2] # additional allowed PR repositories
base-branch: "develop" # target branch for PR (default: target repo's default branch)
github-token: ${{ secrets.GH_AW_AGENT_TOKEN }} # token for permissions
```
**Supported agents:** `copilot` (`copilot-swe-agent`)
## Target Issue or Pull Request
[Section titled “Target Issue or Pull Request”](#target-issue-or-pull-request)
The `target` parameter determines which issue or PR to assign the agent to:
* `target: "triggering"` (default) - Auto-resolves from `github.event.issue.number` or `github.event.pull_request.number`
* `target: "*"` - Requires explicit `issue_number` or `pull_number` in agent output
* `target: "123"` - Always uses issue/PR #123
## Cross-Repository PR Creation
[Section titled “Cross-Repository PR Creation”](#cross-repository-pr-creation)
Use `pull-request-repo` to create pull requests in a different repository than where the issue lives — useful when issues are tracked centrally but code lives elsewhere. The issue repository is determined by `target-repo` or defaults to the workflow’s repository.
`pull-request-repo` is automatically included in the allowed list; use `allowed-pull-request-repos` for additional repositories. Use `base-branch` to target a specific branch (defaults to the target repo’s default branch).
## Assignee Filtering
[Section titled “Assignee Filtering”](#assignee-filtering)
When an `allowed` list is configured, existing agent assignees not in the list are removed while regular user assignees are preserved.
## Authentication
[Section titled “Authentication”](#authentication)
This safe output requires a fine-grained PAT to authenticate the agent assignment operation. The default `GITHUB_TOKEN` lacks the necessary permissions.
### Using a Personal Access Token (PAT)
[Section titled “Using a Personal Access Token (PAT)”](#using-a-personal-access-token-pat)
The required token type and permissions depend on whether you own the repository or an organization owns it.
1. **Create the PAT** with **Repository permissions**: Actions, Contents, Issues, Pull requests (all Write).
* [User-owned repositories](https://github.com/settings/personal-access-tokens/new?name=GH_AW_AGENT_TOKEN\&description=GitHub+Agentic+Workflows+-+Agent+assignment\&actions=write\&contents=write\&issues=write\&pull_requests=write): Resource owner = your user account; Repository access = “Public repositories” or specific repos
* [Organization-owned repositories](https://github.com/settings/personal-access-tokens/new?name=GH_AW_AGENT_TOKEN\&description=GitHub+Agentic+Workflows+-+Agent+assignment\&actions=write\&contents=write\&issues=write\&pull_requests=write): Resource owner = the organization; Repository access = specific repositories that will use the workflow
2. Add to repository secrets:
```bash
gh aw secrets set GH_AW_AGENT_TOKEN --value "YOUR_AGENT_PAT"
```
### Using a GitHub App
[Section titled “Using a GitHub App”](#using-a-github-app)
GitHub App tokens are not supported for Copilot assignment
The Copilot assignment API only accepts fine-grained PATs — GitHub App installation tokens are rejected regardless of permissions. When `github-app:` is configured in `safe-outputs`, `assign-to-agent` falls back to: explicit `github-token:` in `assign-to-agent`, then `github-token:` at the `safe-outputs` level, then the magic secret chain (`GH_AW_AGENT_TOKEN || GH_AW_GITHUB_TOKEN || GITHUB_TOKEN`).
### Using a magic secret
[Section titled “Using a magic secret”](#using-a-magic-secret)
Alternatively, you can set the magic secret `GH_AW_AGENT_TOKEN` to a suitable PAT (see the above guide for creating one). This secret name is known to GitHub Agentic Workflows and does not need to be explicitly referenced in your workflow.
```bash
gh aw secrets set GH_AW_AGENT_TOKEN --value ""
```
Your browser doesn't support HTML5 video. Download the video [here](/gh-aw/videos/create-pat-org-agent.mp4).
Creating a fine-grained PAT for organization-owned repositories with permissions for agent assignment
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - All safe output configurations
* [Authentication Reference](/gh-aw/reference/auth/) - All tokens and secrets
* [IssueOps](/gh-aw/patterns/issue-ops/) - Issue-triggered workflow patterns
# Audit Commands
> Reference for the gh aw audit commands — single-run analysis, behavioral diff, and cross-run security reports.
The `gh aw audit` commands download workflow run artifacts and logs, analyze MCP tool usage and network behavior, and produce structured reports suited for security reviews, debugging, and feeding to AI agents.
## `gh aw audit `
[Section titled “gh aw audit \”](#gh-aw-audit-run-id-or-url)
Audit a single workflow run and generate a detailed Markdown report.
**Arguments:**
| Argument | Description |
| ----------------- | ------------------------------------------------------------------------------ |
| `` | A numeric run ID, GitHub Actions run URL, job URL, or job URL with step anchor |
**Accepted input formats:**
* Numeric run ID: `1234567890`
* Run URL: `https://github.com/owner/repo/actions/runs/1234567890`
* Job URL: `https://github.com/owner/repo/actions/runs/1234567890/job/9876543210`
* Job URL with step: `https://github.com/owner/repo/actions/runs/1234567890/job/9876543210#step:7:1`
* Short run URL: `https://github.com/owner/repo/runs/1234567890`
* GitHub Enterprise URLs using the same formats above
When a job URL is provided without a step anchor, the command extracts the output of the first failing step. When a step anchor is included, it extracts that specific step.
**Flags:**
| Flag | Default | Description |
| --------------------- | -------- | ------------------------------------------------------------------------------------- |
| `-o, --output ` | `./logs` | Directory to write downloaded artifacts and report files |
| `--json` | off | Output report as JSON to stdout |
| `--parse` | off | Run JavaScript parsers on agent and firewall logs, writing `log.md` and `firewall.md` |
| `--repo ` | auto | Specify repository when the run ID is not from a URL |
| `--verbose` | off | Print detailed progress information |
**Examples:**
```bash
gh aw audit 1234567890
gh aw audit https://github.com/owner/repo/actions/runs/1234567890
gh aw audit 1234567890 --parse
gh aw audit 1234567890 --json
gh aw audit 1234567890 -o ./audit-reports
gh aw audit 1234567890 --repo owner/repo
```
**Report sections** (rendered in Markdown or JSON): Overview, Comparison, Task/Domain, Behavior Fingerprint, Agentic Assessments, Metrics, Key Findings, Recommendations, Observability Insights, Performance Metrics, Engine Config, Prompt Analysis, Session Analysis, Safe Output Summary, MCP Server Health, Jobs, Downloaded Files, Missing Tools, Missing Data, Noops, MCP Failures, Firewall Analysis, Policy Analysis, Redacted Domains, Errors, Warnings, Tool Usage, MCP Tool Usage, Created Items.
## `gh aw audit diff [...]`
[Section titled “gh aw audit diff \ \ \[\...\]”](#gh-aw-audit-diff-base-run-id-comparison-run-id-comparison-run-id)
Compare behavior between workflow runs. Detects policy regressions, new unauthorized domains, behavioral drift, and changes in MCP tool usage or run metrics.
**Arguments:**
| Argument | Description |
| -------------------------- | --------------------------------------------------- |
| `` | Numeric run ID for the baseline run |
| `` | Numeric run ID for the comparison run |
| `[...]` | Additional run IDs to compare against the same base |
The base run is downloaded once and reused when multiple comparison runs are provided. Self-comparisons and duplicate run IDs are rejected.
**Flags:**
| Flag | Default | Description |
| --------------------- | -------- | ------------------------------------- |
| `--format ` | `pretty` | Output format: `pretty` or `markdown` |
| `--json` | off | Output diff as JSON |
| `--repo ` | auto | Specify repository |
| `-o, --output ` | `./logs` | Directory for downloaded artifacts |
| `--verbose` | off | Print detailed progress |
The diff output includes:
* New and removed network domains
* Domain status changes (allowed denied)
* Volume changes (request count changes above a 100% threshold)
* Anomaly flags (new denied domains, previously-denied domains now allowed)
* MCP tool invocation changes (new/removed tools, call count and error count diffs)
* Run metrics comparison (token usage, duration, turns)
* Token usage breakdown: input tokens, output tokens, cache read/write tokens, effective tokens, total API requests, and cache efficiency per run
**Output behavior with multiple comparisons:**
* `--json` outputs a single object for one comparison, or an array for multiple
* `--format pretty` and `--format markdown` separate multiple diffs with dividers
**Examples:**
```bash
gh aw audit diff 12345 12346
gh aw audit diff 12345 12346 12347 12348
gh aw audit diff 12345 12346 --format markdown
gh aw audit diff 12345 12346 --json
gh aw audit diff 12345 12346 --repo owner/repo
```
## `gh aw logs --format `
[Section titled “gh aw logs --format \”](#gh-aw-logs---format-fmt)
Generate a cross-run security and performance audit report across multiple recent workflow runs. This feature is built into the `gh aw logs` command via the `--format` flag.
**Flags:**
| Flag | Default | Description |
| --------------------- | ------------- | ------------------------------------------------------------------------ |
| `[workflow]` | all workflows | Filter by workflow name or filename (positional argument) |
| `-c, --count ` | 10 | Number of recent runs to analyze |
| `--last ` | — | Alias for `--count` |
| `--format ` | — | Output format: `markdown` or `pretty` (generates cross-run audit report) |
| `--json` | off | Output cross-run report as JSON (when combined with `--format`) |
| `--repo ` | auto | Specify repository |
| `-o, --output ` | `./logs` | Directory for downloaded artifacts |
| `--verbose` | off | Print detailed progress |
The report output includes an executive summary, domain inventory, metrics trends, MCP server health, and per-run breakdown. It detects cross-run anomalies such as domain access spikes, elevated MCP error rates, and connection rate changes.
**Examples:**
```bash
gh aw logs --format markdown
gh aw logs daily-repo-status --format markdown --count 10
gh aw logs agent-task --format markdown --last 5 --json
gh aw logs --format pretty
gh aw logs --format markdown --repo owner/repo --count 10
```
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Cost Management](/gh-aw/reference/cost-management/) — Track token usage and inference spend
* [Effective Tokens Specification](/gh-aw/reference/effective-tokens-specification/) — How effective tokens are computed
* [Network](/gh-aw/reference/network/) — Firewall and domain allow/deny configuration
* [MCP Gateway](/gh-aw/reference/mcp-gateway/) — MCP server health and debugging
* [CLI Commands](/gh-aw/setup/cli/) — Full CLI reference
# Authentication
> Comprehensive reference for GitHub Actions secrets, GitHub tokens and GitHub Apps in gh-aw
This page describes authentication settings for GitHub Agentic Workflows.
## Authenticating Your Coding Agent (AI Engine)
[Section titled “Authenticating Your Coding Agent (AI Engine)”](#authenticating-your-coding-agent-ai-engine)
You will need one of the following GitHub Actions secrets configured in your repository to authenticate the AI engine you choose:
* **Copilot** – Add [`COPILOT_GITHUB_TOKEN`](#copilot_github_token)
* **Claude by Anthropic** – Add [`ANTHROPIC_API_KEY`](#anthropic_api_key)
* **Codex by OpenAI** – Add [`OPENAI_API_KEY`](#openai_api_key)
* **Gemini by Google** – Add [`GEMINI_API_KEY`](#gemini_api_key)
Most workflows will run without any additional secrets or additional authentication.
## Additional Authentication
[Section titled “Additional Authentication”](#additional-authentication)
Some workflows need additional authentication. These can be tokens added as secrets and referenced in your workflow, or GitHub App can be used.
Workflows using the following **read** operations from GitHub require [Additional Authentication for GitHub Tools](/gh-aw/reference/github-tools/#additional-authentication-for-github-tools), via either a secret containing a PAT or GitHub App:
* **Read from multiple repositories**
* **Read from projects**
* **GitHub tools remote mode**
Workflows using the following features of [Safe Outputs](/gh-aw/reference/safe-outputs/) require additional authentication, via either a secret containing a PAT or GitHub App:
* [**Safe outputs writing cross-repo**](/gh-aw/reference/safe-outputs/#cross-repository-operations)
* [**Safe outputs assigning Copilot coding agent to issues/PRs**](/gh-aw/reference/assign-to-copilot/)
* [**Safe outputs updating GitHub Projects**](/gh-aw/patterns/project-ops/#project-token-authentication)
* [**Safe outputs triggering CI on PRs**](/gh-aw/reference/triggering-ci/)
Workflows using custom MCP tools or safe outputs may require additional authentication depending on the operations performed.
## How do I add a GitHub Actions secret to my repository?
[Section titled “How do I add a GitHub Actions secret to my repository?”](#how-do-i-add-a-github-actions-secret-to-my-repository)
You can add secrets manually in the GitHub UI or use the CLI for a streamlined experience.
### Adding secrets using the CLI
[Section titled “Adding secrets using the CLI”](#adding-secrets-using-the-cli)
```bash
gh aw secrets set COPILOT_GITHUB_TOKEN --value "YOUR_COPILOT_PAT"
```
You can also check existing secrets with:
```bash
gh aw secrets bootstrap
```
If you’re working in Codespaces, use the GitHub UI method below to add secrets.
### Adding secrets using the GitHub UI
[Section titled “Adding secrets using the GitHub UI”](#adding-secrets-using-the-github-ui)
1. Go to your repository on GitHub
2. Click on “Settings” → “Secrets and variables” → “Actions”
3. Click “New repository secret” and add the token name and value

## GitHub Actions secrets for AI engines
[Section titled “GitHub Actions secrets for AI engines”](#github-actions-secrets-for-ai-engines)
A reference for all GitHub Actions secrets used by GitHub Agentic Workflows for AI engine authentication:
### `COPILOT_GITHUB_TOKEN`
[Section titled “COPILOT\_GITHUB\_TOKEN”](#copilot_github_token)
If using Copilot as your AI engine, you need a GitHub Actions Secret set to a GitHub Personal Access Token (PAT) to authenticate Copilot CLI.
**Setup**:
[**Create a fine-grained PAT**](https://github.com/settings/personal-access-tokens/new?name=COPILOT_GITHUB_TOKEN\&description=GitHub+Agentic+Workflows+-+Copilot+engine+authentication\&user_copilot_requests=read) (this link pre-fills the token name, description, and Copilot Requests permission). Verify the following settings before generating:
1. **Resource owner** is your **user account**, not an organization.
2. Under **Permissions → Account permissions**, **Copilot Requests** is set to **Read**.
3. Click **Generate token** and copy the token value.
4. Add the PAT to your GitHub Actions repository secrets as `COPILOT_GITHUB_TOKEN`, either by CLI or GitHub UI.
```bash
gh aw secrets set COPILOT_GITHUB_TOKEN --value ""
```
**Troubleshooting**:
If your workflow fails at the Copilot inference step even with the token set, verify that the token owner’s account has an active Copilot license. See [Copilot License or Inference Access Issues](/gh-aw/troubleshooting/common-issues/#copilot-license-or-inference-access-issues) for a local diagnostic step.
***
### `ANTHROPIC_API_KEY`
[Section titled “ANTHROPIC\_API\_KEY”](#anthropic_api_key)
If using the Claude by Anthropic engine, you need to set a GitHub Actions secret `ANTHROPIC_API_KEY` to be an API key from Anthropic.
**Setup**:
1. Create an API key at
2. Add it to your repository secrets, either by CLI or GitHub UI:
```bash
gh aw secrets set ANTHROPIC_API_KEY --value "YOUR_ANTHROPIC_API_KEY"
```
See also [AI Engines](/gh-aw/reference/engines/#available-coding-agents) for additional configuration needed when using Claude with GitHub MCP.
***
### `OPENAI_API_KEY`
[Section titled “OPENAI\_API\_KEY”](#openai_api_key)
If using the Codex by OpenAI engine, you need to set a GitHub Actions secret `OPENAI_API_KEY` with an API key from OpenAI.
**Setup**:
1. Create an API key at
2. Add it to your repository secrets, either by CLI or GitHub UI:
```bash
gh aw secrets set OPENAI_API_KEY --value "YOUR_OPENAI_API_KEY"
```
See also [AI Engines](/gh-aw/reference/engines/#available-coding-agents) for additional configuration needed when using Codex with GitHub MCP.
***
### `GEMINI_API_KEY`
[Section titled “GEMINI\_API\_KEY”](#gemini_api_key)
If using the Gemini by Google engine, you need to set a GitHub Actions secret `GEMINI_API_KEY` with an API key from Google AI Studio.
**Setup**:
1. Create an API key at
2. Add it to your repository secrets, either by CLI or GitHub UI:
```bash
gh aw secrets set GEMINI_API_KEY --value "YOUR_GEMINI_API_KEY"
```
See also [AI Engines](/gh-aw/reference/engines/#available-coding-agents) for additional configuration needed when using Gemini with GitHub MCP.
***
## Using a GitHub App for Authentication
[Section titled “Using a GitHub App for Authentication”](#using-a-github-app-for-authentication)
For enhanced security with short-lived tokens, you may configure a GitHub App instead of using PATs.
This does not apply to `COPILOT_GITHUB_TOKEN`, which must currently be a PAT. A single GitHub App can be used for all other GitHub authentication needs in GitHub Agentic Workflows, including tool authentication and safe outputs.
After creating your app, configure it in your workflow:
```yaml
permissions:
contents: read
issues: read
tools:
github:
mode: remote
toolsets: [repos, issues, pull_requests]
github-app:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: "my-org" # Optional: defaults to current repo owner
repositories: ["repo1", "repo2"] # Optional: defaults to current repo only
```
Make sure you set up repository variables and secrets:
```bash
gh variable set APP_ID --body "123456"
gh aw secrets set APP_PRIVATE_KEY --value "$(cat path/to/private-key.pem)"
```
At workflow start, a token is automatically minted with **permissions matching your job’s `permissions:` field**. The token is passed to the GitHub MCP server and automatically revoked at workflow end (even on failure).
You can also use GitHub App tokens for safe outputs operations:
```yaml
safe-outputs:
github-app:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: "my-org" # optional: installation owner
repositories: ["repo1", "repo2"] # optional: scope to specific repos
create-issue:
```
When you configure `github-app:` for safe outputs, tokens are minted with permissions specific to the safe output operations being performed, rather than the broader job-level permissions. This provides enhanced security by ensuring that tokens have the minimum necessary permissions for their specific use case.
For both tool authentication and safe outputs, you can scope the GitHub App token to specific repositories for enhanced security. This limits the token’s access to only the repositories it needs to interact with.
* Omit `repositories` field - Current repository only (default)
* `repositories: ["*"]` - Org-wide access (all repos in the installation)
* `repositories: ["repo1", "repo2"]` - Specific repositories only
***
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Token Reference](/gh-aw/reference/tokens/) - Consolidated reference for all tokens, precedence chains, and permissions
* [Engines](/gh-aw/reference/engines/) - Engine-specific authentication
* [Safe Outputs](/gh-aw/reference/safe-outputs/) - Safe output token configuration
* [Tools](/gh-aw/reference/tools/) - Tool authentication and modes
* [Permissions](/gh-aw/reference/permissions/) - Permission model overview
# Authentication (Projects)
> Reference for authenticating GitHub Projects read and write operations in gh-aw
GitHub Projects operations require additional authentication because the default `GITHUB_TOKEN` is repository-scoped and cannot access the Projects GraphQL API for read or write operations.
## Why a separate token is needed
[Section titled “Why a separate token is needed”](#why-a-separate-token-is-needed)
The standard `GITHUB_TOKEN` provided to every GitHub Actions workflow has repository-level scope only. GitHub Projects (both user-owned and organization-owned) sit outside that scope, so any workflow step that reads project fields or writes updates must supply a token with explicit Projects permissions.
This applies to:
* [GitHub tools `projects` toolset](/gh-aw/reference/github-tools/#additional-authentication-for-github-tools) — reads project items and field values
* [`update-project` safe output](/gh-aw/reference/safe-outputs/#project-board-updates-update-project) — adds items and updates fields
* [`create-project` safe output](/gh-aw/reference/safe-outputs/#project-creation-create-project) — creates new project boards
* [`create-project-status-update` safe output](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update) — posts status updates
## Personal Access Tokens
[Section titled “Personal Access Tokens”](#personal-access-tokens)
### User-owned projects
[Section titled “User-owned projects”](#user-owned-projects)
Use a [classic PAT](https://github.com/settings/tokens/new) with the following scopes:
* `project`
* `repo` (required if the project contains items from private repositories)
### Organization-owned projects
[Section titled “Organization-owned projects”](#organization-owned-projects)
Use a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new?name=GH_AW_WRITE_PROJECT_TOKEN\&description=GitHub+Agentic+Workflows+-+Projects+authentication\&contents=read\&issues=read\&pull_requests=read) with these settings:
* **Resource owner**: the organization that owns the project
* **Repository access**: the repositories that will run the workflow
* **Repository permissions**: `Contents: Read`, and optionally `Issues: Read` / `Pull requests: Read`
* **Organization permissions**: `Projects: Read and write`
## GitHub App tokens
[Section titled “GitHub App tokens”](#github-app-tokens)
For organization-wide standardization, a GitHub App can be used instead of PATs. The app must have **Organization projects: Read and write** permission.
See [Using a GitHub App for Authentication](/gh-aw/reference/auth/#using-a-github-app-for-authentication) for setup instructions.
## Recommended secret layout
[Section titled “Recommended secret layout”](#recommended-secret-layout)
Use separate read and write tokens to enforce least privilege:
```bash
gh aw secrets set GH_AW_READ_PROJECT_TOKEN --value ""
gh aw secrets set GH_AW_WRITE_PROJECT_TOKEN --value ""
```
Reference each token in the workflow where it is needed:
```aw
tools:
github:
mode: remote
toolsets: [projects]
github-token: ${{ secrets.GH_AW_READ_PROJECT_TOKEN }}
safe-outputs:
update-project:
project-url: https://github.com/orgs/my-org/projects/1
github-token: ${{ secrets.GH_AW_WRITE_PROJECT_TOKEN }}
```
The magic secret `GH_AW_GITHUB_MCP_SERVER_TOKEN` is recognized by GitHub Agentic Workflows and does not need to be explicitly referenced in your workflow — if it is present in the repository, it is used automatically for all GitHub tools toolsets, including `projects`.
## Related documentation
[Section titled “Related documentation”](#related-documentation)
* [Authentication](/gh-aw/reference/auth/) — AI engine secrets and GitHub App setup
* [GitHub Tools](/gh-aw/reference/github-tools/) — toolset configuration and additional authentication
* [Safe Outputs](/gh-aw/reference/safe-outputs/) — write operations and token configuration
* [ProjectOps pattern](/gh-aw/patterns/project-ops/) — end-to-end example with project boards
# Cache Memory
> Guide to using cache-memory for persistent file storage across workflow runs with GitHub Actions cache.
Cache memory provides persistent file storage across workflow runs via GitHub Actions cache with 7-day retention. The compiler automatically configures the cache directory, restore/save operations, and progressive fallback keys at `/tmp/gh-aw/cache-memory/` (default) or `/tmp/gh-aw/cache-memory-{id}/` (additional caches).
## Enabling Cache Memory
[Section titled “Enabling Cache Memory”](#enabling-cache-memory)
```aw
---
tools:
cache-memory: true
---
```
Stores files at `/tmp/gh-aw/cache-memory/` using default key `memory-${{ github.workflow }}-${{ github.run_id }}`. Use standard file operations to store/retrieve JSON/YAML, text files, or subdirectories.
## Advanced Configuration
[Section titled “Advanced Configuration”](#advanced-configuration)
```aw
---
tools:
cache-memory:
key: custom-memory-${{ github.workflow }}-${{ github.run_id }}
retention-days: 30 # 1-90 days, extends access beyond cache expiration
allowed-extensions: [".json", ".txt", ".md"] # Restrict file types (default: empty/all files allowed)
---
```
### File Type Restrictions
[Section titled “File Type Restrictions”](#file-type-restrictions)
The `allowed-extensions` field restricts which file types can be written to cache-memory. By default, all file types are allowed (empty array). When specified, only files with listed extensions can be stored.
```aw
---
tools:
cache-memory:
allowed-extensions: [".json", ".jsonl", ".txt"] # Only these extensions allowed
---
```
If files with disallowed extensions are found, the workflow will report validation failures.
## Multiple Configurations
[Section titled “Multiple Configurations”](#multiple-configurations)
```aw
---
tools:
cache-memory:
- id: default
key: memory-default
- id: session
key: memory-session-${{ github.run_id }}
- id: logs
retention-days: 7
---
```
Mounts at `/tmp/gh-aw/cache-memory/` (default) or `/tmp/gh-aw/cache-memory-{id}/`. The `id` determines folder name; `key` defaults to `memory-{id}-${{ github.workflow }}-${{ github.run_id }}`.
## Merging from Shared Workflows
[Section titled “Merging from Shared Workflows”](#merging-from-shared-workflows)
```aw
---
imports:
- shared/mcp/server-memory.md
tools:
cache-memory: true
---
```
Merge rules: **Single→Single** (local overrides), **Single→Multiple** (local converts to array), **Multiple→Multiple** (merge by `id`, local wins).
## Behavior
[Section titled “Behavior”](#behavior)
GitHub Actions cache: 7-day retention, 10GB per repo, LRU eviction. Add `retention-days` to upload artifacts (1-90 days) for extended access.
Caches accessible across branches with unique per-run keys. Custom keys auto-append `-${{ github.run_id }}`. Progressive restore splits on dashes: `custom-memory-project-v1-${{ github.run_id }}` tries `custom-memory-project-v1-`, `custom-memory-project-`, `custom-memory-`, `custom-`.
## Best Practices
[Section titled “Best Practices”](#best-practices)
Use descriptive file/directory names, hierarchical cache keys (`project-${{ github.repository_owner }}-${{ github.workflow }}`), and appropriate scope (workflow-specific default or repository/user-wide). Monitor growth within 10GB limit.
## Comparison with Repo Memory
[Section titled “Comparison with Repo Memory”](#comparison-with-repo-memory)
| Feature | Cache Memory | Repo Memory |
| --------------- | -------------------- | ----------------- |
| Storage | GitHub Actions Cache | Git Branches |
| Retention | 7 days | Unlimited |
| Size Limit | 10GB/repo | Repository limits |
| Version Control | No | Yes |
| Performance | Fast | Slower |
| Best For | Temporary/sessions | Long-term/history |
For unlimited retention with version control, see [Repo Memory](/gh-aw/reference/repo-memory/).
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
* **Files not persisting**: Check cache key consistency and logs for restore/save messages.
* **File access issues**: Create subdirectories first, verify permissions, use absolute paths.
* **Cache size issues**: Track growth, clear periodically, or use time-based keys for auto-expiration.
## Integrity-Aware Caching
[Section titled “Integrity-Aware Caching”](#integrity-aware-caching)
When a workflow uses `tools.github.min-integrity`, cache-memory automatically applies integrity-level isolation. Cache keys include the workflow’s integrity level and a hash of the guard policy so that changing any policy field forces a cache miss.
The compiler generates git-backed branching steps around the agent. Before the agent runs, it checks out the matching integrity branch and merges down from all higher-integrity branches (higher integrity always wins conflicts). After the agent runs, changes are committed to that branch. The agent itself sees only plain files — the `.git/` directory rides along transparently in the Actions cache tarball.
### Merge semantics
[Section titled “Merge semantics”](#merge-semantics)
| Run integrity | Sees data written by | Cannot see |
| ------------- | ------------------------------------ | -------------------------------- |
| `merged` | `merged` only | `approved`, `unapproved`, `none` |
| `approved` | `approved` + `merged` | `unapproved`, `none` |
| `unapproved` | `unapproved` + `approved` + `merged` | `none` |
| `none` | all levels | — |
This prevents a lower-integrity agent from poisoning data that a higher-integrity run would later read.
Note
Existing caches will get a cache miss on first run after upgrading to a version that includes this feature — intentional, as legacy data has no integrity provenance.
## Security
[Section titled “Security”](#security)
Don’t store sensitive data in cache memory. Cache memory follows repository permissions.
Logs access. With [threat detection](/gh-aw/reference/threat-detection/), cache saves only after validation succeeds (restore→modify→upload artifact→validate→save).
## Examples
[Section titled “Examples”](#examples)
See [Grumpy Code Reviewer](https://github.com/github/gh-aw/blob/main/.github/workflows/grumpy-reviewer.md) for tracking PR review history.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Repo Memory](/gh-aw/reference/repo-memory/) - Git branch-based persistent storage with unlimited retention
* [Frontmatter](/gh-aw/reference/frontmatter/) - Complete frontmatter configuration guide
* [Safe Outputs](/gh-aw/reference/safe-outputs/) - Output processing and automation
* [GitHub Actions Cache Documentation](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows) - Official GitHub cache documentation
# GitHub Repository Checkout
> Configure how actions/checkout is invoked in the agent job — disable checkout, override settings, check out multiple repositories, fetch additional refs, and mark a primary target repository.
The `checkout:` frontmatter field controls how `actions/checkout` is invoked in the agent job. Configure custom checkout settings, check out multiple repositories, or disable checkout entirely.
By default, the agent checks out the repository where the workflow is running with a shallow fetch (`fetch-depth: 1`). If triggered by a pull request event, it also checks out the PR head ref. For most workflows, this default checkout is sufficient and no `checkout:` configuration is necessary.
Use `checkout:` when you need to check out additional branches, check out multiple repositories, or to disable checkout entirely for workflows that don’t need to access code or can access code dynamically through the GitHub Tools.
## Custom Checkout Settings
[Section titled “Custom Checkout Settings”](#custom-checkout-settings)
You can use `checkout:` to override default checkout settings (e.g., fetch depth, sparse checkout) without needing to define a custom job:
```yaml
checkout:
fetch-depth: 0 # Full git history
github-token: ${{ secrets.MY_TOKEN }} # Custom authentication
```
Or use GitHub App authentication:
```yaml
checkout:
fetch-depth: 0
github-app:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
```
You can also use `checkout:` to check out additional repositories alongside the main repository:
```yaml
checkout:
- fetch-depth: 0
- repository: owner/other-repo
path: ./libs/other
ref: main
github-token: ${{ secrets.CROSS_REPO_PAT }}
```
## Configuration Options
[Section titled “Configuration Options”](#configuration-options)
| Field | Type | Description |
| ----------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `repository` | string | Repository in `owner/repo` format. Defaults to the current repository. |
| `ref` | string | Branch, tag, or SHA to checkout. Defaults to the triggering ref. |
| `path` | string | Path within `GITHUB_WORKSPACE` to place the checkout. Defaults to workspace root. |
| `github-token` | string | Token for authentication. Use `${{ secrets.MY_TOKEN }}` syntax. |
| `github-app` | object | GitHub App credentials (`app-id`, `private-key`, optional `owner`, `repositories`). Mutually exclusive with `github-token`. `app` is a deprecated alias. |
| `fetch-depth` | integer | Commits to fetch. `0` = full history, `1` = shallow clone (default). |
| `fetch` | string \| string\[] | Additional Git refs to fetch after checkout. See [Fetching Additional Refs](#fetching-additional-refs). |
| `sparse-checkout` | string | Newline-separated patterns for sparse checkout (e.g., `.github/\nsrc/`). |
| `submodules` | string/bool | Submodule handling: `"recursive"`, `"true"`, or `"false"`. |
| `lfs` | boolean | Download Git LFS objects. |
| `current` | boolean | Marks this checkout as the primary working repository. The agent uses this as the default target for all GitHub operations. Only one checkout may set `current: true`; the compiler rejects workflows where multiple checkouts enable it. |
## Fetching Additional Refs
[Section titled “Fetching Additional Refs”](#fetching-additional-refs)
By default, `actions/checkout` performs a shallow clone (`fetch-depth: 1`) of a single ref. For workflows that need to work with other branches — for example, a scheduled workflow that must push changes to open pull-request branches — use the `fetch:` option to retrieve additional refs after the checkout step.
A dedicated git fetch step is emitted after the `actions/checkout` step. Authentication re-uses the checkout token (or falls back to `github.token`) via a transient `http.extraheader` credential — no credentials are persisted to disk, consistent with the enforced `persist-credentials: false` policy.
| Value | Description |
| --------------------- | -------------------------------------------------- |
| `"*"` | All remote branches. |
| `"refs/pulls/open/*"` | All open pull-request head refs (GH-AW shorthand). |
| `"main"` | A specific branch name. |
| `"feature/*"` | A glob pattern matching branch names. |
```yaml
checkout:
- fetch: ["*"] # fetch all branches (default checkout)
fetch-depth: 0 # fetch full history to ensure we can see all commits and PR details
```
```yaml
checkout:
- repository: githubnext/gh-aw-side-repo
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
fetch: ["refs/pulls/open/*"] # fetch all open PR refs after checkout
fetch-depth: 0 # fetch full history to ensure we can see all commits and PR details
```
```yaml
checkout:
- repository: org/target-repo
github-token: ${{ secrets.CROSS_REPO_PAT }}
fetch: ["main", "feature/*"] # fetch specific branches
fetch-depth: 0 # fetch full history to ensure we can see all commits and PR details
```
Note
If a branch you need is not available after checkout and is not covered by a `fetch:` pattern, and you’re in a private or internal repo, then the agent cannot access its Git history except inefficiently, file by file, via the GitHub MCP. For private repositories, it will be unable to fetch or explore additional branches. If the branch is required and unavailable, configure the appropriate pattern in `fetch:` (e.g., `fetch: ["*"]` for all branches, or `fetch: ["refs/pulls/open/*"]` for PR branches) and recompile the workflow.
## Disabling Checkout (`checkout: false`)
[Section titled “Disabling Checkout (checkout: false)”](#disabling-checkout-checkout-false)
Set `checkout: false` to suppress the default `actions/checkout` step entirely. Use this for workflows that access repositories through MCP servers or other mechanisms that do not require a local clone:
```yaml
checkout: false
```
This is equivalent to omitting the checkout step from the agent job. Custom dev-mode steps (such as “Checkout actions folder”) are unaffected.
## Marking a Primary Repository (`current: true`)
[Section titled “Marking a Primary Repository (current: true)”](#marking-a-primary-repository-current-true)
When a workflow running from a central repository targets a different repository, use `current: true` to tell the agent which repository to treat as its primary working target. The agent uses this as the default for all GitHub operations (creating issues, opening PRs, reading content) unless the prompt instructs otherwise. When omitted, the agent defaults to the repository where the workflow is running.
```yaml
checkout:
- repository: org/target-repo
path: ./target
github-token: ${{ secrets.CROSS_REPO_PAT }}
current: true # agent's primary target
```
## Checkout Merging
[Section titled “Checkout Merging”](#checkout-merging)
Multiple `checkout:` configurations can target the same path and repository. This is useful for monorepos where different parts of the repository must be merged into the same workspace directory with different settings (e.g., sparse checkout for some paths, full checkout for others).
When multiple `checkout:` entries target the same repository and path, their configurations are merged with the following rules:
* **Fetch depth**: Deepest value wins (`0` = full history always takes precedence)
* **Fetch refs**: Merged (union of all patterns; duplicates are removed)
* **Sparse patterns**: Merged (union of all patterns)
* **LFS**: OR-ed (if any config enables `lfs`, the merged configuration enables it)
* **Submodules**: First non-empty value wins for each `(repository, path)`; once set, later values are ignored
* **Ref/Token/App**: First-seen wins
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Cross-Repository Operations](/gh-aw/reference/cross-repository/) - Reading and writing across multiple repositories
* [Authentication Reference](/gh-aw/reference/auth/) - PAT and GitHub App setup
* [Multi-Repository Examples](/gh-aw/examples/multi-repo/) - Complete working examples
# Command Triggers
> Learn about slash command triggers and context text functionality for agentic workflows, including special @mention triggers for interactive automation.
GitHub Agentic Workflows add the convenience `slash_command:` trigger to create workflows that respond to `/my-bots` in issues and comments.
```yaml
on:
slash_command:
name: my-bot # Optional: defaults to filename without .md extension
```
You can also use shorthand formats:
```yaml
on:
slash_command: "my-bot" # Shorthand: string directly specifies command name
```
```yaml
on: /my-bot # Ultra-short: slash prefix automatically expands to slash_command + workflow_dispatch
```
## Multiple Command Identifiers
[Section titled “Multiple Command Identifiers”](#multiple-command-identifiers)
A single workflow can respond to multiple slash command names by providing an array of command identifiers:
```yaml
on:
slash_command:
name: ["cmd.add", "cmd.remove", "cmd.list"]
```
When triggered, the matched command is available as `needs.activation.outputs.slash_command`, allowing your workflow to determine which command was used:
```aw
---
on:
slash_command:
name: ["summarize", "summary", "tldr"]
---
# Multi-Command Handler
You invoked the workflow using: `/${{ needs.activation.outputs.slash_command }}`
Now analyzing the content...
```
This feature enables command aliases and grouped command handlers without workflow duplication.
This automatically creates issue/PR triggers (`opened`, `edited`, `reopened`), comment triggers (`created`, `edited`), and conditional execution matching `/command-name` mentions.
**Code availability:** When a command is triggered from a pull request body, PR comment, or PR review comment, the coding agent has access to both the PR branch and the default branch.
The command must be the **first word** of the comment or body text to trigger the workflow. This prevents accidental triggers when the command is mentioned elsewhere in the content.
You can combine `slash_command:` with other events like `workflow_dispatch` or `schedule`:
```yaml
on:
slash_command:
name: my-bot
workflow_dispatch:
schedule: weekly on monday
```
**Note**: You cannot combine `slash_command` with `issues`, `issue_comment`, or `pull_request` as they would conflict.
**Exception for Label-Only Events**: You CAN combine `slash_command` with `issues` or `pull_request` if those events are configured for label-only triggers (`labeled` or `unlabeled` types only). This allows workflows to respond to slash commands while also reacting to label changes.
```yaml
on:
slash_command: deploy
issues:
types: [labeled, unlabeled] # Valid: label-only triggers don't conflict
```
This pattern is useful when you want a workflow that can be triggered both manually via commands and automatically when labels change.
## Filtering Command Events
[Section titled “Filtering Command Events”](#filtering-command-events)
By default, command triggers respond to `/command-name` mentions in all comment-related contexts. Use the `events:` field to restrict where commands are active:
```yaml
on:
slash_command:
name: my-bot
events: [issues, issue_comment] # Only in issue bodies and issue comments
```
**Supported events:** `issues` (issue bodies), `issue_comment` (issue comments only), `pull_request_comment` (PR comments only), `pull_request` (PR bodies), `pull_request_review_comment` (PR review comments), `discussion` (discussion bodies), `discussion_comment` (discussion comments), or `*` (all comment events, default).
### Example command workflow
[Section titled “Example command workflow”](#example-command-workflow)
Using object format:
```aw
---
on:
slash_command:
name: summarize-issue
tools:
github:
toolsets: [issues]
---
# Issue Summarizer
When someone mentions /summarize-issue in an issue or comment,
analyze and provide a helpful summary.
The current context text is: "${{ steps.sanitized.outputs.text }}"
```
PR-focused example using event filtering to restrict to pull requests and PR comments:
```aw
---
on:
slash_command:
name: code-review
events: [pull_request, pull_request_comment]
permissions:
contents: read
tools:
github:
toolsets: [pull_requests]
safe-outputs:
add-comment:
max: 5
timeout-minutes: 10
---
# Code Review Assistant
When someone mentions /code-review in a pull request or PR comment,
analyze the code changes and provide detailed feedback.
The current context is: "${{ steps.sanitized.outputs.text }}"
Review the pull request changes and add helpful review comments on specific
lines of code where improvements can be made.
```
## Context Text
[Section titled “Context Text”](#context-text)
All workflows access `steps.sanitized.outputs.text`, which provides **sanitized** context: for issues and PRs, it’s `title + "\n\n" + body`; for comments and reviews, it’s the body content.
```aw
# Analyze this content: "${{ steps.sanitized.outputs.text }}"
```
**Why sanitized context?** The sanitized text neutralizes @mentions and bot triggers (like `fixes #123`), protects against XML injection, filters URIs to trusted HTTPS domains, limits content size (0.5MB max, 65k lines), and strips ANSI escape sequences.
**Comparison:**
```aw
# RECOMMENDED: Secure sanitized context
Analyze this issue: "${{ steps.sanitized.outputs.text }}"
# DISCOURAGED: Raw context values (security risks)
Title: "${{ github.event.issue.title }}"
Body: "${{ github.event.issue.body }}"
```
## Reactions
[Section titled “Reactions”](#reactions)
Command workflows automatically add the “eyes” () emoji reaction to triggering comments and edit them with workflow run links, providing immediate feedback. Customize the reaction:
```yaml
on:
slash_command:
name: my-bot
reaction: "rocket" # Override default "eyes"
```
See [Reactions](/gh-aw/reference/frontmatter/) for available reactions and detailed behavior.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Frontmatter](/gh-aw/reference/frontmatter/) - All configuration options for workflows
* [Workflow Structure](/gh-aw/reference/workflow-structure/) - Directory layout and organization
* [CLI Commands](/gh-aw/setup/cli/) - CLI commands for workflow management
# Compilation Process
> Advanced technical documentation on how GitHub Agentic Workflows compiles markdown files into GitHub Actions YAML, including job orchestration, action pinning, artifacts, and MCP integration.
This guide documents the internal compilation process that transforms markdown workflow files into executable GitHub Actions YAML. Understanding this process helps when debugging workflows, optimizing performance, or contributing to the project.
## Overview
[Section titled “Overview”](#overview)
The `gh aw compile` command transforms a markdown workflow file into a complete GitHub Actions `.lock.yml` by embedding frontmatter and setting up runtime loading of the markdown body. The process runs five compilation phases (parsing, validation, job construction, dependency resolution, and YAML generation) described below.
When the workflow runs, the markdown body is loaded at runtime — you can edit instructions without recompilation. See [Editing Workflows](/gh-aw/guides/editing-workflows/) for details.
## Compilation Phases
[Section titled “Compilation Phases”](#compilation-phases)
### Phase 1: Parsing and Validation
[Section titled “Phase 1: Parsing and Validation”](#phase-1-parsing-and-validation)
The compilation process reads the markdown file and:
* Extracts YAML frontmatter
* Parses workflow configuration
* Validates against the workflow schema
* **Resolves imports** using breadth-first search (BFS) traversal
* **Merges configurations** from imported files according to field-specific rules
* Validates expression safety (only allowed GitHub Actions expressions)
#### Import Resolution Algorithm
[Section titled “Import Resolution Algorithm”](#import-resolution-algorithm)
Import processing follows a deterministic BFS algorithm:
1. **Queue initialization**: Parse main workflow’s `imports:` field and add entries to queue
2. **Iterative processing**: For each import in queue:
* Resolve path (local file or remote repository reference)
* Load and parse import file
* Extract mergeable configurations (tools, mcp-servers, network, etc.)
* Add import’s own imports to end of queue (nested imports)
* Track visited files to detect circular imports
3. **Configuration accumulation**: Collect all configurations by field type
4. **Merge execution**: Apply field-specific merge strategies
5. **Validation**: Check for conflicts and permission requirements
**Merge strategies**:
* **Tools**: Deep merge with array concatenation and deduplication
* **MCP servers**: Imported servers override main workflow servers with same name
* **Network**: Union of allowed domains, deduplicated and sorted
* **Permissions**: Validation only - main must satisfy imported requirements
* **Safe outputs**: Main workflow overrides imported configurations per type
* **Runtimes**: Main workflow versions override imported versions
**Example processing order**:
```plaintext
Main Workflow
├── import-a.md → Processed 1st
│ ├── nested-1.md → Processed 3rd (after import-b)
│ └── nested-2.md → Processed 4th
└── import-b.md → Processed 2nd
└── nested-3.md → Processed 5th
```
See [Imports Reference](/gh-aw/reference/imports/) for complete merge semantics.
### Phases 2–5: Building the Workflow
[Section titled “Phases 2–5: Building the Workflow”](#phases-25-building-the-workflow)
| Phase | Steps |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **2 Job Construction** | Builds specialized jobs: pre-activation (if needed), activation, agent, safe outputs, safe-jobs, and custom jobs |
| **3 Dependency Resolution** | Validates job dependencies, detects circular references, computes topological order, generates Mermaid graph |
| **4 Action Pinning** | Pins all actions to SHAs: check cache → GitHub API → embedded pins → add version comment (e.g., `actions/checkout@sha # v6`) |
| **5 YAML Generation** | Assembles final `.lock.yml`: header with metadata, Mermaid dependency graph, alphabetical jobs, embedded original prompt |
## Job Types
[Section titled “Job Types”](#job-types)
The compilation process generates specialized jobs based on workflow configuration:
| Job | Trigger | Purpose | Key Dependencies |
| -------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------- |
| **pre\_activation** | Role checks, stop-after deadlines, skip-if-match, or command triggers | Validates permissions, deadlines, and conditions before AI execution | None (runs first) |
| **activation** | Always | Prepares workflow context, sanitizes event text, validates lock file freshness | `pre_activation` (if exists) |
| **agent** | Always | Core job that executes AI agent with configured engine, tools, and Model Context Protocol (MCP) servers | `activation` |
| **detection** | `safe-outputs.threat-detection:` configured | Scans agent output for security threats before processing | `agent` |
| **Safe output jobs** | Corresponding `safe-outputs.*:` configured | Process agent output to perform GitHub API operations (create issues/PRs, add comments, upload assets, etc.) | `agent`, `detection` (if exists) |
| **conclusion** | Always (if safe outputs exist) | Aggregates results and generates workflow summary | All safe output jobs |
### Agent Job Steps
[Section titled “Agent Job Steps”](#agent-job-steps)
The agent job orchestrates AI execution through these phases:
1. Repository checkout and runtime setup (Node.js, Python, Go)
2. Cache restoration for persistent memory
3. MCP server container initialization
4. Prompt generation from markdown content
5. Engine execution (Copilot, Claude, or Codex)
6. Output upload as GitHub Actions artifact
7. Cache persistence for next run
Environment variables include `GH_AW_PROMPT` (prompt file), `GH_AW_SAFE_OUTPUTS` (output JSON), and `GITHUB_TOKEN`.
### Safe Output Jobs
[Section titled “Safe Output Jobs”](#safe-output-jobs)
Each safe output type (create issue, add comment, create PR, etc.) follows a consistent pattern: download agent artifact, parse JSON output, execute GitHub API operations with appropriate permissions, and link to related items.
Common safe output jobs:
* **create\_issue** / **create\_discussion** - Create GitHub items with labels and prefixes
* **add\_comment** - Comment on issues/PRs with links to created items
* **create\_pull\_request** - Apply git patches, create branch, open PR
* **create\_pr\_review\_comment** - Add line-specific code review comments
* **create\_code\_scanning\_alert** - Submit SARIF security findings
* **add\_labels** / **assign\_milestone** - Manage issue metadata
* **update\_issue** / **update\_release** - Modify existing items
* **push\_to\_pr\_branch** / **upload\_assets** - Handle file operations
* **update\_project** - Sync with project boards
* **missing\_tool** / **noop** - Report issues or log status
### Custom Jobs
[Section titled “Custom Jobs”](#custom-jobs)
Use `safe-outputs.jobs:` for custom jobs with full GitHub Actions syntax, or `jobs:` for additional workflow jobs with user-defined dependencies. See [Deterministic & Agentic Patterns](/gh-aw/guides/deterministic-agentic-patterns/) for examples of multi-stage workflows combining deterministic computation with AI reasoning.
## Job Dependency Graphs
[Section titled “Job Dependency Graphs”](#job-dependency-graphs)
Jobs execute in topological order based on dependencies. Here’s a comprehensive example:
```
graph LR
pre_activation["pre_activation"]
activation["activation"]
agent["agent"]
detection["detection"]
create_issue["create_issue"]
add_comment["add_comment"]
conclusion["conclusion"]
pre_activation --> activation
activation --> agent
agent --> detection
agent --> create_issue
agent --> add_comment
detection --> create_issue
detection --> add_comment
create_issue --> add_comment
create_issue --> conclusion
add_comment --> conclusion
```
**Execution flow**: Pre-activation validates permissions → Activation prepares context → Agent executes AI → Detection scans output → Safe outputs run in parallel → Add comment waits for created items → Conclusion summarizes results. Safe output jobs without cross-dependencies run concurrently; when threat detection is enabled, safe outputs depend on both agent and detection jobs.
## Why Detection, Safe Outputs, and Conclusion Are Separate Jobs
[Section titled “Why Detection, Safe Outputs, and Conclusion Are Separate Jobs”](#why-detection-safe-outputs-and-conclusion-are-separate-jobs)
A typical compiled workflow contains these post-agent jobs:
```
flowchart TD
activation["activation ubuntu-slim contents: read"] --> agent["agent ubuntu-latest READ-ONLY permissions concurrency group"]
agent --> detection["detection ubuntu-latest contents: read concurrency group RUNS AI ENGINE"]
agent --> conclusion["conclusion ubuntu-slim issues: write pr: write"]
detection --> safe_outputs["safe_outputs ubuntu-slim contents: write issues: write pr: write"]
detection --> conclusion
safe_outputs --> conclusion
detection --> update_cache_memory["update_cache_memory ubuntu-latest contents: read"]
update_cache_memory --> conclusion
activation --> safe_outputs
activation --> conclusion
```
These three jobs form a **sequential security pipeline** and cannot be combined into a single job for the following reasons.
### 1. Security Architecture: Trust Boundaries
[Section titled “1. Security Architecture: Trust Boundaries”](#1-security-architecture-trust-boundaries)
The system enforces [Plan-Level Trust](/gh-aw/introduction/architecture/) — separating AI reasoning (read-only) from write operations. The **detection** job runs its own AI engine as a security gate: `success == 'true'` is the explicit condition controlling whether `safe_outputs` executes at all. If combined, a compromised agent’s output could bypass detection.
### 2. Job-Level Permissions Are Immutable
[Section titled “2. Job-Level Permissions Are Immutable”](#2-job-level-permissions-are-immutable)
In GitHub Actions, permissions are declared per-job and cannot change during execution:
| Job | Key Permissions | Rationale |
| ----------------- | ------------------------------------------------------------- | --------------------------------------------- |
| **detection** | `contents: read` (minimal) | Runs AI analysis — must NOT have write access |
| **safe\_outputs** | `contents: write`, `issues: write`, `pull-requests: write` | Executes GitHub API write operations |
| **conclusion** | `issues: write`, `pull-requests: write`, `discussions: write` | Updates comments, handles failures |
If detection and safe\_outputs were combined, the combined job would hold **write permissions during threat detection**, violating least privilege. A compromised detection step could exploit those write permissions.
### 3. Job-Level Gating Provides Hard Isolation
[Section titled “3. Job-Level Gating Provides Hard Isolation”](#3-job-level-gating-provides-hard-isolation)
The `safe_outputs` job condition (`needs.detection.outputs.success == 'true'`) ensures the runner **never starts** if detection fails — write-permission code never loads. Step-level `if` conditions within a single job provide weaker isolation.
### 4. The Conclusion Job Requires `always()` Semantics
[Section titled “4. The Conclusion Job Requires always() Semantics”](#4-the-conclusion-job-requires-always-semantics)
The `conclusion` job uses `always()` to handle upstream failures: agent errors, no-op logging, error status updates, and missing tool reporting. As a separate job it inspects upstream results via `needs.agent.result`; merging it with safe\_outputs would block these steps when writes fail.
### 5. Different Runners and Resource Requirements
[Section titled “5. Different Runners and Resource Requirements”](#5-different-runners-and-resource-requirements)
Detection requires `ubuntu-latest` for AI execution; safe\_outputs and conclusion use the lightweight `ubuntu-slim`. Merging detection with safe\_outputs would force `ubuntu-latest` for the entire pipeline.
### 6. Concurrency Group Isolation
[Section titled “6. Concurrency Group Isolation”](#6-concurrency-group-isolation)
The `detection` job shares a **concurrency group** (`gh-aw-copilot-${{ github.workflow }}`) with the agent job, serializing AI engine execution. The `safe_outputs` job intentionally does **not** have this group — it can run concurrently with other workflow instances’ detection phases.
### 7. Artifact-Based Security Handoff
[Section titled “7. Artifact-Based Security Handoff”](#7-artifact-based-security-handoff)
Data flows via GitHub Actions artifacts: agent writes `agent_output.json` → detection analyzes it and outputs `success` → safe\_outputs downloads it only if approved. This prevents the output tampering possible with a shared filesystem in a single job.
## Action Pinning
[Section titled “Action Pinning”](#action-pinning)
All GitHub Actions are pinned to commit SHAs (e.g., `actions/checkout@b4ffde6...11 # v6`) to prevent supply chain attacks. Tags can be moved to malicious commits, but SHA commits are immutable. The resolution order mirrors Phase 4: cache (`.github/aw/actions-lock.json`) → GitHub API → embedded pins.
### The actions-lock.json Cache
[Section titled “The actions-lock.json Cache”](#the-actions-lockjson-cache)
`.github/aw/actions-lock.json` stores resolved `action@version` → SHA mappings so that compilation produces consistent results regardless of the token available. Resolving a version tag to a SHA requires querying the GitHub API, which can fail when the token has limited permissions — notably when compiling via GitHub Copilot Coding Agent (CCA), which uses a restricted token that may not have access to external repositories.
By caching SHA resolutions from a prior compilation (done with a user PAT or a GitHub Actions token with broader scope), subsequent compilations reuse those SHAs without making API calls. Without the cache, compilation is unstable: it succeeds with a permissive token but fails when token access is restricted.
**Commit `actions-lock.json` to version control.** This ensures all contributors and automated tools, including CCA, use the same immutable pins. Refresh it periodically with `gh aw update-actions`, or delete it and recompile with an appropriate token to force full re-resolution.
## The gh-aw-actions Repository
[Section titled “The gh-aw-actions Repository”](#the-gh-aw-actions-repository)
`github/gh-aw-actions` is the GitHub Actions repository containing all reusable actions that power compiled agentic workflows. When `gh aw compile` generates a `.lock.yml`, every action step references `github/gh-aw-actions` using a ref (typically a commit SHA, but may be a stable version tag such as `v0` when SHA resolution is unavailable):
```yaml
uses: github/gh-aw-actions/setup@abc1234...
```
These references are generated entirely by the compiler and should never be edited manually in `.lock.yml` files. To update action refs to a newer `gh-aw-actions` release, run `gh aw compile` or `gh aw update-actions`.
The repository is referenced via the `--actions-repo` flag default (`github/gh-aw-actions`) when `--action-mode action` is set during compilation. See [Compilation Commands](#compilation-commands) for how to compile against a fork or specific tag during development.
### Dependabot and gh-aw-actions
[Section titled “Dependabot and gh-aw-actions”](#dependabot-and-gh-aw-actions)
Dependabot scans all `.yml` files in `.github/workflows/` for action references and may open pull requests attempting to update `github/gh-aw-actions` to a newer SHA. **Do not merge these PRs.** The correct way to update `gh-aw-actions` pins is by running `gh aw compile` (or `gh aw update-actions`), which regenerates all action pins consistently across all compiled workflows from a single coordinated release.
To suppress Dependabot PRs for `github/gh-aw-actions`, add an `ignore` entry in `.github/dependabot.yml`:
```yaml
updates:
- package-ecosystem: github-actions
directory: "/"
ignore:
# ignore updates to gh-aw-actions, which only appears in auto-generated *.lock.yml
# files managed by 'gh aw compile' and should not be touched by dependabot
- dependency-name: "github/gh-aw-actions"
```
This tells Dependabot to skip version updates for `github/gh-aw-actions` while still monitoring all other GitHub Actions dependencies.
## Artifacts Created
[Section titled “Artifacts Created”](#artifacts-created)
Workflows generate several artifacts during execution:
| Artifact | Location | Purpose | Lifecycle |
| --------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| **agent\_output.json** | `/tmp/gh-aw/safeoutputs/` | AI agent output with structured safe output data (create\_issue, add\_comment, etc.) | Uploaded by agent job, downloaded by safe output jobs, auto-deleted after 90 days |
| **agent\_usage.json** | `/tmp/gh-aw/` | Aggregated token counts: `{"input_tokens":…,"output_tokens":…,"cache_read_tokens":…,"cache_write_tokens":…}` | Bundled in the unified agent artifact when the firewall is enabled; accessible to third-party tools without parsing step summaries |
| **prompt.txt** | `/tmp/gh-aw/aw-prompts/` | Generated prompt sent to AI agent (includes markdown instructions, imports, context variables) | Retained for debugging and reproduction |
| **firewall-logs/** | `/tmp/gh-aw/firewall-logs/` | Network access logs in Squid format (when `network.firewall:` enabled) | Analyzed by `gh aw logs` command |
| **cache-memory/** | `/tmp/gh-aw/cache-memory/` | Persistent agent memory across runs (when `tools.cache-memory:` configured) | Restored at start, saved at end via GitHub Actions cache |
| **patches/**, **sarif/**, **metadata/** | Various | Safe output data (git patches, SARIF files, metadata JSON) | Temporary, cleaned after processing |
## MCP Server Integration
[Section titled “MCP Server Integration”](#mcp-server-integration)
Model Context Protocol (MCP) servers provide tools to AI agents. Compilation generates `mcp-config.json` from workflow configuration.
**Local MCP servers** run in Docker containers with auto-generated Dockerfiles. Secrets inject via environment variables, and engines connect via stdio.
**HTTP MCP servers** require no containers. Engines connect directly with configured headers and authentication.
**Tool filtering** via `allowed:` restricts agent access to specific MCP tools. Environment variables inject through Dockerfiles (local) or config references (HTTP).
**Agent job integration**: MCP containers start after runtime setup → Engine executes with tool access → Containers stop after completion.
## Pre-Activation Job
[Section titled “Pre-Activation Job”](#pre-activation-job)
Pre-activation enforces security and operational policies before expensive AI execution. It validates permissions, deadlines, and conditions, setting `activated=false` to skip downstream jobs when checks fail.
**Validation types**:
* **Role checks** (`roles:`): Verify actor has required permissions (admin, maintainer, write)
* **Stop-after** (`on.stop-after:`): Honor time-limited workflows (e.g., `+30d`, `2024-12-31`)
* **Skip-if-match** (`skip-if-match:`): Prevent duplicates by searching for existing items matching criteria
* **Command position** (`on.slash_command:`): Ensure command appears in first 3 lines to avoid accidental triggers
Pre-activation runs checks sequentially. Any failure sets `activated=false`, preventing AI execution and saving costs.
## Compilation Commands
[Section titled “Compilation Commands”](#compilation-commands)
| Command | Description |
| ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `gh aw compile` | Compile all workflows in `.github/workflows/` |
| `gh aw compile my-workflow` | Compile specific workflow |
| `gh aw compile --verbose` | Enable verbose output |
| `gh aw compile --strict` | Enhanced security validation |
| `gh aw compile --no-emit` | Validate without generating files |
| `gh aw compile --actionlint --zizmor --poutine` | Run security scanners |
| `gh aw compile --purge` | Remove orphaned `.lock.yml` files |
| `gh aw compile --output /path/to/output` | Custom output directory |
| `gh aw compile --action-mode action --actions-repo owner/repo` | Compile using a custom actions repository (requires `--action-mode action`) |
| `gh aw compile --action-mode action --actions-repo owner/repo --action-tag branch-or-sha` | Compile against a specific branch or SHA in a fork |
| `gh aw compile --action-tag v1.2.3` | Pin action references to a specific tag or SHA (implies release mode) |
| `gh aw validate` | Validate all workflows (compile + all linters, no file output) |
| `gh aw validate my-workflow` | Validate a specific workflow |
| `gh aw validate --json` | Validate and output results in JSON format |
| `gh aw validate --strict` | Validate with strict mode enforced |
Tip
Compilation is only required when changing **frontmatter configuration**. The **markdown body** (AI instructions) is loaded at runtime and can be edited without recompilation. See [Editing Workflows](/gh-aw/guides/editing-workflows/) for details.
Note
The `--actions-repo` flag overrides the default `github/gh-aw-actions` repository used when `--action-mode action` is set. Use it together with `--action-tag` to compile against a branch or fork during development.
## Debugging Compilation
[Section titled “Debugging Compilation”](#debugging-compilation)
**Enable verbose logging**: `DEBUG=workflow:* gh aw compile my-workflow --verbose` shows job creation, action pin resolutions, tool configurations, and MCP setups.
**Inspect `.lock.yml` files**: Check header comments (imports, dependencies, prompt), job dependency graphs (Mermaid diagrams), job structure (steps, environment, permissions), action SHA pinning, and MCP configurations.
**Common issues**: Circular deps → review `needs:` clauses; Missing action pin → add to `action_pins.json` or enable dynamic resolution; Invalid MCP config → verify `command`, `args`, `env`.
## Performance Optimization
[Section titled “Performance Optimization”](#performance-optimization)
**Compilation speed**: Simple workflows compile in \~100ms, complex workflows with imports in \~500ms, and workflows with dynamic action resolution in \~2s. Optimize by using action cache (`.github/aw/actions-lock.json`), minimizing import depth, and pre-compiling shared workflows.
**Runtime performance**: Safe output jobs without dependencies run in parallel. Enable `cache:` for dependencies, use `cache-memory:` for persistent agent memory, and cache action resolutions for faster compilation.
## Advanced Topics
[Section titled “Advanced Topics”](#advanced-topics)
**Custom engine integration**: Create engines that return GitHub Actions steps, provide environment variables, and configure tool access. Register with the framework for workflow availability.
**Schema extension**: Add frontmatter fields by updating the workflow schema, rebuilding (`make build`), adding parser handling, and updating documentation.
**Workflow manifest resolution**: Compilation tracks imported files in lock file headers for dependency tracking, update detection, and audit trails.
## Best Practices
[Section titled “Best Practices”](#best-practices)
**Security**: Always use action pinning (never floating tags), enable threat detection (`safe-outputs.threat-detection:`), limit tool access with `allowed:`, review generated `.lock.yml` files, and run security scanners (`--actionlint --zizmor --poutine`).
**Maintainability**: Use imports for shared configuration, document complex workflows with `description:`, compile frequently during development, version control lock files and action pins (`.github/aw/actions-lock.json`).
**Performance**: Enable caching (`cache:` and `cache-memory:`), minimize imports to essentials, optimize tool configurations with restricted `allowed:` lists, use safe-jobs for custom logic.
**Debugging**: Enable verbose logging (`--verbose`), check job dependency graphs in headers, inspect artifacts and firewall logs (`gh aw logs`), validate without file generation (`--no-emit`).
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Editing Workflows](/gh-aw/guides/editing-workflows/) - When to recompile vs edit directly
* [Frontmatter Reference](/gh-aw/reference/frontmatter/) - All configuration options
* [Tools Reference](/gh-aw/reference/tools/) - Tool configuration guide
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Output processing
* [Engines Reference](/gh-aw/reference/engines/) - AI engine configuration
* [Network Reference](/gh-aw/reference/network/) - Network permissions
# Concurrency Control
> Complete guide to concurrency control in GitHub Agentic Workflows, including agent job concurrency configuration and engine isolation.
GitHub Agentic Workflows uses dual-level concurrency control to prevent resource exhaustion and ensure predictable execution:
* **Per-workflow**: Limits based on workflow name and trigger context (issue, PR, branch)
* **Per-engine**: Limits AI execution across all workflows via `engine.concurrency`
## Per-Workflow Concurrency
[Section titled “Per-Workflow Concurrency”](#per-workflow-concurrency)
Workflow-level concurrency groups include the workflow name plus context-specific identifiers:
| Trigger Type | Concurrency Group | Cancel In Progress |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------- |
| Issues | `gh-aw-${{ github.workflow }}-${{ issue.number }}` | No |
| Pull Requests | `gh-aw-${{ github.workflow }}-${{ pr.number \|\| ref }}` | Yes (new commits cancel outdated runs) |
| Push | `gh-aw-${{ github.workflow }}-${{ github.ref }}` | No |
| Schedule/Other | `gh-aw-${{ github.workflow }}` | No |
| Label-triggered (label trigger shorthand or label\_command) | `gh-aw-${{ github.workflow }}-${{ entity.number }}-${{ github.event.label.name }}` | Yes for PRs, No otherwise |
This ensures workflows on different issues, PRs, or branches run concurrently without interference.
For label-triggered workflows, the concurrency group includes `github.event.label.name` as an additional segment. This prevents cross-label cancellation when multiple labels are added to the same PR or issue simultaneously: each label event gets its own distinct group, so workflows triggered by different labels do not cancel each other.
## Per-Engine Concurrency
[Section titled “Per-Engine Concurrency”](#per-engine-concurrency)
The default per-engine pattern `gh-aw-{engine-id}` ensures only one agent job runs per engine across all workflows, preventing AI resource exhaustion. The group includes only the engine ID and `gh-aw-` prefix - workflow name, issue/PR numbers, and branches are excluded.
```yaml
jobs:
agent:
concurrency:
group: "gh-aw-{engine-id}"
```
## Custom Concurrency
[Section titled “Custom Concurrency”](#custom-concurrency)
Override either level independently:
```yaml
---
on: push
concurrency: # Workflow-level
group: custom-group-${{ github.ref }}
cancel-in-progress: true
engine:
id: copilot
concurrency: # Engine-level
group: "gh-aw-copilot-${{ github.workflow }}"
tools:
github:
allowed: [list_issues]
---
```
## Safe Outputs Job Concurrency
[Section titled “Safe Outputs Job Concurrency”](#safe-outputs-job-concurrency)
The `safe_outputs` job runs independently from the agent job and can process outputs concurrently across workflow runs. Use `safe-outputs.concurrency-group` to serialize access when needed:
```yaml
safe-outputs:
concurrency-group: "safe-outputs-${{ github.repository }}"
create-issue:
```
When set, the `safe_outputs` job uses `cancel-in-progress: false` — meaning queued runs wait for the in-progress run to finish rather than being cancelled. This is useful for workflows that create issues or pull requests where duplicate operations would be undesirable.
See [Safe Outputs](/gh-aw/reference/safe-outputs/#safe-outputs-job-concurrency-concurrency-group) for details.
## Conclusion Job Concurrency
[Section titled “Conclusion Job Concurrency”](#conclusion-job-concurrency)
The `conclusion` job — which handles reporting and post-agent cleanup — automatically receives a workflow-specific concurrency group derived from the workflow filename:
```yaml
conclusion:
concurrency:
group: "gh-aw-conclusion-my-workflow"
cancel-in-progress: false
```
This prevents conclusion jobs from colliding when multiple agents run the same workflow concurrently. The group uses `cancel-in-progress: false` so queued conclusion runs complete in order rather than being discarded.
This concurrency group is set automatically during compilation and requires no manual configuration.
When `concurrency.job-discriminator` is set, the discriminator is also appended to the conclusion job’s concurrency group, making each run’s group distinct:
```yaml
concurrency:
job-discriminator: ${{ github.event.issue.number || github.run_id }}
```
This generates a group like `gh-aw-conclusion-my-workflow-${{ github.event.issue.number || github.run_id }}`, preventing concurrent runs for different issues or inputs from competing for the same conclusion slot.
## Fan-Out Concurrency (`job-discriminator`)
[Section titled “Fan-Out Concurrency (job-discriminator)”](#fan-out-concurrency-job-discriminator)
When multiple workflow instances are dispatched concurrently with different inputs (fan-out pattern), compiler-generated job-level concurrency groups are static across all runs — causing all but the latest dispatched run to be cancelled as they compete for the same slot.
Use `concurrency.job-discriminator` to append a unique expression to compiler-generated job-level concurrency groups (`agent`, `output`, and `conclusion` jobs), making each dispatched run’s group distinct:
```yaml
concurrency:
job-discriminator: ${{ inputs.finding_id }}
```
This generates a unique job-level concurrency group per dispatched run, preventing fan-out cancellations while preserving the per-workflow concurrency group at the workflow level.
Example usage:
```yaml
concurrency:
job-discriminator: ${{ inputs.finding_id }}
```
Common expressions:
| Scenario | Expression |
| ------------------------------------------ | ----------------------------------------------- |
| Fan-out by a specific input | `${{ inputs.finding_id }}` |
| Universal uniqueness (e.g. scheduled runs) | `${{ github.run_id }}` |
| Dispatched or scheduled fallback | `${{ inputs.organization \|\| github.run_id }}` |
Note
`job-discriminator` is a gh-aw extension and is stripped from the compiled lock file. It does not appear in the generated GitHub Actions YAML.
Note
`job-discriminator` has no effect on workflows triggered by `workflow_dispatch`-only, `push`, or `pull_request` events, or when the engine provides an explicit job-level concurrency configuration.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [AI Engines](/gh-aw/reference/engines/) - Engine configuration and capabilities
* [Frontmatter](/gh-aw/reference/frontmatter/) - Complete frontmatter reference
* [Workflow Structure](/gh-aw/reference/workflow-structure/) - Overall workflow organization
* [Safe Outputs](/gh-aw/reference/safe-outputs/) - Safe output processing and job configuration
# Importing Copilot Agent Files
> Import and reuse Copilot agent files with GitHub Agentic Workflows
“Custom agents” is a term used in GitHub Copilot for specialized prompts for behaviors for specific tasks. They are markdown files stored in the `.github/agents/` directory and imported via the `imports` field. Copilot supports agent files natively, while other engines (Claude, Codex) inject the markdown body as a prompt.
A typical custom agent file looks like this:
.github/agents/my-agent.md
```markdown
---
name: My Copilot Agent
description: Specialized prompt for code review tasks
---
# Agent Instructions
You are a specialized code review agent. Focus on:
- Code quality and best practices
- Security vulnerabilities
- Performance optimization
```
## Using Copilot Agent Files from Agentic Workflows
[Section titled “Using Copilot Agent Files from Agentic Workflows”](#using-copilot-agent-files-from-agentic-workflows)
Import Copilot agent files in your workflow using the `imports` field. Agent files can be imported from local `.github/agents/` directories or from external repositories.
### Local Agent File Import
[Section titled “Local Agent File Import”](#local-agent-file-import)
Import an agent from your repository:
```yaml
---
on: pull_request
engine: copilot
imports:
- .github/agents/my-agent.md
---
Review the pull request and provide feedback.
```
### Remote Agent File Import
[Section titled “Remote Agent File Import”](#remote-agent-file-import)
Import an agent file from an external repository using the `owner/repo/path@ref` format:
```yaml
---
on: pull_request
engine: copilot
imports:
- acme-org/shared-agents/.github/agents/code-reviewer.md@v1.0.0
---
Perform comprehensive code review using shared agent instructions.
```
The agent instructions are merged with the workflow prompt, customizing the AI engine’s behavior for specific tasks.
## Agent File Requirements
[Section titled “Agent File Requirements”](#agent-file-requirements)
* **Location**: Must be in a `.github/agents/` directory (local or remote repository)
* **Format**: Markdown with YAML frontmatter
* **Frontmatter**: Can include `name`, `description`, `tools`, and `mcp-servers`
* **One per workflow**: Only one agent file can be imported per workflow
* **Caching**: Remote agent files are cached by commit SHA in `.github/aw/imports/`
## Copilot Agent File Collections
[Section titled “Copilot Agent File Collections”](#copilot-agent-file-collections)
Organizations can create libraries of specialized custom agent files:
```text
acme-org/ai-agents/
└── .github/
└── agents/
├── code-reviewer.md # General code review
├── security-auditor.md # Security-focused analysis
├── performance-analyst.md # Performance optimization
├── accessibility-checker.md # WCAG compliance
└── documentation-writer.md # Technical documentation
```
Teams import agent files based on workflow needs:
Security-focused PR review
```yaml
---
on: pull_request
engine: copilot
imports:
- acme-org/ai-agents/.github/agents/security-auditor.md@v2.0.0
- acme-org/ai-agents/.github/agents/code-reviewer.md@v1.5.0
---
# Security Review
Perform comprehensive security review of this pull request.
```
## Combining Copilot Agent Files with Other Imports
[Section titled “Combining Copilot Agent Files with Other Imports”](#combining-copilot-agent-files-with-other-imports)
You can mix custom agent file imports with tool configurations and shared components:
```yaml
---
on: pull_request
engine: copilot
imports:
# Import specialized custom agent file
- acme-org/ai-agents/.github/agents/security-auditor.md@v2.0.0
# Import tool configurations
- acme-org/workflow-library/shared/tools/github-standard.md@v1.0.0
# Import MCP servers
- acme-org/workflow-library/shared/mcp/database.md@v1.0.0
# Import security policies
- acme-org/workflow-library/shared/config/security-policies.md@v1.0.0
permissions:
contents: read
safe-outputs:
create-pull-request-review-comment:
max: 10
---
# Comprehensive Security Review
Perform detailed security analysis using specialized agent files and tools.
```
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Imports Reference](/gh-aw/reference/imports/) - Complete import system documentation
* [Reusing Workflows](/gh-aw/guides/packaging-imports/) - Managing workflow imports
* [Frontmatter](/gh-aw/reference/frontmatter/) - Configuration options reference
# Cost Management
> Understand and control the cost of running GitHub Agentic Workflows, including Actions minutes, inference billing, and strategies to reduce spend.
The cost of running an agentic workflow is the sum of two components: **GitHub Actions minutes** consumed by the workflow jobs, and **inference costs** charged by the AI provider for each agent run.
## Cost Components
[Section titled “Cost Components”](#cost-components)
### GitHub Actions Minutes
[Section titled “GitHub Actions Minutes”](#github-actions-minutes)
Every workflow job consumes Actions compute time billed at standard [GitHub Actions pricing](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-actions/about-billing-for-github-actions). A typical agentic workflow run includes at least two jobs:
| Job | Purpose | Typical duration |
| -------------------------- | ----------------------------------------------------------------------------------- | ---------------- |
| Pre-activation / detection | Validates the trigger, runs membership checks, evaluates `skip-if-match` conditions | 10–30 seconds |
| Agent | Runs the AI engine and executes tools | 1–15 minutes |
Each job also incurs approximately 1.5 minutes of runner setup overhead on top of its execution time.
### Inference Costs
[Section titled “Inference Costs”](#inference-costs)
The agent job invokes an AI engine (Copilot, Claude, Codex, or a custom engine) to process the prompt and call tools. Inference is billed by the provider:
* **GitHub Copilot CLI** (`copilot` engine): Usage is billed as premium requests against the GitHub account that owns the [`COPILOT_GITHUB_TOKEN`](/gh-aw/reference/auth/#copilot_github_token). A typical workflow run uses 1–2 premium requests. See [GitHub Copilot billing](https://docs.github.com/en/copilot/about-github-copilot/subscription-plans-for-github-copilot).
* **Claude** (`claude` engine): Billed per token to the Anthropic account associated with [`ANTHROPIC_API_KEY`](/gh-aw/reference/auth/#anthropic_api_key).
* **Codex** (`codex` engine): Billed per token to the OpenAI account associated with [`OPENAI_API_KEY`](/gh-aw/reference/auth/#openai_api_key).
Note
For Copilot, inference is charged to the individual account owning `COPILOT_GITHUB_TOKEN`, not to the repository or organization running the workflow. Use a dedicated service account and monitor its premium request usage to track spend per workflow.
## Monitoring Costs with `gh aw logs`
[Section titled “Monitoring Costs with gh aw logs”](#monitoring-costs-with-gh-aw-logs)
The `gh aw logs` command downloads workflow run data and surfaces per-run metrics including elapsed duration, token usage, and estimated inference cost. Use it to see exactly what your workflows are consuming before deciding what to optimize.
For a deep dive into a single run’s token usage, tool calls, and inference spend, use `gh aw audit `. The **Metrics** and **Performance Metrics** sections of the audit report show token counts, effective tokens, turn counts, and estimated cost in one place — useful for diagnosing why a specific run was expensive. For cost trends across multiple runs, use `gh aw logs --format markdown [workflow]` to generate a cross-run report with metrics trends and anomaly detection.
### View recent run durations
[Section titled “View recent run durations”](#view-recent-run-durations)
```bash
# Overview table for all agentic workflows (last 10 runs)
gh aw logs
# Narrow to a single workflow
gh aw logs issue-triage-agent
# Last 30 days for Copilot workflows
gh aw logs --engine copilot --start-date -30d
```
The overview table includes a **Duration** column showing elapsed wall-clock time per run. Because GitHub Actions bills compute time by the minute (rounded up per job), duration is the primary indicator of Actions spend.
### Export metrics as JSON
[Section titled “Export metrics as JSON”](#export-metrics-as-json)
Use `--json` to get structured output suitable for scripting or trend analysis:
```bash
# Write JSON to a file for further processing
gh aw logs --start-date -1w --json > /tmp/logs.json
# List per-run duration, tokens, and cost across all workflows
gh aw logs --start-date -30d --json | \
jq '.runs[] | {workflow: .workflow_name, duration: .duration, cost: .estimated_cost}'
# Total cost grouped by workflow over the past 30 days
gh aw logs --start-date -30d --json | \
jq '[.runs[]] | group_by(.workflow_name) |
map({workflow: .[0].workflow_name, runs: length, total_cost: (map(.estimated_cost) | add // 0)})'
```
The JSON output includes `duration`, `token_usage`, `estimated_cost`, `workflow_name`, and `agent` (the engine ID) for each run under `.runs[]`.
For orchestrated workflows, the same JSON also includes deterministic lineage under `.episodes[]` and `.edges[]`. The episode rollups expose aggregate fields such as `total_runs`, `total_tokens`, `total_estimated_cost`, `risky_node_count`, and `suggested_route`, which are more useful than raw per-run metrics when one logical job spans multiple workflow runs.
```bash
# List episode-level cost and risk data over the past 30 days
gh aw logs --start-date -30d --json | \
jq '.episodes[] | {episode: .episode_id, workflow: .primary_workflow, runs: .total_runs, cost: .total_estimated_cost, risky_nodes: .risky_node_count}'
```
### Use inside a workflow agent
[Section titled “Use inside a workflow agent”](#use-inside-a-workflow-agent)
The `agentic-workflows` MCP tool exposes the same `logs` operation so that a workflow agent can collect cost data programmatically. Add `tools: agentic-workflows:` to any workflow that needs to read run metrics:
```aw
description: Weekly Actions minutes cost report
on: weekly
permissions:
actions: read
engine: copilot
tools:
agentic-workflows:
```
The agent then calls the `logs` tool with `start_date: "-7d"` to retrieve duration and cost data for all recent runs, enabling automated reporting or optimization.
## Trigger Frequency and Cost Risk
[Section titled “Trigger Frequency and Cost Risk”](#trigger-frequency-and-cost-risk)
The primary cost lever for most workflows is how often they run. Some events are inherently high-frequency:
| Trigger type | Risk | Notes |
| ---------------------------------------------- | --------------- | ------------------------------------------------------- |
| `push` | High | Every commit to any matching branch fires the workflow |
| `pull_request` | Medium–High | Fires on open, sync, re-open, label, and other subtypes |
| `issues` | Medium–High | Fires on open, close, label, edit, and other subtypes |
| `check_run`, `check_suite` | High | Can fire many times per push in busy repositories |
| `issue_comment`, `pull_request_review_comment` | Medium | Scales with comment activity |
| `schedule` | Low–Predictable | Fires at a fixed cadence; easy to budget |
| `workflow_dispatch` | Low | Human-initiated; naturally rate-limited |
Danger
Attaching an agentic workflow to `push`, `check_run`, or `check_suite` in an active repository can generate hundreds of runs per day. Start with `schedule` or `workflow_dispatch` while evaluating cost, then move to event-based triggers with safeguards in place.
## Reducing Cost
[Section titled “Reducing Cost”](#reducing-cost)
### Use Deterministic Checks to Skip the Agent
[Section titled “Use Deterministic Checks to Skip the Agent”](#use-deterministic-checks-to-skip-the-agent)
The most effective cost reduction is skipping the agent job entirely when it is not needed. The `skip-if-match` and `skip-if-no-match` conditions run during the low-cost pre-activation job and cancel the workflow before the agent starts:
```aw
on:
issues:
types: [opened]
skip-if-match: 'label:duplicate OR label:wont-fix'
```
```aw
on:
issues:
types: [labeled]
skip-if-no-match: 'label:needs-triage'
```
Use these to filter out noise before incurring inference costs. See [Triggers](/gh-aw/reference/triggers/) for the full syntax.
### Choose a Cheaper Model
[Section titled “Choose a Cheaper Model”](#choose-a-cheaper-model)
The `engine.model` field selects the AI model. Smaller or faster models cost significantly less per token while still handling many routine tasks:
```aw
engine:
id: copilot
model: gpt-4.1-mini
```
```aw
engine:
id: claude
model: claude-haiku-4-5
```
Reserve frontier models (GPT-5, Claude Sonnet, etc.) for complex tasks. Use lighter models for triage, labeling, summarization, and other structured outputs.
### Limit Context Size
[Section titled “Limit Context Size”](#limit-context-size)
Inference cost scales with the size of the prompt sent to the model. Reduce context by:
* Writing focused prompts that include only necessary information.
* Avoiding whole-file reads when only a few lines are relevant.
* Capping the number of search results or list items fetched by tools.
* Using `imports` to compose a smaller subset of prompt sections at runtime.
### Rate Limiting and Concurrency
[Section titled “Rate Limiting and Concurrency”](#rate-limiting-and-concurrency)
Use `rate-limit` to cap how many times a user can trigger the workflow in a given window, and rely on concurrency controls to serialize runs rather than letting them pile up:
```aw
rate-limit:
max: 3
window: 60 # 3 runs per hour per user
```
See [Rate Limiting Controls](/gh-aw/reference/rate-limiting-controls/) and [Concurrency](/gh-aw/reference/concurrency/) for details.
### Use Schedules for Predictable Budgets
[Section titled “Use Schedules for Predictable Budgets”](#use-schedules-for-predictable-budgets)
Scheduled workflows fire at a fixed cadence, making cost easy to estimate and cap:
```aw
schedule: daily on weekdays
```
One scheduled run per weekday = five agent invocations per week. See [Schedule Syntax](/gh-aw/reference/schedule-syntax/) for the full fuzzy schedule syntax.
## Agentic Cost Optimization
[Section titled “Agentic Cost Optimization”](#agentic-cost-optimization)
Agentic workflows can inspect and optimize other agentic workflows automatically. A scheduled meta-agent reads aggregate run data through the `agentic-workflows` MCP tool, identifies expensive or inefficient workflows, and applies changes — closing the optimization loop without manual intervention.
### How It Works
[Section titled “How It Works”](#how-it-works)
The `agentic-workflows` tool exposes the same operations as the CLI (`logs`, `audit`, `status`) to any workflow agent. A meta-agent can:
1. Fetch aggregate cost and token data with the `logs` tool (equivalent to `gh aw logs`).
2. Deep-dive into individual runs with the `audit` tool (equivalent to `gh aw audit `).
3. Propose or directly apply frontmatter changes (cheaper model, tighter `skip-if-match`, lower `rate-limit`) via a pull request.
### What to Optimize Automatically
[Section titled “What to Optimize Automatically”](#what-to-optimize-automatically)
| Signal | Automatic action |
| ------------------------------------------ | -------------------------------------------------------------- |
| High token count per run | Switch to a smaller model (`gpt-4.1-mini`, `claude-haiku-4-5`) |
| Frequent runs with no safe-output produced | Add or tighten `skip-if-match` |
| Long queue times due to concurrency | Lower `rate-limit.max` or add a `concurrency` group |
| Workflow running too often | Change trigger to `schedule` or add `workflow_dispatch` |
Note
The `agentic-workflows` tool requires `actions: read` permission and is configured under the `tools:` frontmatter key. See [GH-AW as an MCP Server](/gh-aw/reference/gh-aw-as-mcp-server/) for available operations.
## Common Scenario Estimates
[Section titled “Common Scenario Estimates”](#common-scenario-estimates)
These are rough estimates to help with budgeting. Actual costs vary by prompt size, tool usage, model, and provider pricing.
| Scenario | Frequency | Actions minutes/month | Inference/month |
| ----------------------------------------------------- | --------------- | --------------------- | -------------------------------- |
| Weekly digest (schedule, 1 repo) | 4×/month | \~1 min | \~4–8 premium requests (Copilot) |
| Issue triage (issues opened, 20/month) | 20×/month | \~10 min | \~20–40 premium requests |
| PR review on every push (busy repo, 100 pushes/month) | 100×/month | \~100 min | \~100–200 premium requests |
| On-demand via slash command | User-controlled | Varies | Varies |
Tip
Use `gh aw audit ` to deep-dive into token usage and cost for a single run. Use `gh aw logs --format markdown [workflow]` to analyze cost trends across multiple runs. Create separate `COPILOT_GITHUB_TOKEN` service accounts per repository or team to attribute spend by workflow.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Audit Commands](/gh-aw/reference/audit/) - Single-run analysis, diff, and cross-run reporting
* [Effective Tokens Specification](/gh-aw/reference/effective-tokens-specification/) - How effective token counts are computed
* [Triggers](/gh-aw/reference/triggers/) - Configuring workflow triggers and skip conditions
* [Rate Limiting Controls](/gh-aw/reference/rate-limiting-controls/) - Preventing runaway workflows
* [Concurrency](/gh-aw/reference/concurrency/) - Serializing workflow execution
* [AI Engines](/gh-aw/reference/engines/) - Engine and model configuration
* [Schedule Syntax](/gh-aw/reference/schedule-syntax/) - Cron schedule format
* [GH-AW as an MCP Server](/gh-aw/reference/gh-aw-as-mcp-server/) - `agentic-workflows` tool for self-inspection
* [FAQ](/gh-aw/reference/faq/) - Common questions including cost and billing
# Cross-Repository Operations
> Configure workflows to access, modify, and operate across multiple GitHub repositories using checkout, target-repo, and allowed-repos settings
Cross-repository operations enable workflows to access code from multiple repositories and create resources (issues, PRs, comments) in external repositories. This page documents all declarative frontmatter features for cross-repository workflows.
Cross-repository features fall into three categories:
1. **Cross-Repository Checkout** - Check out code from other repositories
2. **Cross-Repository Reading** - Read issues, pull requests and other information from other repositories
3. **Cross-Repository Safe Outputs** - Create issues, PRs, comments, and other resources in external repositories using `target-repo` and `allowed-repos` in safe outputs
All require additional authentication.
## Cross-Repository Checkout (`checkout:`)
[Section titled “Cross-Repository Checkout (checkout:)”](#cross-repository-checkout-checkout)
The `checkout:` frontmatter field controls how `actions/checkout` is invoked in the agent job. Use it to check out one or more repositories, override fetch depth or sparse-checkout settings, fetch additional refs (e.g., all open PR branches), or disable checkout entirely with `checkout: false`.
For multi-repository workflows, list multiple entries to clone several repos into the workspace. Mark the agent’s primary target with `current: true` when working from a central repository that targets a different repo.
```yaml
checkout:
- fetch-depth: 0 # checkout this repository with full history
fetch: ["refs/pulls/open/*"] # fetch all open PR branches after checkout
- repository: owner/other-repo # another repository to check out
path: ./libs/other # path within workspace to check out to
github-token: ${{ secrets.CROSS_REPO_PAT }} # additional auth for cross-repo access
```
See [GitHub Repository Checkout](/gh-aw/reference/checkout/) for the full configuration reference, including fetch options, sparse checkout, merging rules, and examples.
## Cross-Repository Reading
[Section titled “Cross-Repository Reading”](#cross-repository-reading)
The [GitHub Tools](/gh-aw/reference/github-tools/) are used to read information such as issues and pull requests from repositories. By default, these tools can access the current repository and all public repositories (if permitted by the network firewall). This set can be further restricted by using [GitHub Repository Access Restrictions](/gh-aw/reference/github-tools/#github-repository-access-restrictions-toolsgithuballowed-repos).
To read from other private repositories, you must configure additional authorization. Configure a PAT or GitHub App in your GitHub Tools configuration:
```yaml
tools:
github:
toolsets: [repos, issues, pull_requests]
github-token: ${{ secrets.CROSS_REPO_PAT }}
```
This enables operations like:
* Reading files and searching code in external repositories dynamically, even if the repository is not checked out
* Querying issues and pull requests from other repos
* Accessing commits, releases, and workflow runs across repositories
* Reading organization-level information
See [Additional Authentication for GitHub Tools](/gh-aw/reference/github-tools/#additional-authentication-for-github-tools) for full details on creating a PAT, using a GitHub App, or using the magic secret `GH_AW_GITHUB_MCP_SERVER_TOKEN`.
## Cross-Repository Safe Outputs
[Section titled “Cross-Repository Safe Outputs”](#cross-repository-safe-outputs)
Most safe output types support creating resources in external repositories using `target-repo` and `allowed-repos` parameters.
### Target Repository (`target-repo`)
[Section titled “Target Repository (target-repo)”](#target-repository-target-repo)
Specify a single target repository for resource creation:
```yaml
safe-outputs:
github-token: ${{ secrets.CROSS_REPO_PAT }}
create-issue:
target-repo: "org/tracking-repo"
title-prefix: "[component] "
```
Without `target-repo`, safe outputs operate on the repository where the workflow is running.
### Wildcard Target Repository (`target-repo: "*"`)
[Section titled “Wildcard Target Repository (target-repo: "\*")”](#wildcard-target-repository-target-repo-)
Set `target-repo: "*"` to allow the agent to dynamically target any repository at runtime. When configured, the agent receives a `repo` parameter in its tool call where it supplies the target repository in `owner/repo` format:
```yaml
safe-outputs:
github-token: ${{ secrets.CROSS_REPO_PAT }}
create-issue:
target-repo: "*"
title-prefix: "[component] "
```
Use this when the target repository is not known at workflow authoring time — for example, when building a workflow that routes issues to different repositories based on labels or content.
Caution
The following safe-output types do **not** support `target-repo: "*"`: `create-pull-request-review-comment`, `reply-to-pull-request-review-comment`, `submit-pull-request-review`, `create-agent-session`, and `manage-project-items`. Use an explicit `owner/repo` value or `allowed-repos` for these types.
### Allowed Repositories (`allowed-repos`)
[Section titled “Allowed Repositories (allowed-repos)”](#allowed-repositories-allowed-repos)
Allow the agent to dynamically select from multiple repositories:
```yaml
safe-outputs:
github-token: ${{ secrets.CROSS_REPO_PAT }}
create-issue:
target-repo: "org/default-repo"
allowed-repos: ["org/repo-a", "org/repo-b", "org/repo-c"]
title-prefix: "[cross-repo] "
```
When `allowed-repos` is specified:
* Agent can include a `repo` field in output to select which repository
* Target repository (from `target-repo` or current repo) is always implicitly allowed
* Creates a union of allowed destinations
## Examples
[Section titled “Examples”](#examples)
### Example: Monorepo Development
[Section titled “Example: Monorepo Development”](#example-monorepo-development)
This uses multiple `checkout:` entries to check out different parts of the same repository with different settings:
```aw
---
on:
pull_request:
types: [opened, synchronize]
checkout:
- fetch-depth: 0
- repository: org/shared-libs
path: ./libs/shared
ref: main
github-token: ${{ secrets.LIBS_PAT }}
- repository: org/config-repo
path: ./config
sparse-checkout: |
defaults/
overrides/
permissions:
contents: read
pull-requests: read
---
# Cross-Repo PR Analysis
Analyze this PR considering shared library compatibility and configuration standards.
Check compatibility with shared libraries in `./libs/shared` and verify configuration against standards in `./config`.
```
### Example: Hub-and-Spoke Tracking
[Section titled “Example: Hub-and-Spoke Tracking”](#example-hub-and-spoke-tracking)
This creates issues in a central tracking repository when issues are opened in component repositories:
```aw
---
on:
issues:
types: [opened, labeled]
permissions:
contents: read
issues: read
safe-outputs:
github-token: ${{ secrets.CROSS_REPO_PAT }}
create-issue:
target-repo: "org/central-tracker"
title-prefix: "[component-a] "
labels: [tracking, multi-repo]
max: 1
---
# Cross-Repository Issue Tracker
When issues are created in this component repository, create tracking issues in the central coordination repo.
Analyze the issue and create a tracking issue that:
- Links back to the original component issue
- Summarizes the problem and impact
- Tags relevant teams for coordination
```
### Example: Cross-Repository Analysis
[Section titled “Example: Cross-Repository Analysis”](#example-cross-repository-analysis)
This checks out multiple repositories and compares code patterns across them:
```aw
---
on:
issue_comment:
types: [created]
tools:
github:
toolsets: [repos, issues, pull_requests]
github-token: ${{ secrets.CROSS_REPO_PAT }}
permissions:
contents: read
issues: read
safe-outputs:
github-token: ${{ secrets.CROSS_REPO_WRITE_PAT }}
add-comment:
max: 1
---
# Multi-Repository Code Search
Search for similar patterns across org/repo-a, org/repo-b, and org/repo-c.
Analyze how each repository implements authentication and provide a comparison.
```
### Example: Deterministic Multi-Repo Workflows
[Section titled “Example: Deterministic Multi-Repo Workflows”](#example-deterministic-multi-repo-workflows)
For direct repository access without agent involvement, use custom steps with `actions/checkout`:
```aw
---
engine:
id: claude
steps:
- name: Checkout main repo
uses: actions/checkout@v6
with:
path: main-repo
- name: Checkout secondary repo
uses: actions/checkout@v6
with:
repository: org/secondary-repo
token: ${{ secrets.CROSS_REPO_PAT }}
path: secondary-repo
permissions:
contents: read
---
# Compare Repositories
Compare code structure between main-repo and secondary-repo.
```
This approach provides full control over checkout timing and configuration.
### Example: Scheduled Push to Pull-Request Branch
[Section titled “Example: Scheduled Push to Pull-Request Branch”](#example-scheduled-push-to-pull-request-branch)
A scheduled workflow that automatically pushes changes to open pull-request branches in another repository needs to fetch those branches after checkout. Without `fetch:`, only the default branch (usually `main`) is available.
```aw
---
on:
schedule:
- cron: "0 * * * *"
checkout:
- repository: org/target-repo
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
fetch: ["refs/pulls/open/*"] # fetch all open PR branches after checkout
current: true
permissions:
contents: read
safe-outputs:
github-token: ${{ secrets.GH_AW_SIDE_REPO_PAT }}
push-to-pull-request-branch:
target-repo: "org/target-repo"
---
# Auto-Update PR Branches
Check open pull requests in org/target-repo and apply any pending automated
updates to each PR branch.
```
`fetch: ["refs/pulls/open/*"]` causes a `git fetch` step to run after `actions/checkout`, downloading all open PR head refs into the workspace. The agent can then inspect and modify those branches directly.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [GitHub Repository Checkout](/gh-aw/reference/checkout/) - Full checkout configuration reference
* [MultiRepoOps Pattern](/gh-aw/patterns/multi-repo-ops/) - Cross-repository workflow pattern
* [CentralRepoOps Pattern](/gh-aw/patterns/central-repo-ops/) - Central control plane pattern
* [GitHub Tools Reference](/gh-aw/reference/github-tools/) - Complete GitHub Tools configuration
* [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Complete safe output configuration
* [Authentication Reference](/gh-aw/reference/auth/) - PAT and GitHub App setup
* [Multi-Repository Examples](/gh-aw/examples/multi-repo/) - Complete working examples
# Copilot Agent Files support for Agentic Workflows
> How to create, update, import, and debug agentic workflows using our AI agent.
“Custom Agents” are added prompts that can be used with Copilot, Copilot CLI and VSCode Agent Mode to provide specialized behavior for specific tasks.
In this guide, we show you how to install and use the custom agent `agentic-workflows` to create, update, import, and debug agentic workflows in your repository.
## Installing the Copilot Agent Files for Agentic Workflows
[Section titled “Installing the Copilot Agent Files for Agentic Workflows”](#installing-the-copilot-agent-files-for-agentic-workflows)
Follow these steps to set up your repository for agentic workflows using the custom `agentic-workflows` agent.
1. **Start your coding agent**.
* Navigate to your repository on and click the “Agents” tab, or
* Start [VSCode Agent Mode](https://code.visualstudio.com/docs/copilot/agents/overview), or
* Start your coding agent in your repository
2. **Install the Copilot Agent Files for Agentic Workflows into your repository**.
```text
Initialize this repository for GitHub Agentic Workflows using https://github.com/github/gh-aw/blob/main/install.md
```
Alternatively just run
```bash
gh aw init
```
After initialization, you’ll have `.github/agents/agentic-workflows.agent.md`, a [Copilot agent file](/gh-aw/reference/glossary/#agent-files) that registers the `/agent agentic-workflows` command in Copilot Chat.
## Using the Copilot Agent Files for Agentic Workflows
[Section titled “Using the Copilot Agent Files for Agentic Workflows”](#using-the-copilot-agent-files-for-agentic-workflows)
Once your repository is set up for agentic workflows, you can use the `agentic-workflows` agent from VSCode or GitHub.com to perform a variety of tasks:
### Creating New Agentic Workflows
[Section titled “Creating New Agentic Workflows”](#creating-new-agentic-workflows)
Navigate to your repository on and click the “Agents” tab, then use this prompt:
```text
# Create a new workflow
/agent agentic-workflows create a workflow that triages issues
```
The agent will generate a workflow file in `.github/workflows/`, write the frontmatter and prompt, configure tools and permissions, and compile to `.lock.yml`.
### Updating Existing Workflows
[Section titled “Updating Existing Workflows”](#updating-existing-workflows)
Modify or improve existing workflows using natural language prompts:
```text
/agent agentic-workflows update the issue-triage workflow to add web-fetch tool and
improve the prompt for better accuracy
```
### Upgrading Agentic Workflows
[Section titled “Upgrading Agentic Workflows”](#upgrading-agentic-workflows)
Keep workflows up-to-date with the latest `gh-aw` versions and features:
```text
/agent agentic-workflows upgrade all workflows to latest version
```
### Importing Workflows
[Section titled “Importing Workflows”](#importing-workflows)
Import workflows from any accessible GitHub repository:
```text
/agent agentic-workflows import workflow from https://github.com/githubnext/agentics/blob/main/workflows/ci-doctor.md
```
When importing, you can specify customizations such as engine or tools:
```text
/agent agentic-workflows import issue-triage from githubnext/agentics and use claude engine
```
### Debugging Agentic Workflows
[Section titled “Debugging Agentic Workflows”](#debugging-agentic-workflows)
When workflows fail or behave unexpectedly, use the agentic-workflows agent to investigate and diagnose issues:
```text
/agent agentic-workflows debug why is my issue-triage workflow failing?
```
For the fastest diagnosis, pass the full run URL from the GitHub Actions page:
```text
/agent agentic-workflows debug https://github.com/OWNER/REPO/actions/runs/RUN_ID
```
The agent audits logs, identifies the root cause, and suggests targeted fixes. It handles permission errors, missing tools, network access issues, and safe-output problems — just describe the issue in natural language.
### Self-Contained Debugging (Without Copilot)
[Section titled “Self-Contained Debugging (Without Copilot)”](#self-contained-debugging-without-copilot)
If your repository is not yet set up with the `agentic-workflows` agent, or if you prefer to use a different AI assistant, use the standalone debugging prompt by sharing its URL:
```text
Debug this workflow run using https://raw.githubusercontent.com/github/gh-aw/main/debug.md
The failed workflow run is at https://github.com/OWNER/REPO/actions/runs/RUN_ID
```
Copy debug instructions
The `debug.md` file is a self-contained prompt that works with any coding agent or AI assistant. It guides the agent to install `gh aw`, analyze the run logs, identify the root cause, and open a pull request with the fix.
## Creating Agentic Workflows with an AI Chatbot
[Section titled “Creating Agentic Workflows with an AI Chatbot”](#creating-agentic-workflows-with-an-ai-chatbot)
If you prefer to use an AI chatbot to author agentic workflows, use the [agentic-chat instructions](https://raw.githubusercontent.com/github/gh-aw/main/.github/aw/agentic-chat.md) with any conversational AI application. Copy agentic-chat instructions
Copy the instructions into your AI chat interface, describe your workflow goal, and the assistant will generate a structured task description you can use in your workflow. It focuses on clear, actionable specifications rather than implementation details.
## Dictating Agentic Workflows
[Section titled “Dictating Agentic Workflows”](#dictating-agentic-workflows)
When creating agentic workflows using speech-to-text (dictation), you may encounter terminology mismatches and formatting issues common to voice recognition systems. To help correct these issues, use the [dictation instructions prompt](https://raw.githubusercontent.com/github/gh-aw/main/skills/dictation/SKILL.md) or Copy dictation instructions .
This prompt corrects terminology (e.g., “ghaw” → “gh-aw”), removes filler words, and transforms dictated sentences into clear, imperative task descriptions. Load it into your AI assistant before or after dictating to improve accuracy.
# Custom Safe Outputs
> How to create custom safe outputs for third-party integrations using custom jobs and MCP servers.
Custom safe outputs extend built-in GitHub operations to integrate with third-party services — Slack, Discord, Notion, Jira, databases, or any external API requiring authentication. Use them for any write operation that built-in safe outputs don’t cover.
## Quick Start
[Section titled “Quick Start”](#quick-start)
Here’s a minimal custom safe output that sends a Slack message:
.github/workflows/shared/slack-notify.md
```yaml
---
safe-outputs:
jobs:
slack-notify:
description: "Send a message to Slack"
runs-on: ubuntu-latest
output: "Message sent to Slack!"
inputs:
message:
description: "The message to send"
required: true
type: string
steps:
- name: Send Slack message
env:
SLACK_WEBHOOK: "${{ secrets.SLACK_WEBHOOK }}"
run: |
if [ -f "$GH_AW_AGENT_OUTPUT" ]; then
MESSAGE=$(cat "$GH_AW_AGENT_OUTPUT" | jq -r '.items[] | select(.type == "slack_notify") | .message')
# Use jq to safely escape JSON content
PAYLOAD=$(jq -n --arg text "$MESSAGE" '{text: $text}')
curl -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "$PAYLOAD"
else
echo "No agent output found"
exit 1
fi
---
```
Use it in a workflow:
.github/workflows/issue-notifier.md
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
imports:
- shared/slack-notify.md
---
# Issue Notifier
A new issue was opened: "${{ steps.sanitized.outputs.text }}"
Summarize the issue and use the slack-notify tool to send a notification.
```
The agent can now call `slack-notify` with a message, and the custom job executes with access to the `SLACK_WEBHOOK` secret.
## Architecture
[Section titled “Architecture”](#architecture)
Custom safe outputs separate read and write operations: agents use read-only Model Context Protocol (MCP) servers with `allowed:` tool lists, while custom jobs handle write operations with secret access after agent completion.
```text
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Agent (AI) │────│ MCP Server │────│ External API │
│ │ │ (read-only) │ │ (GET requests) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
│ calls safe-job tool
▼
┌─────────────────┐ ┌─────────────────┐
│ Custom Job │────│ External API │
│ (with secrets) │ │ (POST/PUT) │
└─────────────────┘ └─────────────────┘
```
## Creating a Custom Safe Output
[Section titled “Creating a Custom Safe Output”](#creating-a-custom-safe-output)
### Step 1: Define the Shared Configuration
[Section titled “Step 1: Define the Shared Configuration”](#step-1-define-the-shared-configuration)
In a shared file, define the read-only MCP server and the custom job together:
```yaml
---
mcp-servers:
notion:
container: "mcp/notion"
env:
NOTION_TOKEN: "${{ secrets.NOTION_TOKEN }}"
allowed:
- "search_pages"
- "get_page"
- "get_database"
- "query_database"
safe-outputs:
jobs:
notion-add-comment:
description: "Add a comment to a Notion page"
runs-on: ubuntu-latest
output: "Comment added to Notion successfully!"
permissions:
contents: read
inputs:
page_id:
description: "The Notion page ID to add a comment to"
required: true
type: string
comment:
description: "The comment text to add"
required: true
type: string
steps:
- name: Add comment to Notion page
uses: actions/github-script@v8
env:
NOTION_TOKEN: "${{ secrets.NOTION_TOKEN }}"
with:
script: |
const fs = require('fs');
const notionToken = process.env.NOTION_TOKEN;
const outputFile = process.env.GH_AW_AGENT_OUTPUT;
if (!notionToken) {
core.setFailed('NOTION_TOKEN secret is not configured');
return;
}
if (!outputFile) {
core.info('No GH_AW_AGENT_OUTPUT environment variable found');
return;
}
// Read and parse agent output
const fileContent = fs.readFileSync(outputFile, 'utf8');
const agentOutput = JSON.parse(fileContent);
// Filter for notion-add-comment items (job name with dashes → underscores)
const items = agentOutput.items.filter(item => item.type === 'notion_add_comment');
for (const item of items) {
const pageId = item.page_id;
const comment = item.comment;
core.info(`Adding comment to Notion page: ${pageId}`);
try {
const response = await fetch('https://api.notion.com/v1/comments', {
method: 'POST',
headers: {
'Authorization': `Bearer ${notionToken}`,
'Notion-Version': '2022-06-28',
'Content-Type': 'application/json'
},
body: JSON.stringify({
parent: { page_id: pageId },
rich_text: [{
type: 'text',
text: { content: comment }
}]
})
});
if (!response.ok) {
const errorData = await response.text();
core.setFailed(`Notion API error (${response.status}): ${errorData}`);
return;
}
const data = await response.json();
core.info('Comment added successfully');
core.info(`Comment ID: ${data.id}`);
} catch (error) {
core.setFailed(`Failed to add comment: ${error.message}`);
return;
}
}
---
```
Use `container:` for Docker servers or `command:`/`args:` for npx. List only read-only tools in `allowed`. All jobs require `description` and `inputs`. Use `output` for success messages and `actions/github-script@v8` for API calls with `core.setFailed()` error handling.
### Step 2: Use in Workflow
[Section titled “Step 2: Use in Workflow”](#step-2-use-in-workflow)
Import the configuration:
```aw
---
on:
issues:
types: [opened]
permissions:
contents: read
actions: read
imports:
- shared/mcp/notion.md
---
# Issue Summary to Notion
Analyze the issue: "${{ steps.sanitized.outputs.text }}"
Search for the GitHub Issues page in Notion using the read-only Notion tools, then add a summary comment using the notion-add-comment safe-job.
```
The agent uses read-only tools to query, then calls the safe-job which executes with write permissions after completion.
## Safe Job Reference
[Section titled “Safe Job Reference”](#safe-job-reference)
### Job Properties
[Section titled “Job Properties”](#job-properties)
| Property | Type | Required | Description |
| ----------------- | --------------- | -------- | -------------------------------------------------------------------------------------- |
| `description` | string | Yes | Tool description shown to the agent |
| `runs-on` | string | Yes | GitHub Actions runner (e.g., `ubuntu-latest`) |
| `inputs` | object | Yes | Tool parameters (see [Input Types](#input-types)) |
| `steps` | array | Yes | GitHub Actions steps to execute |
| `output` | string | No | Success message returned to the agent |
| `needs` | string or array | No | Jobs that must complete before this job runs (see [Job Ordering](#job-ordering-needs)) |
| `permissions` | object | No | GitHub token permissions for the job |
| `env` | object | No | Environment variables for all steps |
| `if` | string | No | Conditional execution expression |
| `timeout-minutes` | number | No | Maximum job duration (GitHub Actions default: 360) |
### Job Ordering (`needs:`)
[Section titled “Job Ordering (needs:)”](#job-ordering-needs)
Use `needs:` to sequence a custom safe-output job relative to other jobs in the compiled workflow. Unlike manually patching `needs:` in the lock file (which gets overwritten on every recompile), `needs:` declared in the frontmatter persists across recompiles.
```yaml
safe-outputs:
create-issue: {}
jobs:
post-process:
needs: safe_outputs # runs after the consolidated safe-outputs job
steps:
- run: echo "post-processing"
```
The compiler validates each `needs:` entry at compile time and fails with a clear error if the target does not exist. Target names with dashes are automatically normalized to underscores (e.g., `safe-outputs` → `safe_outputs`).
Valid `needs:` targets for custom safe-jobs:
| Target | Available when |
| --------------- | ------------------------------------------------------------------------ |
| `agent` | Always |
| `safe_outputs` | At least one builtin handler, script, action, or user step is configured |
| `detection` | Threat detection is enabled |
| `upload_assets` | `upload-asset` is configured |
| `unlock` | `lock-for-agent` is enabled |
| `` | That job exists in `safe-outputs.jobs` |
Self-dependencies and cycles between custom jobs are also caught at compile time.
### Input Types
[Section titled “Input Types”](#input-types)
All jobs must define `inputs`:
| Type | Description |
| --------- | ---------------------------------------------- |
| `string` | Text input |
| `boolean` | True/false (as strings: `"true"` or `"false"`) |
| `choice` | Selection from predefined options |
```yaml
inputs:
message:
description: "Message content"
required: true
type: string
notify:
description: "Send notification"
required: false
type: boolean
default: "true"
environment:
description: "Target environment"
required: true
type: choice
options: ["staging", "production"]
```
### Environment Variables
[Section titled “Environment Variables”](#environment-variables)
Custom safe-output jobs have access to these environment variables:
| Variable | Description |
| --------------------------- | ---------------------------------------------------- |
| `GH_AW_AGENT_OUTPUT` | Path to JSON file containing the agent’s output data |
| `GH_AW_SAFE_OUTPUTS_STAGED` | Set to `"true"` when running in staged/preview mode |
### Accessing Agent Output
[Section titled “Accessing Agent Output”](#accessing-agent-output)
Custom safe-output jobs receive the agent’s data through the `GH_AW_AGENT_OUTPUT` environment variable, which contains a path to a JSON file. This file has the structure:
```json
{
"items": [
{
"type": "job_name_with_underscores",
"field1": "value1",
"field2": "value2"
}
]
}
```
The `type` field matches your job name with dashes converted to underscores (e.g., job `webhook-notify` → type `webhook_notify`).
#### Example
[Section titled “Example”](#example)
```yaml
steps:
- name: Process output
run: |
if [ -f "$GH_AW_AGENT_OUTPUT" ]; then
MESSAGE=$(cat "$GH_AW_AGENT_OUTPUT" | jq -r '.items[] | select(.type == "my_job") | .message')
echo "Message: $MESSAGE"
else
echo "No agent output found"
exit 1
fi
```
The `inputs:` schema serves as both the MCP tool definition visible to the agent and validation for the output fields written to `GH_AW_AGENT_OUTPUT`.
## Inline Script Handlers (`safe-outputs.scripts`)
[Section titled “Inline Script Handlers (safe-outputs.scripts)”](#inline-script-handlers-safe-outputsscripts)
Use `safe-outputs.scripts` to define lightweight inline JavaScript handlers that execute inside the consolidated safe-outputs job handler loop. Unlike `jobs` (which create a separate GitHub Actions job for each tool call), scripts run in-process alongside the built-in safe-output handlers — there is no extra job allocation or startup overhead.
**When to use scripts vs jobs:**
| | Scripts | Jobs |
| --------- | -------------------------------------------------------------- | ------------------------------------ |
| Execution | In-process, in the consolidated safe-outputs job | Separate GitHub Actions job |
| Startup | Fast (no job scheduling) | Slower (new job per call) |
| Secrets | Not directly available — use for lightweight logic | Full access to repository secrets |
| Use case | Lightweight processing, logging, notifications without secrets | External API calls requiring secrets |
### Defining a Script
[Section titled “Defining a Script”](#defining-a-script)
Under `safe-outputs.scripts`, define each handler with a `description`, `inputs`, and `script` body:
.github/workflows/my-workflow\.md
```yaml
---
safe-outputs:
scripts:
post-slack-message:
description: Post a message to a Slack channel
inputs:
channel:
description: Slack channel name
required: true
type: string
message:
description: Message text
required: true
type: string
script: |
const targetChannel = item.channel || "#general";
const text = item.message || "(no message)";
core.info(`Posting to ${targetChannel}: ${text}`);
return { success: true, channel: targetChannel };
---
```
The agent calls `post_slack_message` (dashes normalized to underscores) and the script runs synchronously in the handler loop.
### Script Body Context
[Section titled “Script Body Context”](#script-body-context)
Write only the handler body — the compiler wraps it automatically. Inside the body you have access to:
| Variable | Description |
| ---------------------- | ----------------------------------------------------------------------------- |
| `item` | Runtime message object with field values matching your `inputs` schema |
| `core` | `@actions/core` for logging (`core.info()`, `core.warning()`, `core.error()`) |
| `resolvedTemporaryIds` | Map of temporary object IDs resolved at runtime |
Each input declared in `inputs` is also destructured into a local variable. For example, an `inputs.channel` entry is available as `item.channel`.
```javascript
// Example: access inputs via item
const channel = item.channel;
const message = item.message;
core.info(`Sending to ${channel}: ${message}`);
return { sent: true };
```
Note
Script names with dashes are normalized to underscores when registered as MCP tools (e.g., `post-slack-message` becomes `post_slack_message`). The normalized name is what the agent uses to call the tool.
### Script Reference
[Section titled “Script Reference”](#script-reference)
| Property | Type | Required | Description |
| ------------- | ------ | -------- | -------------------------------------------- |
| `description` | string | Yes | Tool description shown to the agent |
| `inputs` | object | Yes | Tool parameters (same schema as custom jobs) |
| `script` | string | Yes | JavaScript handler body |
Scripts support the same `inputs` types as custom jobs: `string`, `boolean`, and `number`.
## GitHub Action Wrappers (`safe-outputs.actions`)
[Section titled “GitHub Action Wrappers (safe-outputs.actions)”](#github-action-wrappers-safe-outputsactions)
Use `safe-outputs.actions` to mount any public GitHub Action as a once-callable MCP tool. At compile time, `gh aw compile` fetches the action’s `action.yml` to resolve its inputs and pins the action reference to a specific SHA. The agent can call the tool once per workflow run; the action executes inside the consolidated safe-outputs job.
**When to use actions vs scripts vs jobs:**
| | Actions | Scripts | Jobs |
| --------- | ----------------------------------------------- | ------------------------------------------------ | --------------------------------- |
| Execution | In the consolidated safe-outputs job, as a step | In-process, in the consolidated safe-outputs job | Separate GitHub Actions job |
| Reuse | Any public GitHub Action | Custom inline JavaScript | Custom inline YAML job |
| Secrets | Full access via `env:` | Not directly available | Full access to repository secrets |
| Use case | Reuse existing marketplace actions | Lightweight logic | Complex multi-step workflows |
### Defining an Action
[Section titled “Defining an Action”](#defining-an-action)
Under `safe-outputs.actions`, define each action with a `uses` field (matching GitHub Actions `uses` syntax) and an optional `description` override:
.github/workflows/my-workflow\.md
```yaml
---
safe-outputs:
actions:
add-smoked-label:
uses: actions-ecosystem/action-add-labels@v1
description: Add the 'smoked' label to the current pull request
env:
GITHUB_TOKEN: ${{ github.token }}
---
```
The agent calls `add_smoked_label` (dashes normalized to underscores). The action’s declared inputs become the tool’s parameters — values are passed as step inputs at runtime.
### Action Reference
[Section titled “Action Reference”](#action-reference)
| Property | Type | Required | Description |
| ------------- | ------ | -------- | ---------------------------------------------------------------------------- |
| `uses` | string | Yes | Action reference (`owner/repo@ref` or `./path/to/local-action`) |
| `description` | string | No | Tool description shown to the agent (overrides the action’s own description) |
| `env` | object | No | Additional environment variables injected into the action step |
Note
Action names with dashes are normalized to underscores when registered as MCP tools (e.g., `add-smoked-label` becomes `add_smoked_label`). The normalized name is what the agent uses to call the tool.
Tip
Action references are pinned to a SHA at compile time for reproducibility. Run `gh aw compile` again to update pinned SHAs after an upstream action release.
## Importing Custom Jobs
[Section titled “Importing Custom Jobs”](#importing-custom-jobs)
Define jobs in shared files under `.github/workflows/shared/` and import them:
```aw
---
on: issues
permissions:
contents: read
imports:
- shared/slack-notify.md
- shared/jira-integration.md
---
# Issue Handler
Handle the issue and notify via Slack and Jira.
```
Jobs with duplicate names cause compilation errors - rename to resolve conflicts.
## Error Handling
[Section titled “Error Handling”](#error-handling)
Use `core.setFailed()` for errors and validate required inputs:
```javascript
if (!process.env.API_KEY) {
core.setFailed('API_KEY secret is not configured');
return;
}
try {
const response = await fetch(url);
if (!response.ok) {
core.setFailed(`API error (${response.status}): ${await response.text()}`);
return;
}
core.info('Operation completed successfully');
} catch (error) {
core.setFailed(`Request failed: ${error.message}`);
}
```
## Security
[Section titled “Security”](#security)
Store secrets in GitHub Secrets and pass via environment variables. Limit job permissions to minimum required and validate all inputs.
## Staged Mode Support
[Section titled “Staged Mode Support”](#staged-mode-support)
When `GH_AW_SAFE_OUTPUTS_STAGED === 'true'`, skip the real operation and display a preview using `core.summary`. See [Staged Mode](/gh-aw/reference/staged-mode/#staged-mode-for-custom-safe-output-jobs) for a complete example.
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
| Issue | Solution |
| ----------------------------------- | -------------------------------------------------------------------------------------- |
| Job or script not appearing as tool | Ensure `inputs` and `description` are defined; verify import path; run `gh aw compile` |
| Secrets not available | Check secret exists in repository settings and name matches exactly (case-sensitive) |
| Job fails silently | Add `core.info()` logging and ensure `core.setFailed()` is called on errors |
| Agent calls wrong tool | Make `description` specific and unique; explicitly mention job name in prompt |
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Deterministic & Agentic Patterns](/gh-aw/guides/deterministic-agentic-patterns/) - Mixing computation and AI reasoning
* [Safe Outputs](/gh-aw/reference/safe-outputs/) - Built-in safe output types
* [MCPs](/gh-aw/guides/mcps/) - Model Context Protocol setup
* [Frontmatter](/gh-aw/reference/frontmatter/) - All configuration options
* [Imports](/gh-aw/reference/imports/) - Sharing workflow configurations
# Dependabot Manifest Generation
> Automatic dependency manifest generation for tracking runtime dependencies in agentic workflows, enabling Dependabot to detect and update outdated tools.
The `gh aw compile --dependabot` command scans workflows for runtime tools (`npx`, `pip install`, `go install`), generates dependency manifests (`package.json`, `requirements.txt`, `go.mod`), and configures Dependabot to monitor for updates
## Usage
[Section titled “Usage”](#usage)
Run `gh aw compile --dependabot` to compile all workflows and generate manifests in `.github/workflows/`.
Caution
Must compile **all workflows** - cannot be used with specific files or `--dir` flag.
**Prerequisites**: Node.js/npm required for `package-lock.json` generation. Pip and Go manifests generate without additional tools.
## Generated Files
[Section titled “Generated Files”](#generated-files)
| Ecosystem | Manifest | Lock File |
| --------- | ------------------ | ----------------------------------------------------------- |
| **npm** | `package.json` | `package-lock.json` (via `npm install --package-lock-only`) |
| **pip** | `requirements.txt` | - |
| **Go** | `go.mod` | - |
All ecosystems update `.github/dependabot.yml` with weekly update schedules. Existing configurations are preserved; only missing ecosystems are added.
## Handling Dependabot PRs
[Section titled “Handling Dependabot PRs”](#handling-dependabot-prs)
Caution
**Never merge Dependabot PRs that only modify manifest files.** These changes are overwritten on next compilation.
**Correct workflow**: Update source `.md` files, then recompile to regenerate manifests.
```bash
# Find affected workflows
grep -r "@playwright/test@1.41.0" .github/workflows/*.md
# Edit workflow .md files (change version)
# npx @playwright/test@1.41.0 → npx @playwright/test@1.42.0
# Regenerate manifests
gh aw compile --dependabot
# Commit (Dependabot auto-closes its PR)
git add .github/workflows/
git commit -m "chore: update @playwright/test to 1.42.0"
git push
```
### Handling Transitive Dependencies (MCP Servers)
[Section titled “Handling Transitive Dependencies (MCP Servers)”](#handling-transitive-dependencies-mcp-servers)
When Dependabot flags transitive dependencies (e.g., `@modelcontextprotocol/sdk`, `hono` from `@sentry/mcp-server`), update the **shared MCP configuration** instead:
```bash
# Locate the shared MCP config (e.g., .github/workflows/shared/mcp/sentry.md)
# Update the version in the args array:
# args: ["@sentry/mcp-server@0.27.0"] → args: ["@sentry/mcp-server@0.29.0"]
# Regenerate manifests
gh aw compile --dependabot
# Regenerate package-lock.json to pick up transitive dependency updates
cd .github/workflows && npm install --package-lock-only
# Commit changes
git add .github/workflows/
git commit -m "chore: update @sentry/mcp-server to 0.29.0"
git push
```
**Why?** The compiler generates `package.json` from MCP server configurations in workflow files. Directly editing `package.json` will be overwritten on next compilation.
## AI Agent Prompt Template
[Section titled “AI Agent Prompt Template”](#ai-agent-prompt-template)
```markdown
A Dependabot PR updated dependencies in .github/workflows/.
Fix workflow:
1. Identify which .md files reference the outdated dependency
2. Update versions in workflow files
3. Run `gh aw compile --dependabot` to regenerate manifests
4. Verify manifests match the Dependabot PR
5. Commit and push (Dependabot auto-closes)
Affected PR: [link]
Updated dependency: [name@version]
```
## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
| Issue | Solution |
| --------------------------------- | ---------------------------------------------------------------------- |
| **package-lock.json not created** | Install Node.js/npm from [nodejs.org](https://nodejs.org/) |
| **Dependency not detected** | Avoid shell variables (`${TOOL}`); use literal package names |
| **Dependabot not opening PRs** | Verify `.github/dependabot.yml` is valid YAML and manifest files exist |
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [CLI Commands](/gh-aw/setup/cli/#compile) - Complete compile command reference
* [Compilation Process](/gh-aw/reference/compilation-process/) - How compilation works
* [GitHub Dependabot Docs](https://docs.github.com/en/code-security/dependabot) - Official Dependabot guide
# APM Dependencies
> Install and manage APM (Agent Package Manager) packages in your agentic workflows, including skills, prompts, instructions, agents, hooks, and plugins.
[APM (Agent Package Manager)](https://microsoft.github.io/apm/) manages AI agent primitives such as skills, prompts, instructions, agents, hooks, and plugins (including the Claude `plugin.json` specification). Packages can depend on other packages and APM resolves the full dependency tree.
APM is configured by importing the `shared/apm.md` workflow, which creates a dedicated `apm` job that packs packages and uploads the bundle as a GitHub Actions artifact. The agent job then downloads and unpacks the bundle for deterministic startup.
Note
The `dependencies:` frontmatter field is deprecated and no longer supported. Migrate to the import-based approach shown below.
## Usage
[Section titled “Usage”](#usage)
Import `shared/apm.md` and supply the list of packages via the `packages` parameter:
```aw
imports:
- uses: shared/apm.md
with:
packages:
- microsoft/apm-sample-package
- github/awesome-copilot/skills/review-and-refactor
- anthropics/skills/skills/frontend-design
```
## Reproducibility and governance
[Section titled “Reproducibility and governance”](#reproducibility-and-governance)
APM lock files (`apm.lock`) pin every package to an exact commit SHA, so the same versions are installed on every run. Lock file diffs appear in pull requests and are reviewable before merge, giving teams and enterprises a clear audit trail and the ability to govern which agent context is in use. See the [APM governance guide](https://microsoft.github.io/apm/enterprise/governance/) for details on policy enforcement and access controls.
## Package reference formats
[Section titled “Package reference formats”](#package-reference-formats)
Each entry in `packages` is an APM package reference. Supported formats:
| Format | Description |
| ------------------------------ | ------------------------------------------------------------------------- |
| `owner/repo` | Full APM package |
| `owner/repo/path/to/primitive` | Individual primitive (skill, instruction, plugin, etc.) from a repository |
| `owner/repo#ref` | Package pinned to a tag, branch, or commit SHA |
### Examples
[Section titled “Examples”](#examples)
```aw
imports:
- uses: shared/apm.md
with:
packages:
# Full APM package
- microsoft/apm-sample-package
# Individual primitive from any repository
- github/awesome-copilot/skills/review-and-refactor
# Plugin (Claude plugin.json format)
- github/awesome-copilot/plugins/context-engineering
# Version-pinned to a tag
- microsoft/apm-sample-package#v2.0
# Version-pinned to a branch
- microsoft/apm-sample-package#main
```
## How it works
[Section titled “How it works”](#how-it-works)
The `shared/apm.md` import adds a dedicated `apm` job to the compiled workflow. This job runs `microsoft/apm-action` to install packages and create a bundle archive, which is uploaded as a GitHub Actions artifact. The agent job downloads and restores the bundle as pre-steps, making all skills and tools available at runtime.
Packages are fetched using the cascading token fallback: `GH_AW_PLUGINS_TOKEN` → `GH_AW_GITHUB_TOKEN` → `GITHUB_TOKEN`.
To reproduce or debug the pack/unpack flow locally, run `apm pack` and `apm unpack` directly. See the [pack and distribute guide](https://microsoft.github.io/apm/guides/pack-distribute/) for instructions.
## Reference
[Section titled “Reference”](#reference)
| Resource | URL |
| ---------------------------- | --------------------------------------------------------- |
| APM documentation | |
| APM governance guide | |
| Pack and distribute guide | |
| gh-aw integration (APM docs) | |
| apm-action (GitHub) | |
| microsoft/apm (GitHub) | |
# Workflow Editors
> A curated list of editors for authoring and previewing agentic workflows.
The following editors can be used to author, compile, and preview agentic workflows. Some are built-in tools maintained alongside gh-aw; others are community-created projects.
### Compiler Playground
[Section titled “Compiler Playground”](#compiler-playground)
An **experimental** interactive browser-based playground that runs the gh-aw compiler entirely in the browser using [WebAssembly](/gh-aw/reference/wasm-compilation/). It demonstrates how to use the WASM build of the compiler directly in a webpage and shows how to compile workflows in the browser using the WASM-based execution engine.
*
## Community editors
[Section titled “Community editors”](#community-editors)
Note
Community editors are created and maintained by independent contributors. They are not officially supported by the gh-aw project.
### Agentic Prompt Generator
[Section titled “Agentic Prompt Generator”](#agentic-prompt-generator)
A web-based tool for generating and editing agentic workflow prompts. It provides an interactive interface to help author workflow prompts for agentic workflows.
*
### Graphical Workflow Editor
[Section titled “Graphical Workflow Editor”](#graphical-workflow-editor)
A visual, graphical workflow editor that provides a richer UI for editing agentic workflows. Rather than working directly with markdown and YAML, this editor focuses on a more interactive and visual editing experience.
*
# Effective Tokens Specification
> Formal specification defining Effective Tokens (ET), a normalized metric for measuring LLM token usage across token classes, model multipliers, and multi-agent execution graphs
# Effective Tokens Specification
[Section titled “Effective Tokens Specification”](#effective-tokens-specification)
**Version**: 0.2.0 **Status**: Draft **Publication Date**: 2026-04-02 **Editor**: GitHub Agentic Workflows Team **This Version**: [effective-tokens-specification](/gh-aw/reference/effective-tokens-specification/) **Latest Published Version**: This document
***
## Abstract
[Section titled “Abstract”](#abstract)
This specification defines **Effective Tokens (ET)**, a normalized unit for measuring Large Language Model (LLM) usage across token classes, model-relative computational intensity, and multi-invocation execution graphs. ET provides a single unified metric for composite LLM workloads including multi-step pipelines, tool-augmented calls, sub-agent orchestration, and recursive inference.
## Status of This Document
[Section titled “Status of This Document”](#status-of-this-document)
This section describes the status of this document at the time of publication. This is a draft specification and may be updated, replaced, or made obsolete by other documents at any time.
This document is governed by the GitHub Agentic Workflows project specifications process.
## Table of Contents
[Section titled “Table of Contents”](#table-of-contents)
1. [Introduction](#1-introduction)
2. [Conformance](#2-conformance)
3. [Terminology](#3-terminology)
4. [Token Accounting Model](#4-token-accounting-model)
5. [Multi-Invocation Aggregation](#5-multi-invocation-aggregation)
6. [Execution Graph Requirements](#6-execution-graph-requirements)
7. [Reporting](#7-reporting)
8. [Implementation Requirements](#8-implementation-requirements)
9. [Extensibility](#9-extensibility)
10. [Compliance Testing](#10-compliance-testing)
11. [Appendices](#appendices)
12. [References](#references)
13. [Change Log](#change-log)
***
## 1. Introduction
[Section titled “1. Introduction”](#1-introduction)
### 1.1 Purpose
[Section titled “1.1 Purpose”](#11-purpose)
Token counts reported by LLM APIs are not directly comparable: different token classes (input, cached, output, reasoning) carry different computational costs, and different models have different relative costs. Effective Tokens normalizes these variables into a single scalar that reflects true computational intensity, enabling consistent measurement and comparison across complex multi-agent systems.
### 1.2 Scope
[Section titled “1.2 Scope”](#12-scope)
This specification covers:
* Definition of token classes and their default weights
* The per-invocation ET computation formula
* Aggregation across multi-invocation execution graphs
* Structural requirements for invocation nodes and summary reports
This specification does NOT cover:
* Billing, pricing, or cost allocation
* Model selection or routing strategies
* Streaming or partial token reporting
### 1.3 Design Goals
[Section titled “1.3 Design Goals”](#13-design-goals)
An ET implementation:
1. Preserves raw token counts per invocation
2. Normalizes across token classes using disclosed weights
3. Normalizes across models using per-model multipliers
4. Supports aggregation across any number of invocations
5. Produces a single reproducible metric from identical inputs
6. Carries no dependency on billing or pricing systems
***
## 2. Conformance
[Section titled “2. Conformance”](#2-conformance)
### 2.1 Conformance Classes
[Section titled “2.1 Conformance Classes”](#21-conformance-classes)
**Conforming implementation**: An implementation that satisfies all MUST/SHALL requirements in this specification.
**Partially conforming implementation**: An implementation that satisfies core accounting requirements (Sections 4–5) but omits optional fields or extensions.
### 2.2 Requirements Notation
[Section titled “2.2 Requirements Notation”](#22-requirements-notation)
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
### 2.3 Compliance Levels
[Section titled “2.3 Compliance Levels”](#23-compliance-levels)
* **Level 1 – Basic**: Single-invocation ET computation (Section 4)
* **Level 2 – Standard**: Multi-invocation aggregation and execution graph (Sections 5–6)
* **Level 3 – Complete**: Full reporting and extensibility support (Sections 7–9)
***
## 3. Terminology
[Section titled “3. Terminology”](#3-terminology)
### 3.1 Token Classes
[Section titled “3.1 Token Classes”](#31-token-classes)
| Class | Symbol | Description |
| ------------------- | ------ | ------------------------------------------------ |
| Input Tokens | I | Tokens newly processed by the model |
| Cached Input Tokens | C | Tokens served via cache or prefix reuse |
| Output Tokens | O | Tokens generated by the model |
| Reasoning Tokens | R | Internal tokens used during inference (optional) |
### 3.2 Model Multiplier
[Section titled “3.2 Model Multiplier”](#32-model-multiplier)
The **Copilot Multiplier** (`m`) is a scalar representing the relative computational intensity of a model versus a defined baseline. Its value is model-specific and MUST be disclosed by the implementation.
### 3.3 Invocation
[Section titled “3.3 Invocation”](#33-invocation)
A single LLM request-response cycle. Each invocation produces one set of token counts and yields one ET value.
### 3.4 Sub-Agent
[Section titled “3.4 Sub-Agent”](#34-sub-agent)
Any invocation triggered by another LLM call or orchestration layer. Examples include tool-using agents, retrieval-augmented calls, planning/execution agents, and recursively delegated LLM calls.
### 3.5 Execution Graph
[Section titled “3.5 Execution Graph”](#35-execution-graph)
A directed structure representing all invocations associated with a single top-level request. The root node has no parent; sub-agents reference their triggering invocation as their parent.
***
## 4. Token Accounting Model
[Section titled “4. Token Accounting Model”](#4-token-accounting-model)
### 4.1 Raw Token Count
[Section titled “4.1 Raw Token Count”](#41-raw-token-count)
For each invocation, the raw total is:
```plaintext
raw_total_tokens = I + C + O + R
```
### 4.2 Token Class Weights
[Section titled “4.2 Token Class Weights”](#42-token-class-weights)
Default weights for the four token classes are:
| Token Class | Symbol | Default Weight |
| ------------ | --------- | -------------- |
| Input | w\_in | 1.0 |
| Cached Input | w\_cache | 0.1 |
| Output | w\_out | 4.0 |
| Reasoning | w\_reason | 4.0 |
Implementations MAY override these values but MUST disclose the weights used in any reported output.
### 4.3 Base Weighted Tokens
[Section titled “4.3 Base Weighted Tokens”](#43-base-weighted-tokens)
Per invocation:
```plaintext
base_weighted_tokens =
(w_in × I) + (w_cache × C) + (w_out × O) + (w_reason × R)
```
### 4.4 Effective Tokens Per Invocation
[Section titled “4.4 Effective Tokens Per Invocation”](#44-effective-tokens-per-invocation)
```plaintext
effective_tokens = m × base_weighted_tokens
```
***
## 5. Multi-Invocation Aggregation
[Section titled “5. Multi-Invocation Aggregation”](#5-multi-invocation-aggregation)
### 5.1 Total Effective Tokens
[Section titled “5.1 Total Effective Tokens”](#51-total-effective-tokens)
For a request involving N invocations:
```plaintext
ET_total = Σ (m_i × base_weighted_tokens_i)
```
Each invocation MAY use a different model and multiplier.
### 5.2 Total Raw Tokens
[Section titled “5.2 Total Raw Tokens”](#52-total-raw-tokens)
```plaintext
raw_total_tokens = Σ (I_i + C_i + O_i + R_i)
```
### 5.3 Invocation Count
[Section titled “5.3 Invocation Count”](#53-invocation-count)
```plaintext
total_invocations = N
```
This count MUST include the root call, all sub-agent calls, and all tool-triggered LLM calls.
***
## 6. Execution Graph Requirements
[Section titled “6. Execution Graph Requirements”](#6-execution-graph-requirements)
Implementations MUST represent multi-call workflows as a directed execution graph.
### 6.1 Node Schema
[Section titled “6.1 Node Schema”](#61-node-schema)
Each node (invocation) MUST conform to:
```json
{
"id": "string",
"parent_id": "string | null",
"model": {
"name": "string",
"copilot_multiplier": number
},
"usage": {
"input_tokens": number,
"cached_input_tokens": number,
"output_tokens": number,
"reasoning_tokens": number
},
"derived": {
"base_weighted_tokens": number,
"effective_tokens": number
}
}
```
### 6.2 Root Invocation
[Section titled “6.2 Root Invocation”](#62-root-invocation)
The root invocation MUST have `parent_id = null`. It represents the user-facing request that initiates the execution graph.
### 6.3 Sub-Agent Invocations
[Section titled “6.3 Sub-Agent Invocations”](#63-sub-agent-invocations)
Each sub-agent invocation MUST reference a valid `parent_id`. Sub-agent invocations MAY recursively spawn further invocations.
***
## 7. Reporting
[Section titled “7. Reporting”](#7-reporting)
A conforming response MUST include a `summary` object alongside the `invocations` array:
```json
{
"summary": {
"total_invocations": number,
"raw_total_tokens": number,
"base_weighted_tokens": number,
"effective_tokens": number
},
"invocations": [ ... ]
}
```
***
## 8. Implementation Requirements
[Section titled “8. Implementation Requirements”](#8-implementation-requirements)
### 8.1 Completeness
[Section titled “8.1 Completeness”](#81-completeness)
All LLM calls MUST be included in the execution graph. Hidden or system-triggered calls MUST be counted.
### 8.2 Determinism
[Section titled “8.2 Determinism”](#82-determinism)
Given identical inputs and multipliers, ET MUST be reproducible. Implementations SHOULD NOT introduce non-deterministic factors into the computation.
### 8.3 Versioning
[Section titled “8.3 Versioning”](#83-versioning)
Implementations SHOULD version their token weights and model multipliers so that historical reports remain interpretable.
### 8.4 Partial Visibility
[Section titled “8.4 Partial Visibility”](#84-partial-visibility)
When sub-agents are not fully observable, implementations MUST still report aggregate totals. Invocation nodes with incomplete data SHOULD be flagged to indicate missing information.
***
## 9. Extensibility
[Section titled “9. Extensibility”](#9-extensibility)
Implementations MAY:
* Add new token classes (e.g., `tool_tokens`)
* Add latency or compute metadata per invocation node
* Support streaming or partial progress updates
Extensions MUST NOT alter the core ET definition or the default weight values without disclosure.
***
## 10. Compliance Testing
[Section titled “10. Compliance Testing”](#10-compliance-testing)
### 10.1 Test Suite Requirements
[Section titled “10.1 Test Suite Requirements”](#101-test-suite-requirements)
#### 10.1.1 Token Accounting Tests
[Section titled “10.1.1 Token Accounting Tests”](#1011-token-accounting-tests)
* **T-ET-001**: Single invocation with all four token classes produces correct `base_weighted_tokens`
* **T-ET-002**: Single invocation ET equals `m × base_weighted_tokens`
* **T-ET-003**: Zero-value token classes do not affect the result
* **T-ET-004**: Custom weights are applied when default weights are overridden
#### 10.1.2 Aggregation Tests
[Section titled “10.1.2 Aggregation Tests”](#1012-aggregation-tests)
* **T-ET-010**: Multi-invocation `ET_total` equals the sum of per-invocation ET values
* **T-ET-011**: `raw_total_tokens` equals the sum of all raw tokens across all invocations
* **T-ET-012**: `total_invocations` count includes root, sub-agents, and tool-triggered calls
#### 10.1.3 Execution Graph Tests
[Section titled “10.1.3 Execution Graph Tests”](#1013-execution-graph-tests)
* **T-ET-020**: Root node has `parent_id = null`
* **T-ET-021**: All sub-agent nodes reference a valid `parent_id`
* **T-ET-022**: Node schema includes all required fields
#### 10.1.4 Reporting Tests
[Section titled “10.1.4 Reporting Tests”](#1014-reporting-tests)
* **T-ET-030**: Summary object is present in all conforming responses
* **T-ET-031**: Summary values are consistent with per-invocation data
### 10.2 Compliance Checklist
[Section titled “10.2 Compliance Checklist”](#102-compliance-checklist)
| Requirement | Test ID | Level | Status |
| ----------------------------------- | ------------ | ----- | ----------- |
| Per-invocation base weighted tokens | T-ET-001–004 | 1 | Required |
| Per-invocation ET computation | T-ET-002 | 1 | Required |
| Multi-invocation aggregation | T-ET-010–012 | 2 | Required |
| Execution graph node schema | T-ET-020–022 | 2 | Required |
| Summary reporting | T-ET-030–031 | 3 | Required |
| Custom weight disclosure | T-ET-004 | 1 | Required |
| Versioning of weights/multipliers | — | 3 | Recommended |
| Partial visibility flagging | — | 2 | Recommended |
***
## Appendices
[Section titled “Appendices”](#appendices)
### Appendix A: Worked Example
[Section titled “Appendix A: Worked Example”](#appendix-a-worked-example)
#### A.1 Scenario
[Section titled “A.1 Scenario”](#a1-scenario)
A request triggers three invocations: a root call, a retrieval sub-agent, and a final synthesis call.
#### A.2 Input Data
[Section titled “A.2 Input Data”](#a2-input-data)
```json
{
"invocations": [
{
"id": "root",
"parent_id": null,
"model": { "name": "model-a", "copilot_multiplier": 2.0 },
"usage": {
"input_tokens": 500,
"cached_input_tokens": 200,
"output_tokens": 150,
"reasoning_tokens": 0
}
},
{
"id": "retrieval",
"parent_id": "root",
"model": { "name": "model-b", "copilot_multiplier": 1.0 },
"usage": {
"input_tokens": 300,
"cached_input_tokens": 0,
"output_tokens": 100,
"reasoning_tokens": 0
}
},
{
"id": "synthesis",
"parent_id": "root",
"model": { "name": "model-a", "copilot_multiplier": 2.0 },
"usage": {
"input_tokens": 200,
"cached_input_tokens": 100,
"output_tokens": 250,
"reasoning_tokens": 0
}
}
]
}
```
#### A.3 Computation
[Section titled “A.3 Computation”](#a3-computation)
```plaintext
root:
base = (1.0 × 500) + (0.1 × 200) + (4.0 × 150) = 500 + 20 + 600 = 1120
ET = 2.0 × 1120 = 2240
retrieval:
base = (1.0 × 300) + (4.0 × 100) = 300 + 400 = 700
ET = 1.0 × 700 = 700
synthesis:
base = (1.0 × 200) + (0.1 × 100) + (4.0 × 250) = 200 + 10 + 1000 = 1210
ET = 2.0 × 1210 = 2420
```
#### A.4 Output
[Section titled “A.4 Output”](#a4-output)
```json
{
"summary": {
"total_invocations": 3,
"raw_total_tokens": 1800,
"base_weighted_tokens": 3030,
"effective_tokens": 5360
}
}
```
### Appendix B: Core Formula Reference
[Section titled “Appendix B: Core Formula Reference”](#appendix-b-core-formula-reference)
```plaintext
ET_total = Σ [ m_i × (w_in × I_i + w_cache × C_i + w_out × O_i + w_reason × R_i) ]
```
With default weights:
```plaintext
ET_total = Σ [ m_i × (I_i + 0.1 C_i + 4 O_i + 4 R_i) ]
```
### Appendix C: Security Considerations
[Section titled “Appendix C: Security Considerations”](#appendix-c-security-considerations)
ET values are derived from token usage metadata. Implementations SHOULD treat per-invocation token data as potentially sensitive since usage patterns may reveal information about system prompts, model configurations, or user behavior. Aggregate ET values suitable for observability dashboards SHOULD be separated from detailed per-invocation data in access-controlled reporting systems.
***
## References
[Section titled “References”](#references)
### Normative References
[Section titled “Normative References”](#normative-references)
* **\[RFC 2119]** Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
### Informative References
[Section titled “Informative References”](#informative-references)
* **\[OPENAI-USAGE]** OpenAI API Reference — Usage Objects.
* **\[ANTHROPIC-USAGE]** Anthropic API Reference — Token Usage.
***
## Change Log
[Section titled “Change Log”](#change-log)
### Version 0.2.0 (Draft)
[Section titled “Version 0.2.0 (Draft)”](#version-020-draft)
* Adopted W3C-style specification format
* Added conformance levels (Basic, Standard, Complete)
* Added compliance testing section with test IDs
* Added Appendix C: Security Considerations
* Clarified partial visibility requirements
### Version 0.1.0 (Draft)
[Section titled “Version 0.1.0 (Draft)”](#version-010-draft)
* Initial definition of Effective Tokens metric
* Defined four token classes and default weights
* Defined per-invocation and multi-invocation formulas
* Defined execution graph node schema
***
*Copyright 2026 GitHub Agentic Workflows Team. All rights reserved.*
# AI Engines (aka Coding Agents)
> Complete guide to AI engines (coding agents) usable with GitHub Agentic Workflows, including Copilot, Claude, Codex, and Gemini with their specific configuration options.
GitHub Agentic Workflows use [AI Engines](/gh-aw/reference/glossary/#engine) (normally a coding agent) to interpret and execute natural language instructions.
## Available Coding Agents
[Section titled “Available Coding Agents”](#available-coding-agents)
Set `engine:` in your workflow frontmatter and configure the corresponding secret:
| Engine | `engine:` value | Required Secret |
| ------------------------------------------------------------------------------------------------------------- | --------------- | --------------------------------------------------------------------- |
| [GitHub Copilot CLI](https://docs.github.com/en/copilot/how-tos/use-copilot-agents/use-copilot-cli) (default) | `copilot` | [COPILOT\_GITHUB\_TOKEN](/gh-aw/reference/auth/#copilot_github_token) |
| [Claude by Anthropic (Claude Code)](https://www.anthropic.com/index/claude) | `claude` | [ANTHROPIC\_API\_KEY](/gh-aw/reference/auth/#anthropic_api_key) |
| [OpenAI Codex](https://openai.com/blog/openai-codex) | `codex` | [OPENAI\_API\_KEY](/gh-aw/reference/auth/#openai_api_key) |
| [Google Gemini CLI](https://github.com/google-gemini/gemini-cli) | `gemini` | [GEMINI\_API\_KEY](/gh-aw/reference/auth/#gemini_api_key) |
Copilot CLI is the default — `engine:` can be omitted when using Copilot. See the linked authentication docs for secret setup instructions.
## Engine Feature Comparison
[Section titled “Engine Feature Comparison”](#engine-feature-comparison)
Not all features are available across all engines. The table below summarizes per-engine support for commonly used workflow options:
| Feature | Copilot | Claude | Codex | Gemini |
| ------------------------------------- | :-----: | :-----: | :--------: | :-----: |
| `max-turns` | ✗ | ✓ | ✗ | ✗ |
| `max-continuations` | ✓ | ✗ | ✗ | ✗ |
| `tools.web-fetch` | ✓ | ✓ | ✓ | ✓ |
| `tools.web-search` | via MCP | via MCP | ✓ (opt-in) | via MCP |
| `engine.agent` (custom agent file) | ✓ | ✗ | ✗ | ✗ |
| `engine.api-target` (custom endpoint) | ✓ | ✓ | ✓ | ✓ |
| Tools allowlist | ✓ | ✓ | ✓ | ✓ |
**Notes:**
* `max-turns` limits the number of AI chat iterations per run (Claude only).
* `max-continuations` enables autopilot mode with multiple consecutive runs (Copilot only).
* `web-search` for Codex is disabled by default; add `tools: web-search:` to enable it. Other engines use a third-party MCP server — see [Using Web Search](/gh-aw/guides/web-search/).
* `engine.agent` references a `.github/agents/` file for custom Copilot agent behavior. See [Copilot Custom Configuration](#copilot-custom-configuration).
## Extended Coding Agent Configuration
[Section titled “Extended Coding Agent Configuration”](#extended-coding-agent-configuration)
Workflows can specify extended configuration for the coding agent:
```yaml
engine:
id: copilot
version: latest # defaults to latest
model: gpt-5 # example override; omit to use engine default
command: /usr/local/bin/copilot # custom executable path
args: ["--add-dir", "/workspace"] # custom CLI arguments
agent: agent-id # custom agent file identifier
api-target: api.acme.ghe.com # custom API endpoint hostname (GHEC/GHES)
```
### Pinning a Specific Engine Version
[Section titled “Pinning a Specific Engine Version”](#pinning-a-specific-engine-version)
By default, workflows install the latest available version of each engine CLI. To pin to a specific version, set `version` to the desired release:
| Engine | `id` | Example `version` |
| ------------------ | --------- | ----------------- |
| GitHub Copilot CLI | `copilot` | `"0.0.422"` |
| Claude Code | `claude` | `"2.1.70"` |
| Codex | `codex` | `"0.111.0"` |
| Gemini CLI | `gemini` | `"0.31.0"` |
```yaml
engine:
id: copilot
version: "0.0.422"
```
Pinning is useful when you need reproducible builds or want to avoid breakage from a new CLI release while testing. Remember to update the pinned version periodically to pick up bug fixes and new features.
`version` also accepts a GitHub Actions expression string, enabling `workflow_call` reusable workflows to parameterize the engine version via caller inputs. Expressions are passed injection-safely through an environment variable rather than direct shell interpolation:
```yaml
on:
workflow_call:
inputs:
engine-version:
type: string
default: latest
---
engine:
id: copilot
version: ${{ inputs.engine-version }}
```
### Copilot Custom Configuration
[Section titled “Copilot Custom Configuration”](#copilot-custom-configuration)
Use `agent` to reference a custom agent file in `.github/agents/` (omit the `.agent.md` extension):
```yaml
engine:
id: copilot
agent: technical-doc-writer # .github/agents/technical-doc-writer.agent.md
```
See [Copilot Agent Files](/gh-aw/reference/copilot-custom-agents/) for details.
### Engine Environment Variables
[Section titled “Engine Environment Variables”](#engine-environment-variables)
All engines support custom environment variables through the `env` field:
```yaml
engine:
id: copilot
env:
DEBUG_MODE: "true"
AWS_REGION: us-west-2
CUSTOM_API_ENDPOINT: https://api.example.com
```
Environment variables can also be defined at workflow, job, step, and other scopes. See [Environment Variables](/gh-aw/reference/environment-variables/) for complete documentation on precedence and all 13 env scopes.
### Enterprise API Endpoint (`api-target`)
[Section titled “Enterprise API Endpoint (api-target)”](#enterprise-api-endpoint-api-target)
The `api-target` field specifies a custom API endpoint hostname for the agentic engine. Use this when running workflows against GitHub Enterprise Cloud (GHEC), GitHub Enterprise Server (GHES), or any custom AI endpoint.
For a complete setup and debugging walkthrough for GHE Cloud with data residency, see [Debugging GHE Cloud with Data Residency](/gh-aw/troubleshooting/debug-ghe/).
The value must be a hostname only — no protocol or path (e.g., `api.acme.ghe.com`, not `https://api.acme.ghe.com/v1`). The field works with any engine.
**GHEC example** — specify your tenant-specific Copilot endpoint:
```yaml
engine:
id: copilot
api-target: api.acme.ghe.com
network:
allowed:
- defaults
- acme.ghe.com
- api.acme.ghe.com
```
**GHES example** — use the enterprise Copilot endpoint:
```yaml
engine:
id: copilot
api-target: api.enterprise.githubcopilot.com
network:
allowed:
- defaults
- github.company.com
- api.enterprise.githubcopilot.com
```
The specified hostname must also be listed in `network.allowed` for the firewall to permit outbound requests.
#### Custom API Endpoints via Environment Variables
[Section titled “Custom API Endpoints via Environment Variables”](#custom-api-endpoints-via-environment-variables)
Three environment variables receive special treatment when set in `engine.env`: `OPENAI_BASE_URL` (for `codex`), `ANTHROPIC_BASE_URL` (for `claude`), and `GITHUB_COPILOT_BASE_URL` (for `copilot`). When any of these is present, the API proxy automatically routes API calls to the specified host instead of the default endpoint. Firewall enforcement remains active, but this routing layer is not a separate authentication boundary for arbitrary code already running inside the agent container.
This enables workflows to use internal LLM routers, Azure OpenAI deployments, corporate Copilot proxies, or other compatible endpoints without bypassing AWF’s security model.
```yaml
engine:
id: codex
model: gpt-4o
env:
OPENAI_BASE_URL: "https://llm-router.internal.example.com/v1"
OPENAI_API_KEY: ${{ secrets.LLM_ROUTER_KEY }}
network:
allowed:
- github.com
- llm-router.internal.example.com # must be listed here for the firewall to permit outbound requests
```
For Claude workflows routed through a custom Anthropic-compatible endpoint:
```yaml
engine:
id: claude
env:
ANTHROPIC_BASE_URL: "https://anthropic-proxy.internal.example.com"
ANTHROPIC_API_KEY: ${{ secrets.PROXY_API_KEY }}
network:
allowed:
- github.com
- anthropic-proxy.internal.example.com
```
For Copilot workflows routed through a custom Copilot-compatible endpoint (e.g., a corporate proxy or a GHE Cloud data residency instance):
```yaml
engine:
id: copilot
env:
GITHUB_COPILOT_BASE_URL: "https://copilot-proxy.corp.example.com"
network:
allowed:
- github.com
- copilot-proxy.corp.example.com
```
`GITHUB_COPILOT_BASE_URL` is used as a fallback when `engine.api-target` is not explicitly set. If both are configured, `engine.api-target` takes precedence.
The custom hostname is extracted from the URL and passed to the AWF `--openai-api-target`, `--anthropic-api-target`, or `--copilot-api-target` flag automatically at compile time. No additional configuration is required.
### Engine Command-Line Arguments
[Section titled “Engine Command-Line Arguments”](#engine-command-line-arguments)
All engines support custom command-line arguments through the `args` field, injected before the prompt:
```yaml
engine:
id: copilot
args: ["--add-dir", "/workspace", "--verbose"]
```
Arguments are added in order and placed before the `--prompt` flag. Consult the specific engine’s CLI documentation for available flags.
### Custom Engine Command
[Section titled “Custom Engine Command”](#custom-engine-command)
Override the default engine executable using the `command` field. Useful for testing pre-release versions, custom builds, or non-standard installations. Installation steps are automatically skipped.
```yaml
engine:
id: copilot
command: /usr/local/bin/copilot-dev # absolute path
args: ["--verbose"]
```
### Custom Token Weights (`token-weights`)
[Section titled “Custom Token Weights (token-weights)”](#custom-token-weights-token-weights)
Override the built-in token cost multipliers used when computing [Effective Tokens](/gh-aw/reference/effective-tokens-specification/). Useful when your workflow uses a custom model not in the built-in list, or when you want to adjust the relative cost ratios for your use case.
```yaml
engine:
id: claude
token-weights:
multipliers:
my-custom-model: 2.5 # 2.5x the cost of claude-sonnet-4.5
experimental-llm: 0.8 # Override an existing model's multiplier
token-class-weights:
output: 6.0 # Override output token weight (default: 4.0)
cached-input: 0.05 # Override cached input weight (default: 0.1)
```
`multipliers` is a map of model names to numeric multipliers relative to `claude-sonnet-4.5` (= 1.0). Keys are case-insensitive and support prefix matching. `token-class-weights` overrides the per-class weights applied before the model multiplier; the defaults are `input: 1.0`, `cached-input: 0.1`, `output: 4.0`, `reasoning: 4.0`, `cache-write: 1.0`.
Custom weights are embedded in the compiled workflow YAML and read by `gh aw logs` and `gh aw audit` when analyzing runs.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Frontmatter](/gh-aw/reference/frontmatter/) - Complete configuration reference
* [Tools](/gh-aw/reference/tools/) - Available tools and MCP servers
* [Security Guide](/gh-aw/introduction/architecture/) - Security considerations for AI engines
* [MCPs](/gh-aw/guides/mcps/) - Model Context Protocol setup and configuration
# Environment Variables
> Reference for all environment variables in GitHub Agentic Workflows — CLI configuration, model overrides, guard policy fallbacks, and workflow-level scope precedence
Environment variables in GitHub Agentic Workflows can be defined at multiple scopes, each serving a specific purpose in the workflow lifecycle. Variables defined at more specific scopes override those at more general scopes, following GitHub Actions conventions while adding AWF-specific contexts.
## Environment Variable Scopes
[Section titled “Environment Variable Scopes”](#environment-variable-scopes)
GitHub Agentic Workflows supports environment variables in 13 distinct contexts:
| Scope | Syntax | Context | Typical Use |
| ----------------------- | ------------------------------ | ------------------------------------ | ------------------------- |
| **Workflow-level** | `env:` | All jobs | Shared configuration |
| **Job-level** | `jobs..env` | All steps in job | Job-specific config |
| **Step-level** | `steps[*].env` | Single step | Step-specific config |
| **Engine** | `engine.env` | AI engine | Engine secrets, timeouts |
| **Container** | `container.env` | Container runtime | Container settings |
| **Services** | `services..env` | Service containers | Database credentials |
| **Sandbox Agent** | `sandbox.agent.env` | Sandbox runtime | Sandbox configuration |
| **Sandbox MCP** | `sandbox.mcp.env` | Model Context Protocol (MCP) gateway | MCP debugging |
| **MCP Tools** | `tools..env` | MCP server process | MCP server secrets |
| **MCP Scripts** | `mcp-scripts..env` | MCP script execution | Tool-specific tokens |
| **Safe Outputs Global** | `safe-outputs.env` | All safe-output jobs | Shared safe-output config |
| **Safe Outputs Job** | `safe-outputs.jobs..env` | Specific safe-output job | Job-specific config |
| **GitHub Actions Step** | `githubActionsStep.env` | Pre-defined steps | Step configuration |
### Example Configurations
[Section titled “Example Configurations”](#example-configurations)
**Workflow-level shared configuration:**
```yaml
---
env:
NODE_ENV: production
API_ENDPOINT: https://api.example.com
---
```
**Job-specific overrides:**
```yaml
---
jobs:
validation:
env:
VALIDATION_MODE: strict
steps:
- run: npm run build
env:
BUILD_ENV: production # Overrides job and workflow levels
---
```
**AWF-specific contexts:**
```yaml
---
# Engine configuration
engine:
id: copilot
env:
OPENAI_API_KEY: ${{ secrets.CUSTOM_KEY }}
# MCP server with secrets
tools:
database:
command: npx
args: ["-y", "mcp-server-postgres"]
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
# Safe outputs with custom PAT
safe-outputs:
create-issue:
env:
GITHUB_TOKEN: ${{ secrets.CUSTOM_PAT }}
---
```
## Agent Step Summary (`GITHUB_STEP_SUMMARY`)
[Section titled “Agent Step Summary (GITHUB\_STEP\_SUMMARY)”](#agent-step-summary-github_step_summary)
Agents can write markdown content to the `$GITHUB_STEP_SUMMARY` environment variable to publish a formatted summary visible in the GitHub Actions run view.
Inside the AWF sandbox, `$GITHUB_STEP_SUMMARY` is redirected to a file at `/tmp/gh-aw/agent-step-summary.md`. After agent execution completes, the framework automatically appends the contents of that file to the real GitHub step summary. Secret redaction runs before the content is published.
Note
The first 2000 characters of the summary are appended. If the content is longer, a `[truncated: ...]` notice is included. Write your most important content first.
Example: an agent writing a brief analysis result to the step summary:
```bash
echo "## Analysis complete" >> "$GITHUB_STEP_SUMMARY"
echo "Found 3 issues across 12 files." >> "$GITHUB_STEP_SUMMARY"
```
The output appears in the **Summary** tab of the GitHub Actions workflow run.
## System-Injected Runtime Variables
[Section titled “System-Injected Runtime Variables”](#system-injected-runtime-variables)
GitHub Agentic Workflows automatically injects the following environment variables into every agentic engine execution step (both the main agent run and the threat detection run). These variables are read-only from the agent’s perspective and are useful for writing workflows or agents that need to detect their execution context.
| Variable | Value | Description |
| --------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GITHUB_AW` | `"true"` | Present in every gh-aw engine execution step. Agents can check for this variable to confirm they are running inside a GitHub Agentic Workflow. |
| `GH_AW_PHASE` | `"agent"` or `"detection"` | Identifies which execution phase is active. `"agent"` for the main run; `"detection"` for the threat-detection safety check run that precedes the main run. |
| `GH_AW_VERSION` | e.g. `"0.40.1"` | The gh-aw compiler version that generated the workflow. Useful for conditional logic that depends on a minimum feature version. |
These variables appear alongside other `GH_AW_*` context variables in the compiled workflow:
```yaml
env:
GITHUB_AW: "true"
GH_AW_PHASE: agent # or "detection"
GH_AW_VERSION: "0.40.1"
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
```
Note
These variables are injected by the compiler and cannot be overridden by user-defined `env:` blocks in the workflow frontmatter.
## CLI Configuration Variables
[Section titled “CLI Configuration Variables”](#cli-configuration-variables)
These variables configure the `gh aw` CLI tool. Set them in your local shell environment or as repository/organization variables in GitHub Actions.
| Variable | Default | Description |
| -------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEBUG` | disabled | npm-style namespace debug logging. `DEBUG=*` enables all output; `DEBUG=cli:*,workflow:*` selects specific namespaces. Exclusions are supported: `DEBUG=*,-workflow:test`. Also activated when `ACTIONS_RUNNER_DEBUG=true`. |
| `DEBUG_COLORS` | `1` (enabled) | Set to `0` to disable ANSI colors in debug output. Colors are automatically disabled when output is not a TTY. |
| `ACCESSIBLE` | empty | Any non-empty value enables accessibility mode, which disables spinners and animations. Also enabled when `TERM=dumb` or `NO_COLOR` is set. |
| `NO_COLOR` | empty | Any non-empty value disables colored output and enables accessibility mode. Follows the [no-color.org](https://no-color.org/) standard. |
| `GH_AW_ACTION_MODE` | auto-detected | Overrides how JavaScript is embedded in compiled workflows. Valid values: `dev`, `release`, `script`, `action`. When unset, the CLI auto-detects the appropriate mode. |
| `GH_AW_FEATURES` | empty | Comma-separated list of experimental feature flags to enable globally. Values in workflow `features:` frontmatter take precedence over this variable. |
| `GH_AW_MAX_CONCURRENT_DOWNLOADS` | `10` | Maximum number of parallel log and artifact downloads for `gh aw logs`. Valid range: `1`–`100`. |
| `GH_AW_MCP_SERVER` | unset | When set, disables the automatic update check. Set automatically when `gh aw` runs as an MCP server subprocess — no manual configuration needed. |
**Enabling debug logging:**
```bash
# All namespaces
DEBUG=* gh aw compile
# Specific namespaces
DEBUG=cli:*,workflow:* gh aw compile
# Without colors
DEBUG_COLORS=0 DEBUG=* gh aw compile
```
***
## Model Override Variables
[Section titled “Model Override Variables”](#model-override-variables)
These variables override the default AI model used for agent runs and threat detection. Set them as GitHub Actions repository or organization variables to apply org-wide defaults without modifying workflow frontmatter.
Note
The `engine.model:` field in workflow frontmatter takes precedence over these variables.
### Agent runs
[Section titled “Agent runs”](#agent-runs)
| Variable | Engine |
| --------------------------- | ---------------- |
| `GH_AW_MODEL_AGENT_COPILOT` | GitHub Copilot |
| `GH_AW_MODEL_AGENT_CLAUDE` | Anthropic Claude |
| `GH_AW_MODEL_AGENT_CODEX` | OpenAI Codex |
| `GH_AW_MODEL_AGENT_GEMINI` | Google Gemini |
| `GH_AW_MODEL_AGENT_CUSTOM` | Custom engine |
### Detection runs
[Section titled “Detection runs”](#detection-runs)
| Variable | Engine |
| ------------------------------- | ---------------- |
| `GH_AW_MODEL_DETECTION_COPILOT` | GitHub Copilot |
| `GH_AW_MODEL_DETECTION_CLAUDE` | Anthropic Claude |
| `GH_AW_MODEL_DETECTION_CODEX` | OpenAI Codex |
| `GH_AW_MODEL_DETECTION_GEMINI` | Google Gemini |
Set a model override as an organization variable:
```bash
gh variable set GH_AW_MODEL_AGENT_COPILOT --org my-org --body "gpt-5"
```
See [Engines](/gh-aw/reference/engines/) for available engine identifiers and model configuration options.
***
## Guard Policy Fallback Variables
[Section titled “Guard Policy Fallback Variables”](#guard-policy-fallback-variables)
These variables provide fallback values for guard policy fields when the corresponding `tools.github.*` configuration is absent from workflow frontmatter. Set them as GitHub Actions organization or repository variables to enforce a consistent policy across all workflows.
Note
Explicit `tools.github.*` values in workflow frontmatter always take precedence over these variables.
| Variable | Frontmatter field | Format | Description |
| ------------------------------ | ------------------------------ | --------------------------------------- | ------------------------------------------------------------------------- |
| `GH_AW_GITHUB_BLOCKED_USERS` | `tools.github.blocked-users` | Comma- or newline-separated usernames | GitHub usernames blocked from triggering agent runs |
| `GH_AW_GITHUB_APPROVAL_LABELS` | `tools.github.approval-labels` | Comma- or newline-separated label names | Labels that promote content to “approved” integrity for guard checks |
| `GH_AW_GITHUB_TRUSTED_USERS` | `tools.github.trusted-users` | Comma- or newline-separated usernames | GitHub usernames elevated to “approved” integrity, bypassing guard checks |
Set an org-wide blocked user list:
```bash
gh variable set GH_AW_GITHUB_BLOCKED_USERS --org my-org --body "bot-account1,bot-account2"
```
See [Tools Reference](/gh-aw/reference/tools/) for complete guard policy documentation.
***
## Precedence Rules
[Section titled “Precedence Rules”](#precedence-rules)
Environment variables follow a **most-specific-wins** model, consistent with GitHub Actions. Variables at more specific scopes completely override variables with the same name at less specific scopes.
### General Precedence (Highest to Lowest)
[Section titled “General Precedence (Highest to Lowest)”](#general-precedence-highest-to-lowest)
1. **Step-level** (`steps[*].env`, `githubActionsStep.env`)
2. **Job-level** (`jobs..env`)
3. **Workflow-level** (`env:`)
### Safe Outputs Precedence
[Section titled “Safe Outputs Precedence”](#safe-outputs-precedence)
1. **Job-specific** (`safe-outputs.jobs..env`)
2. **Global** (`safe-outputs.env`)
3. **Workflow-level** (`env:`)
### Context-Specific Scopes
[Section titled “Context-Specific Scopes”](#context-specific-scopes)
These scopes are independent and operate in different contexts: `engine.env`, `container.env`, `services..env`, `sandbox.agent.env`, `sandbox.mcp.env`, `tools..env`, `mcp-scripts..env`.
### Override Example
[Section titled “Override Example”](#override-example)
```yaml
---
env:
API_KEY: default-key
DEBUG: "false"
jobs:
test:
env:
API_KEY: test-key # Overrides workflow-level
EXTRA: "value"
steps:
- run: |
# API_KEY = "test-key" (job-level override)
# DEBUG = "false" (workflow-level inherited)
# EXTRA = "value" (job-level)
---
```
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Frontmatter Reference](/gh-aw/reference/frontmatter/) - Complete frontmatter configuration
* [Safe Outputs](/gh-aw/reference/safe-outputs/) - Safe output environment configuration
* [Sandbox](/gh-aw/reference/sandbox/) - Sandbox environment variables
* [Tools](/gh-aw/reference/tools/) - MCP tool configuration and guard policies
* [MCP Scripts](/gh-aw/reference/mcp-scripts/) - MCP script tool configuration
* [Engines](/gh-aw/reference/engines/) - AI engine configuration and model selection
* [Tokens](/gh-aw/reference/tokens/) - Engine secrets and GitHub token reference
* [GitHub Actions Environment Variables](https://docs.github.com/en/actions/learn-github-actions/variables) - GitHub Actions documentation
# Frequently Asked Questions
> Answers to common questions about GitHub Agentic Workflows, including security, costs, privacy, and configuration.
Note
GitHub Agentic Workflows is in early development and may change significantly. Using automated agentic workflows requires careful attention to security considerations and careful human supervision, and even then things can still go wrong. Use it with caution, and at your own risk.
## Determinism
[Section titled “Determinism”](#determinism)
### I like deterministic CI/CD. Isn’t this non-deterministic?
[Section titled “I like deterministic CI/CD. Isn’t this non-deterministic?”](#i-like-deterministic-cicd-isnt-this-non-deterministic)
Agentic workflows are **100% additive** to your existing CI/CD - they don’t replace your deterministic build, test, or release pipelines. Think of it as **Continuous AI** alongside Continuous Integration and Continuous Deployment: a new automation layer running in GitHub Actions where security, permissions, and repository context already exist.
Your deterministic pipelines stay unchanged. Agentic workflows handle tasks where exact reproducibility doesn’t matter - triaging issues, drafting documentation, researching dependencies, or proposing code improvements for human review.
## Capabilities
[Section titled “Capabilities”](#capabilities)
### What’s the difference between agentic workflows and regular GitHub Actions workflows?
[Section titled “What’s the difference between agentic workflows and regular GitHub Actions workflows?”](#whats-the-difference-between-agentic-workflows-and-regular-github-actions-workflows)
Agentic workflows use AI to interpret natural language instructions in markdown instead of complex YAML. The AI engine can call pre-approved tools to perform tasks while running with read-only default permissions, safe outputs, and sandboxed execution.
### What’s the difference between agentic workflows and just running a coding agent in GitHub Actions?
[Section titled “What’s the difference between agentic workflows and just running a coding agent in GitHub Actions?”](#whats-the-difference-between-agentic-workflows-and-just-running-a-coding-agent-in-github-actions)
While you could install and run a coding agent directly in a standard GitHub Actions workflow, agentic workflows provide a structured framework with simpler markdown format, built-in security controls, pre-defined tools for GitHub operations, and easy switching between AI engines.
### Can agentic workflows write code and create pull requests?
[Section titled “Can agentic workflows write code and create pull requests?”](#can-agentic-workflows-write-code-and-create-pull-requests)
Yes! Agentic workflows can create pull requests using the `create-pull-request` safe output. This allows the workflow to propose code changes, documentation updates, or other modifications as pull requests for human review and merging.
Some organizations may completely disable the creation of pull requests from GitHub Actions. In such cases, workflows can still generate diffs or suggestions in issues or comments for manual application.
### Can agentic workflows do more than code?
[Section titled “Can agentic workflows do more than code?”](#can-agentic-workflows-do-more-than-code)
Yes! Agentic workflows can analyze repositories, generate reports, triage issues, research information, create documentation, and coordinate work. The AI interprets natural language instructions and uses available [tools](/gh-aw/reference/tools/) to accomplish tasks.
### Can agentic workflows mix regular GitHub Actions steps with AI agentic steps?
[Section titled “Can agentic workflows mix regular GitHub Actions steps with AI agentic steps?”](#can-agentic-workflows-mix-regular-github-actions-steps-with-ai-agentic-steps)
Yes! Agentic workflows can include both AI agentic steps and traditional GitHub Actions steps. You can add custom steps before the agentic job using the [`steps:` configuration](/gh-aw/reference/frontmatter/#custom-steps-steps). Additionally, [custom safe output jobs](/gh-aw/reference/safe-outputs/#custom-safe-output-jobs-jobs) can be used as consumers of agentic outputs. [MCP Scripts](/gh-aw/reference/mcp-scripts/) allow you to pass data between traditional steps and the AI agent with added checking.
### Can agentic workflows read other repositories?
[Section titled “Can agentic workflows read other repositories?”](#can-agentic-workflows-read-other-repositories)
Not by default, but yes with proper configuration. Cross-repository access requires:
1. A **Personal Access Token (PAT)** with access to target repositories
2. Configuring the token in your workflow
See [MultiRepoOps](/gh-aw/patterns/multi-repo-ops/) for coordinating across repositories, or [SideRepoOps](/gh-aw/patterns/side-repo-ops/) for running workflows from a separate repository.
### Can I use agentic workflows in private repositories?
[Section titled “Can I use agentic workflows in private repositories?”](#can-i-use-agentic-workflows-in-private-repositories)
Yes, and in many cases we recommend it. Private repositories are ideal for proprietary code, creating a “sidecar” repository with limited access, testing workflows, and organization-internal automation. See [SideRepoOps](/gh-aw/patterns/side-repo-ops/) for patterns using private repositories.
### Can I edit workflows directly on GitHub.com without recompiling?
[Section titled “Can I edit workflows directly on GitHub.com without recompiling?”](#can-i-edit-workflows-directly-on-githubcom-without-recompiling)
Yes! The **markdown body** (AI instructions) is loaded at runtime and can be edited directly on GitHub.com or in any editor. Changes take effect on the next workflow run without recompilation.
However, **frontmatter configuration** (tools, permissions, triggers, network rules) is embedded in the compiled workflow and requires recompilation when changed. Run `gh aw compile my-workflow` after editing frontmatter.
See [Editing Workflows](/gh-aw/guides/editing-workflows/) for complete guidance on when recompilation is needed.
### Can workflows trigger other workflows?
[Section titled “Can workflows trigger other workflows?”](#can-workflows-trigger-other-workflows)
Yes, using the `dispatch-workflow` safe output:
```yaml
safe-outputs:
dispatch-workflow:
max: 1
```
This allows your workflow to trigger up to 1 other workflows with custom inputs. See [Safe Outputs](/gh-aw/reference/safe-outputs/#workflow-dispatch-dispatch-workflow) for details.
### Can I use MCP servers with agentic workflows?
[Section titled “Can I use MCP servers with agentic workflows?”](#can-i-use-mcp-servers-with-agentic-workflows)
Yes! [Model Context Protocol (MCP)](/gh-aw/reference/glossary/#mcp-model-context-protocol) servers extend workflow capabilities with custom tools and integrations. Configure them in your frontmatter:
```yaml
tools:
mcp-servers:
my-server:
image: "ghcr.io/org/my-mcp-server:latest"
network:
allowed: ["api.example.com"]
```
See [Getting Started with MCP](/gh-aw/guides/getting-started-mcp/) and [MCP Servers](/gh-aw/guides/mcps/) for configuration guides.
### The `plugins:` field I was using is gone - how do I install agent plugins now?
[Section titled “The plugins: field I was using is gone - how do I install agent plugins now?”](#the-plugins-field-i-was-using-is-gone---how-do-i-install-agent-plugins-now)
The `plugins:` frontmatter field has been removed in favour of the `dependencies:` field backed by [Microsoft APM (Agent Package Manager)](https://microsoft.github.io/apm/). APM provides cross-agent support for all agent primitives – skills, prompts, instructions, hooks, and plugins (including the Copilot `plugin.json` format and the Claude `plugin.json` format).
Run `gh aw fix --write` to automatically migrate your existing `plugins:` fields to `dependencies:`.
Use the `dependencies:` field in your workflow frontmatter to install plugins:
```yaml
# Simple list (public or same-org packages)
dependencies:
- github/my-copilot-plugin
- github/awesome-copilot/plugins/context-engineering
```
For cross-org private packages, use `github-app:` authentication:
```yaml
dependencies:
github-app:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
packages:
- acme-org/acme-plugins
```
The `dependencies:` approach works with all supported engines (Copilot, Claude, Codex, Gemini), whereas the old `plugins:` field was limited to the Copilot engine only.
See [APM Dependencies](/gh-aw/reference/dependencies/) for full configuration options.
### Can I use Claude plugins with APM dependencies?
[Section titled “Can I use Claude plugins with APM dependencies?”](#can-i-use-claude-plugins-with-apm-dependencies)
Yes! APM supports Claude plugins in the `plugin.json` format. When `engine: claude` is set, APM automatically infers the engine target and unpacks only Claude-compatible primitives. Use `#tag` or `#branch` suffixes to pin specific versions:
```yaml
engine: claude
dependencies:
- owner/repo/plugins/my-plugin#v2.0 # pinned to a tag
- owner/repo/plugins/my-plugin#main # pinned to a branch
```
For private cross-org plugins and other configuration options, see [APM Dependencies](/gh-aw/reference/dependencies/).
### Can workflows be broken up into shareable components?
[Section titled “Can workflows be broken up into shareable components?”](#can-workflows-be-broken-up-into-shareable-components)
Workflows can import shared configurations and components:
```yaml
imports:
- shared/github-tools.md
- githubnext/agentics/shared/common-tools.md
```
This enables reusable tool configurations, network settings, and permissions across workflows. See [Imports](/gh-aw/reference/imports/) and [Packaging Imports](/gh-aw/guides/packaging-imports/) for details.
### Can I run workflows on a schedule?
[Section titled “Can I run workflows on a schedule?”](#can-i-run-workflows-on-a-schedule)
Yes, use cron expressions in the `on:` trigger:
```yaml
on:
schedule:
- cron: "0 9 * * MON" # Every Monday at 9am UTC
```
See [Schedule Syntax](/gh-aw/reference/schedule-syntax/) for cron expression reference.
### Can I run workflows conditionally?
[Section titled “Can I run workflows conditionally?”](#can-i-run-workflows-conditionally)
Yes, use the `if:` expression at the workflow level:
```yaml
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
```
See [Conditional Execution](/gh-aw/reference/frontmatter/#conditional-execution-if) in the Frontmatter Reference for details.
## Guardrails
[Section titled “Guardrails”](#guardrails)
### Agentic workflows run in GitHub Actions. Can they access my repository secrets?
[Section titled “Agentic workflows run in GitHub Actions. Can they access my repository secrets?”](#agentic-workflows-run-in-github-actions-can-they-access-my-repository-secrets)
Repository secrets are not available to the agentic step by default. The AI agent runs with read-only permissions and cannot directly access your repository secrets unless explicitly configured. You should review workflows carefully, follow [GitHub Actions security guidelines](https://docs.github.com/en/actions/reference/security/secure-use), use least-privilege permissions, and inspect the compiled `.lock.yml` file. See the [Security Architectur](/gh-aw/introduction/architecture/) for details.
Some MCP tools may be configured using secrets, but these are only accessible to the specific tool steps, not the AI agent itself. Minimize the use of tools equipped with highly privileged secrets.
### Agentic workflows run in GitHub Actions. Can they write to the repository?
[Section titled “Agentic workflows run in GitHub Actions. Can they write to the repository?”](#agentic-workflows-run-in-github-actions-can-they-write-to-the-repository)
By default, the agentic “coding agent” step of agentic workflows runs with read-only permissions. Write operations require explicit approval through [safe outputs](/gh-aw/reference/safe-outputs/) or explicit general `write` permissions (not recommended). This ensures that AI agents cannot make arbitrary changes to your repository.
If safe outputs are configured, the workflow has limited, highly specific write operations that are then sanitized and executed securely.
### What sanitization is done on AI outputs before applying changes?
[Section titled “What sanitization is done on AI outputs before applying changes?”](#what-sanitization-is-done-on-ai-outputs-before-applying-changes)
All safe outputs from the AI agent are sanitized before being applied to your repository. Sanitization includes secret redaction, URL domain filtering, XML escaping, size limits, control character stripping, GitHub reference escaping and HTTPS enforcement.
Additionally, safe outputs enforce permission separation - write operations happen in separate jobs with scoped permissions, never in the agentic job itself.
See [Safe Outputs - Text Sanitization](/gh-aw/reference/safe-outputs/#text-sanitization-allowed-domains-allowed-github-references) for configuration options.
### How do I prevent workflow output from creating backlinks in referenced issues?
[Section titled “How do I prevent workflow output from creating backlinks in referenced issues?”](#how-do-i-prevent-workflow-output-from-creating-backlinks-in-referenced-issues)
When AI-generated content mentions issue or PR numbers (such as `#123` or `owner/repo#456`), GitHub automatically creates “mentioned in…” timeline entries in those issues. Set `allowed-github-references: []` to escape all such references before the content is posted:
```yaml
safe-outputs:
allowed-github-references: [] # Escape all GitHub references
create-issue:
```
With an empty list, every `#N` and `owner/repo#N` reference in the output is wrapped in backticks, which prevents GitHub from resolving them as cross-references and avoids cluttering other repositories’ timelines. This is especially useful for [SideRepoOps](/gh-aw/patterns/side-repo-ops/) workflows that write content about issues in a main repository from a separate sidecar repository.
To allow references only from the current repository while still escaping all others:
```yaml
safe-outputs:
allowed-github-references: [repo]
add-comment:
```
When `allowed-github-references` is not configured at all, all references are left unescaped (default behavior).
See [Text Sanitization](/gh-aw/reference/safe-outputs/#text-sanitization-allowed-domains-allowed-github-references) for full configuration options.
### Tell me more about guardrails
[Section titled “Tell me more about guardrails”](#tell-me-more-about-guardrails)
Guardrails are foundational to the design. Agentic workflows implement defense-in-depth through compilation-time validation (schema checks, expression safety, action SHA pinning), runtime isolation (sandboxed containers with network controls), permission separation (read-only defaults with [safe outputs](/gh-aw/reference/safe-outputs/) for writes), tool allowlisting, and output sanitization. See the [Security Architecture](/gh-aw/introduction/architecture/).
### How is my code and data processed?
[Section titled “How is my code and data processed?”](#how-is-my-code-and-data-processed)
By default, your workflow is run on GitHub Actions, like any other GitHub Actions workflow, and as one if its jobs it invokes your nominated [AI Engine (coding agent)](/gh-aw/reference/engines/), run in a container. This engine may in turn make tool calls and MCP calls. When using the default **GitHub Copilot CLI**, the workflow is processed by the `copilot` CLI tool which uses GitHub Copilot’s services and related AI models. The specifics depend on your engine choice:
* **GitHub Copilot CLI**: See [GitHub Copilot documentation](https://docs.github.com/en/copilot) for details.
* **Claude/Codex**: Uses respective providers’ APIs with their data handling policies.
See the [Security Architecture](/gh-aw/introduction/architecture/) for details on the execution and data flow.
### Does the underlying AI engine run in a sandbox?
[Section titled “Does the underlying AI engine run in a sandbox?”](#does-the-underlying-ai-engine-run-in-a-sandbox)
Yes, the [AI engine](/gh-aw/reference/engines/) runs in a containerized sandbox with network egress control via the [Agent Workflow Firewall](/gh-aw/reference/sandbox/), container isolation, GitHub Actions resource constraints, and limited filesystem access to workspace and temporary directories. The sandbox container runs inside a GitHub Actions VM for additional isolation. See [Sandbox Configuration](/gh-aw/reference/sandbox/).
### Can an agentic workflow use outbound network requests?
[Section titled “Can an agentic workflow use outbound network requests?”](#can-an-agentic-workflow-use-outbound-network-requests)
Yes, but network access is restricted by the [Agent Workflow Firewall](/gh-aw/reference/sandbox/). You must explicitly declare which domains the workflow can access:
```yaml
network:
allowed:
- defaults # Basic infrastructure
- python # Python/PyPI ecosystem
- "api.example.com" # Custom domain
```
See [Network Permissions](/gh-aw/reference/network/) for complete configuration options.
### How does integrity filtering protect my workflow?
[Section titled “How does integrity filtering protect my workflow?”](#how-does-integrity-filtering-protect-my-workflow)
[Integrity filtering](/gh-aw/reference/integrity/) controls which GitHub content the agent can see, filtering by **author trust** and **merge status**. The MCP gateway silently removes content below the configured `min-integrity` threshold before the AI engine sees it.
For **public repositories**, `min-integrity: approved` is automatically applied at runtime — restricting content to owners, members, and collaborators — even without additional authentication.
For triage or spam-detection workflows that need to process content from all users, set `min-integrity: none` explicitly:
```yaml
tools:
github:
min-integrity: none
```
See [Integrity Filtering](/gh-aw/reference/integrity/) for available levels, user blocking, and approval labels.
## Configuration & Setup
[Section titled “Configuration & Setup”](#configuration--setup)
### What is a workflow lock file?
[Section titled “What is a workflow lock file?”](#what-is-a-workflow-lock-file)
A **workflow lock file** (`.lock.yml`) is the compiled GitHub Actions workflow generated from your `.md` file by `gh aw compile`. It contains SHA-pinned actions, resolved imports, configured permissions, and all guardrail hardening - inspect it to see exactly what will run, with no hidden configuration.
Both files should be committed to version control:
* **`.md` file**: Your source - edit the prompt body freely; changes take effect at the next run without recompiling
* **`.lock.yml` file**: The compiled workflow GitHub Actions actually runs; must be regenerated after any frontmatter changes (permissions, tools, triggers)
### What is the actions-lock.json file?
[Section titled “What is the actions-lock.json file?”](#what-is-the-actions-lockjson-file)
The `.github/aw/actions-lock.json` file is a cache of resolved `action@version` → ref mappings. During compilation, the compiler **tries** to pin each action reference to an immutable commit SHA for security. Resolving a version tag to a SHA requires querying the GitHub API (scanning releases), which can fail when the available token has limited permissions — for example, when compiling via GitHub Copilot Coding Agent (CCA) where the token may not have access to external repositories. In those cases, the compiler may fall back to leaving a stable version tag ref (such as `@v0`) instead of a SHA.
The cache avoids this problem: if a ref (typically a SHA) was previously resolved (using a user PAT or a GitHub Actions token with broader access), the result is stored in `actions-lock.json` and reused on subsequent compilations, regardless of the current token’s capabilities. Without this cache, compilation is unstable — it succeeds with a permissive token but fails when token access is restricted.
Commit `actions-lock.json` to version control so that all contributors and automated tools (including CCA) use consistent action refs (SHAs or version tags) without needing to re-resolve them. Refresh the cache periodically with `gh aw update-actions`, or delete it and recompile to force a full re-resolution when you have an appropriate token. See [Action Pinning](/gh-aw/reference/compilation-process/#action-pinning) for details.
### What is `github/gh-aw-actions`?
[Section titled “What is github/gh-aw-actions?”](#what-is-githubgh-aw-actions)
`github/gh-aw-actions` is the GitHub Actions repository containing all reusable actions that power compiled agentic workflows. Compiled `.lock.yml` files reference these actions as `github/gh-aw-actions/setup@` (where `` is usually a commit SHA, but may be a stable version tag such as `v0`). These references are managed entirely by `gh aw compile` — never edit them manually. See [The gh-aw-actions Repository](/gh-aw/reference/compilation-process/#the-gh-aw-actions-repository) for details.
### Why is Dependabot opening PRs to update `github/gh-aw-actions`?
[Section titled “Why is Dependabot opening PRs to update github/gh-aw-actions?”](#why-is-dependabot-opening-prs-to-update-githubgh-aw-actions)
Dependabot scans `.lock.yml` files for action references and treats `github/gh-aw-actions` pins as regular dependencies to update. **Do not merge these PRs.** Action pins in compiled workflows should only be updated by running `gh aw compile` or `gh aw update-actions`.
Suppress these PRs by adding an `ignore` entry in `.github/dependabot.yml`:
```yaml
updates:
- package-ecosystem: github-actions
directory: "/"
ignore:
# ignore updates to gh-aw-actions, which only appears in auto-generated *.lock.yml
# files managed by 'gh aw compile' and should not be touched by dependabot
- dependency-name: "github/gh-aw-actions"
```
See [Dependabot and gh-aw-actions](/gh-aw/reference/compilation-process/#dependabot-and-gh-aw-actions) for more details.
### How does `gh aw upgrade` resolve action versions when no GitHub Releases exist?
[Section titled “How does gh aw upgrade resolve action versions when no GitHub Releases exist?”](#how-does-gh-aw-upgrade-resolve-action-versions-when-no-github-releases-exist)
`gh aw upgrade` (and `gh aw update-actions`) resolves the latest version of each referenced action using a two-step process:
1. **GitHub Releases API** — queries `/repos/{owner}/{repo}/releases` via the `gh` CLI. If releases are found, the highest compatible semantic version is selected.
2. **Git tag fallback** — if the Releases API returns an empty list (which happens when a repository publishes tags without creating GitHub Releases), the command automatically falls back to scanning tags via `git ls-remote`. This fallback is **safe to ignore** — tags are a valid source for version pinning.
Only if *both* sources return no results does the upgrade produce a warning that cannot be resolved automatically.
> **Note:** `github/gh-aw-actions` intentionally publishes only tags (not GitHub Releases). The `gh aw upgrade` warning `github/gh-aw-actions/setup: no releases found` that appeared in earlier versions was caused by this two-step logic not falling back to tags. It has been fixed — the tag fallback now runs automatically.
### Why do I need a token or key?
[Section titled “Why do I need a token or key?”](#why-do-i-need-a-token-or-key)
When using **GitHub Copilot CLI**, a Personal Access Token (PAT) with “Copilot Requests” permission authenticates and associates automation work with your GitHub account. This ensures usage tracking against your subscription, appropriate AI permissions, and auditable actions. In the future, this may support organization-level association. See [Authentication](/gh-aw/reference/auth/).
### Can I use `CLAUDE_CODE_OAUTH_TOKEN` with the Claude engine?
[Section titled “Can I use CLAUDE\_CODE\_OAUTH\_TOKEN with the Claude engine?”](#can-i-use-claude_code_oauth_token-with-the-claude-engine)
No. `CLAUDE_CODE_OAUTH_TOKEN` is not supported by GitHub Agentic Workflows. The only supported authentication method for the Claude engine is [`ANTHROPIC_API_KEY`](/gh-aw/reference/auth/#anthropic_api_key), which must be configured as a GitHub Actions secret. Provider-based OAuth authentication for Claude (such as billing through a Claude Teams subscription) is not supported. See [Authentication](/gh-aw/reference/auth/) and [AI Engines](/gh-aw/reference/engines/#available-coding-agents) for setup instructions.
### What hidden runtime dependencies does this have?
[Section titled “What hidden runtime dependencies does this have?”](#what-hidden-runtime-dependencies-does-this-have)
The executing agentic workflow uses your nominated coding agent (defaulting to GitHub Copilot CLI), a GitHub Actions VM with NodeJS, pinned Actions from [github/gh-aw](https://github.com/github/gh-aw) releases, and an Agent Workflow Firewall container for network control (optional but default). The exact YAML workflow can be inspected in the compiled `.lock.yml` file - there’s no hidden configuration.
### Why are macOS runners not supported?
[Section titled “Why are macOS runners not supported?”](#why-are-macos-runners-not-supported)
macOS runners (`macos-*`) are not currently supported in agentic workflows. Agentic workflows rely on containers to build a secure execution sandbox - specifically the [Agent Workflow Firewall](/gh-aw/reference/sandbox/) that provides network egress control and process isolation. GitHub-hosted macOS runners do not support container jobs, which is a hard requirement for this security architecture.
Use `ubuntu-latest` (the default) or another Linux-based runner instead. For tasks that genuinely require macOS-specific tooling, consider running those steps in a regular GitHub Actions job that coordinates with your agentic workflow.
### I’m not using a supported AI Engine (coding agent). What should I do?
[Section titled “I’m not using a supported AI Engine (coding agent). What should I do?”](#im-not-using-a-supported-ai-engine-coding-agent-what-should-i-do)
If you want to use a coding agent that isn’t currently supported (Copilot, Claude, or Codex), you can contribute support to the [gh-aw repository](https://github.com/github/gh-aw), or open an issue describing your use case. See [AI Engines](/gh-aw/reference/engines/).
### Can I test workflows without affecting my repository?
[Section titled “Can I test workflows without affecting my repository?”](#can-i-test-workflows-without-affecting-my-repository)
Yes! Use [TrialOps](/gh-aw/patterns/trial-ops/) to test workflows in isolated trial repositories. This lets you validate behavior and iterate on prompts without creating real issues, PRs, or comments in your actual repository.
### Where can I find help with common issues?
[Section titled “Where can I find help with common issues?”](#where-can-i-find-help-with-common-issues)
See [Common Issues](/gh-aw/troubleshooting/common-issues/) for detailed troubleshooting guidance including workflow failures, debugging strategies, permission issues, and network problems.
### Why is my create-discussion workflow failing?
[Section titled “Why is my create-discussion workflow failing?”](#why-is-my-create-discussion-workflow-failing)
Ensure discussions are enabled (**Settings → Features → Discussions**) and the workflow has `discussions: write` permission. For category matching failures, verify spelling (case-insensitive) and use lowercase slugs (e.g., `general`, `announcements`) rather than display names.
Use `fallback-to-issue: true` (the default) to automatically create an issue if discussions aren’t available. See [Discussion Creation](/gh-aw/reference/safe-outputs/#discussion-creation-create-discussion) for details.
### Why is my create-pull-request workflow failing with “GitHub Actions is not permitted to create or approve pull requests”?
[Section titled “Why is my create-pull-request workflow failing with “GitHub Actions is not permitted to create or approve pull requests”?”](#why-is-my-create-pull-request-workflow-failing-with-github-actions-is-not-permitted-to-create-or-approve-pull-requests)
Some organizations block PR creation by GitHub Actions via **Settings → Actions → General → Workflow permissions**. If you can’t enable it, use one of these alternatives:
**Automatic issue fallback (default)** — `fallback-as-issue: true` is the default; when PR creation is blocked an issue with the branch link is created instead. Requires `contents: write`, `pull-requests: write`, and `issues: write`.
**Assign to Copilot** — create an issue assigned to `copilot` for automated implementation:
```yaml
safe-outputs:
create-issue:
assignees: [copilot]
labels: [automation, enhancement]
```
**Disable fallback** — set `fallback-as-issue: false` to skip the issue fallback and only attempt PR creation. Requires only `contents: write` and `pull-requests: write`, but the workflow will fail if PR creation is blocked.
See [Pull Request Creation](/gh-aw/reference/safe-outputs/#pull-request-creation-create-pull-request) for details.
### Why don’t pull requests created by agentic workflows trigger my CI checks?
[Section titled “Why don’t pull requests created by agentic workflows trigger my CI checks?”](#why-dont-pull-requests-created-by-agentic-workflows-trigger-my-ci-checks)
This is expected GitHub Actions security behavior. Pull requests created using the default `GITHUB_TOKEN` or by the GitHub Actions bot user **do not trigger workflow runs** on `pull_request`, `pull_request_target`, or `push` events. This is a [GitHub Actions security feature](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow) designed to prevent accidental recursive workflow execution.
The easy way to fix this problem is to set a secret `GH_AW_CI_TRIGGER_TOKEN` with a Personal Access Token (PAT) with ‘Contents: Read & Write’ permission to your repo.
See [Triggering CI](/gh-aw/reference/triggering-ci/) for more details on how to configure workflows to run CI checks on PRs created by agentic workflows.
### How do I suppress the “Generated by…” text in workflow outputs?
[Section titled “How do I suppress the “Generated by…” text in workflow outputs?”](#how-do-i-suppress-the-generated-by-text-in-workflow-outputs)
When workflows create or update issues, pull requests, discussions, or post comments, they append a `> Generated by [Workflow Name](run_url) for issue #N` attribution line. Use `footer: false` to hide this visible text while preserving the hidden XML markers used for search and tracking.
**Hide footers globally** (all safe output types):
```yaml
safe-outputs:
footer: false
add-comment:
create-issue:
title-prefix: "[ai] "
```
**Hide footers for specific output types only:**
```yaml
safe-outputs:
footer: false # hide for all by default
create-pull-request:
footer: true # override: show footer for PRs only
```
Even with `footer: false`, the hidden `` XML marker is still included in the content for searchability - you can search GitHub for `"gh-aw-workflow-id: my-workflow" in:body` to find all items created by a workflow.
See [Footer Control](/gh-aw/reference/footers/) for complete documentation including per-handler overrides and PR review footer options.
### My workflow fails with “Runtime import file not found” when used in a repository ruleset
[Section titled “My workflow fails with “Runtime import file not found” when used in a repository ruleset”](#my-workflow-fails-with-runtime-import-file-not-found-when-used-in-a-repository-ruleset)
This happens because workflows configured as required status checks run in a restricted context without access to the repository file system, so runtime imports cannot be resolved.
The fix is to enable `inlined-imports: true` in your workflow frontmatter so the compiler bundles all imported content into the compiled `.lock.yml` at compile time. See [Self-Contained Lock Files](/gh-aw/reference/imports/#self-contained-lock-files-inlined-imports-true) for the full details.
### My cross-organization `workflow_call` fails with a repository checkout error
[Section titled “My cross-organization workflow\_call fails with a repository checkout error”](#my-cross-organization-workflow_call-fails-with-a-repository-checkout-error)
When a trigger file in one organization calls an agentic workflow in a **different organization**, the activation job attempts to check out the platform repo’s `.github` folder using the caller’s `GITHUB_TOKEN`. That token is scoped to the caller’s organization and cannot access a private repository in another organization, producing an error such as:
```plaintext
fatal: repository 'https://github.com/other-org/platform-repo/' not found
```
The fix is to enable `inlined-imports: true` on the **platform workflow** (the callee). This embeds all imported content into the compiled `.lock.yml` at compile time, eliminating the cross-organization checkout entirely:
```yaml
---
on:
workflow_call:
engine: copilot
inlined-imports: true
imports:
- shared/common-tools.md
---
```
See [Cross-Organization `workflow_call`](/gh-aw/reference/imports/#cross-organization-workflow_call) for the full details.
### My workflow checkout is very slow because my repository is a large monorepo. How can I speed it up?
[Section titled “My workflow checkout is very slow because my repository is a large monorepo. How can I speed it up?”](#my-workflow-checkout-is-very-slow-because-my-repository-is-a-large-monorepo-how-can-i-speed-it-up)
Use **sparse checkout** to only fetch the parts of the repository that your workflow actually needs. This can reduce checkout time from tens of minutes to seconds for large monorepos.
Configure `sparse-checkout` in your workflow frontmatter using the `checkout:` field:
```yaml
checkout:
sparse-checkout: |
node/my-package
.github
```
This generates a checkout step that only downloads the specified paths, dramatically reducing clone size and time.
For cases where you need multiple parts of a monorepo with different settings, you can combine checkouts:
```yaml
checkout:
- sparse-checkout: |
node/my-package
.github
- repository: org/shared-libs
path: ./libs/shared
sparse-checkout: |
defaults/
```
The `sparse-checkout` field accepts newline-separated path patterns compatible with `actions/checkout`. See [GitHub Repository Checkout](/gh-aw/reference/checkout/#configuration-options) for the full list of checkout configuration options.
## Workflow Design
[Section titled “Workflow Design”](#workflow-design)
### Should I focus on one workflow, or write many different ones?
[Section titled “Should I focus on one workflow, or write many different ones?”](#should-i-focus-on-one-workflow-or-write-many-different-ones)
One workflow is simpler to maintain and good for learning, while multiple workflows provide better separation of concerns, different triggers and permissions per task, and clearer audit trails. Start with one or two workflows, then expand as you understand the patterns. See [Peli’s Agent Factory](/gh-aw/blog/2026-01-12-welcome-to-pelis-agent-factory/) for examples.
### Should I create agentic workflows by hand editing or using AI?
[Section titled “Should I create agentic workflows by hand editing or using AI?”](#should-i-create-agentic-workflows-by-hand-editing-or-using-ai)
Either approach works well. AI-assisted authoring using `/agent agentic-workflows create` in GitHub Copilot Chat provides interactive guidance with automatic best practices, while manual editing gives full control and is essential for advanced customizations. See [Creating Workflows](/gh-aw/setup/creating-workflows/) for AI-assisted approach, or [Reference documentation](/gh-aw/reference/frontmatter/) for manual configuration.
### You use ‘agent’ and ‘agentic workflow’ interchangeably. Are they the same thing?
[Section titled “You use ‘agent’ and ‘agentic workflow’ interchangeably. Are they the same thing?”](#you-use-agent-and-agentic-workflow-interchangeably-are-they-the-same-thing)
Yes, for the purpose of this technology. An **“agent”** is an agentic workflow in a repository - an AI-powered automation that can reason, make decisions, and take actions. We use **“agentic workflow”** as it’s plainer and emphasizes the workflow nature of the automation, but the terms are synonymous in this context.
## Costs & Usage
[Section titled “Costs & Usage”](#costs--usage)
### Who pays for the use of AI?
[Section titled “Who pays for the use of AI?”](#who-pays-for-the-use-of-ai)
This depends on the AI engine (coding agent) you use:
* **GitHub Copilot CLI** (default): Usage is currently associated with the individual GitHub account of the user supplying the [`COPILOT_GITHUB_TOKEN`](/gh-aw/reference/auth/#copilot_github_token), and is drawn from the monthly quota of premium requests for that account. See [GitHub Copilot billing](https://docs.github.com/en/copilot/about-github-copilot/subscription-plans-for-github-copilot).
* **Claude**: Usage is billed to the Anthropic account associated with [`ANTHROPIC_API_KEY`](/gh-aw/reference/auth/#anthropic_api_key) Actions secret in the repository.
* **Codex**: Usage is billed to your OpenAI account associated with [`OPENAI_API_KEY`](/gh-aw/reference/auth/#openai_api_key) Actions secret in the repository.
### What’s the approximate cost per workflow run?
[Section titled “What’s the approximate cost per workflow run?”](#whats-the-approximate-cost-per-workflow-run)
Costs vary depending on workflow complexity, AI model, and execution time. GitHub Copilot CLI uses 1-2 premium requests per workflow execution with agentic processing. Track usage with `gh aw logs` for runs and metrics, `gh aw audit ` for detailed token usage and costs, or check your AI provider’s usage portal. Consider creating separate PAT/API keys per repository for tracking.
Reduce costs by optimizing prompts, using smaller models, limiting tool calls, reducing run frequency, and caching results.
### Can I change the model being used, e.g., use a cheaper or more advanced one?
[Section titled “Can I change the model being used, e.g., use a cheaper or more advanced one?”](#can-i-change-the-model-being-used-eg-use-a-cheaper-or-more-advanced-one)
Yes! You can configure the model in your workflow frontmatter:
```yaml
engine:
id: copilot
model: gpt-5 # or claude-sonnet-4
```
Or switch to a different engine entirely:
```yaml
engine: claude
```
See [AI Engines](/gh-aw/reference/engines/) for all configuration options.
# Footer Control
> Learn how to control AI-generated footers in safe output operations and customize footer messages for GitHub issues, pull requests, discussions, and releases.
Control whether AI-generated footers are added to created and updated GitHub items (issues, pull requests, discussions, releases). Footers provide attribution and links to workflow runs, but you may want to omit them for cleaner content or when using custom branding.
## Global Footer Control
[Section titled “Global Footer Control”](#global-footer-control)
Set `footer: false` at the safe-outputs level to hide footers for all output types:
```yaml
safe-outputs:
footer: false # hide footers globally
create-issue:
title-prefix: "[ai] "
create-pull-request:
title-prefix: "[ai] "
```
When `footer: false` is set, visible attribution text is omitted from item bodies but hidden XML markers (workflow-id, tracker-id) remain for searchability. Applies to all output types: create-issue, create-pull-request, create-discussion, update-issue, update-pull-request, update-discussion, and update-release.
## Per-Handler Footer Control
[Section titled “Per-Handler Footer Control”](#per-handler-footer-control)
Override the global setting for specific output types by setting `footer` at the handler level:
```yaml
safe-outputs:
footer: false # global default: no footers
create-issue:
title-prefix: "[issue] "
# inherits footer: false
create-pull-request:
title-prefix: "[pr] "
footer: true # override: show footer for PRs only
```
Individual handler settings always take precedence over the global setting.
## PR Review Footer Control
[Section titled “PR Review Footer Control”](#pr-review-footer-control)
For PR reviews (`submit-pull-request-review`), the `footer` field supports conditional control over when the footer is added to the review body:
```yaml
safe-outputs:
create-pull-request-review-comment:
submit-pull-request-review:
footer: "if-body" # conditional footer based on review body
```
The `footer` field accepts `"always"` (default), `"none"`, or `"if-body"` (footer only when the review has body text). Booleans are accepted: `true` → `"always"`, `false` → `"none"`. Use `"if-body"` for clean approval reviews — approvals without body text appear without a footer, while reviews with comments include it.
## What’s Preserved When Footer is Hidden
[Section titled “What’s Preserved When Footer is Hidden”](#whats-preserved-when-footer-is-hidden)
Even with `footer: false`, hidden HTML markers remain:
* `` — for search and tracking
* `` — for issue/discussion tracking (when applicable)
These markers enable searching for workflow-created items even when footers are hidden.
### Searching for Workflow-Created Items
[Section titled “Searching for Workflow-Created Items”](#searching-for-workflow-created-items)
You can use the workflow-id marker to find all items created by a specific workflow on GitHub.com. The marker is always included in the body of issues, pull requests, discussions, and comments, regardless of the `footer` setting.
**Search Examples:**
Find all open issues created by the `daily-team-status` workflow:
```plaintext
repo:owner/repo is:issue is:open "gh-aw-workflow-id: daily-team-status" in:body
```
Find all pull requests created by the `security-audit` workflow:
```plaintext
repo:owner/repo is:pr "gh-aw-workflow-id: security-audit" in:body
```
Find all items (issues, PRs, discussions) from any workflow in your organization:
```plaintext
org:your-org "gh-aw-workflow-id:" in:body
```
Find comments from a specific workflow:
```plaintext
repo:owner/repo "gh-aw-workflow-id: bot-responder" in:comments
```
Tip
The workflow name in the marker is the filename without `.md`. Combine with filters like `is:open` or `created:>2024-01-01`, and use `in:body` or `in:comments` as appropriate. See [GitHub advanced search](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests).
## Use Cases
[Section titled “Use Cases”](#use-cases)
**Clean content for public repositories:**
```yaml
safe-outputs:
footer: false
create-issue:
title-prefix: "[report] "
labels: [automated]
```
**Custom branding - footers on PRs only:**
```yaml
safe-outputs:
footer: false # hide for issues
create-issue:
title-prefix: "[issue] "
create-pull-request:
footer: true # show for PRs
title-prefix: "[pr] "
```
**Minimal documentation updates:**
```yaml
safe-outputs:
update-release:
footer: false # clean release notes
max: 1
```
## Backward Compatibility
[Section titled “Backward Compatibility”](#backward-compatibility)
The default value for `footer` is `true`, maintaining backward compatibility with existing workflows. To hide footers, you must explicitly set `footer: false`.
## Customizing Footer Messages
[Section titled “Customizing Footer Messages”](#customizing-footer-messages)
Instead of hiding footers entirely, you can customize the footer message text using the `messages.footer` template. This allows you to maintain attribution while using custom branding:
```yaml
safe-outputs:
messages:
footer: "> Powered by [{workflow_name}]({agentic_workflow_url})"
create-issue:
title-prefix: "[bot] "
```
The `messages.footer` template supports variables like `{workflow_name}`, `{agentic_workflow_url}`, `{run_url}`, `{triggering_number}`, `{effective_tokens_suffix}`, and more. `{agentic_workflow_url}` links directly to the agentic workflow file view for the run (equivalent to `{run_url}/agentic_workflow`), while `{run_url}` links to the plain Actions run page. `{effective_tokens_suffix}` is a pre-formatted, always-safe suffix (e.g. `" · ● 1.2K"` or `""`) that you can place directly before `{history_link}` — the same `●` format the default footer uses. See [Custom Messages](/gh-aw/reference/safe-outputs/#custom-messages-messages) for complete documentation on message templates and available variables.
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
* [Safe Outputs](/gh-aw/reference/safe-outputs/) - Complete safe outputs reference
* [Custom Messages](/gh-aw/reference/safe-outputs/#custom-messages-messages) - Message templates and variables
* [Frontmatter](/gh-aw/reference/frontmatter/) - All configuration options for workflows
# Fork Support
> How GitHub Agentic Workflows behaves in forked repositories and how to allow PRs from trusted forks.
GitHub Agentic Workflows has two distinct fork scenarios with different behaviors: **inbound pull requests from forks** and **running workflows inside a forked repository**.
## Running workflows in a fork
[Section titled “Running workflows in a fork”](#running-workflows-in-a-fork)
Agentic workflows do **not** run in forked repositories. When a workflow runs in a fork, all jobs skip automatically using the `if: ${{ !github.event.repository.fork }}` condition injected at compile time.
This means:
* Agent jobs are skipped — no AI execution occurs
* Maintenance and self-update jobs do not run
* No secrets from the upstream repository are available
This is intentional. Forks lack the secrets and context required for agentic workflows to function correctly, and there is no safe way to run agents with partial configuration.
Note
To run agentic workflows in your own repository, fork the upstream repo and configure your own secrets — the workflows will then run in your copy of the repository, which is not a fork from GitHub Actions’ perspective.
## Inbound pull requests from forks
[Section titled “Inbound pull requests from forks”](#inbound-pull-requests-from-forks)
When a pull request is opened from a fork to your repository, the default behavior is to **block the workflow from running** — the `pull_request` trigger includes a repository ID check that verifies the PR head branch comes from the same repository.
To allow workflows to run for PRs from trusted fork repositories, use the `forks:` field:
```aw
---
on:
pull_request:
types: [opened, synchronize]
forks: ["trusted-org/*"]
---
```
### Fork patterns
[Section titled “Fork patterns”](#fork-patterns)
The `forks:` field accepts a string or a list of repository patterns:
| Pattern | Matches |
| -------------- | ---------------------------------------------- |
| `"*"` | All forks (use with caution) |
| `"owner/*"` | All forks from a specific user or organization |
| `"owner/repo"` | A specific fork repository |
```aw
---
on:
pull_request:
types: [opened, synchronize]
forks:
- "trusted-org/*"
- "partner/specific-fork"
---
```
Caution
Allowing all forks (`"*"`) means any user who forks your repository can trigger agent execution. Workflows triggered from fork PRs run with the permissions configured in the workflow — review those permissions carefully before allowing untrusted forks.
# Frontmatter
> Complete guide to all available frontmatter configuration options for GitHub Agentic Workflows, including triggers, permissions, AI engines, and workflow settings.
The [frontmatter](/gh-aw/reference/glossary/#frontmatter) (YAML configuration section between `---` markers) of GitHub Agentic Workflows includes the triggers, permissions, AI [engines](/gh-aw/reference/glossary/#engine) (which AI model/provider to use), and workflow settings. For example:
```yaml
---
on:
issues:
types: [opened]
tools:
edit:
bash: ["gh issue comment"]
---
...markdown instructions...
```
## Frontmatter Elements
[Section titled “Frontmatter Elements”](#frontmatter-elements)
Below is a comprehensive reference to all available frontmatter fields for GitHub Agentic Workflows.
### Trigger Events (`on:`)
[Section titled “Trigger Events (on:)”](#trigger-events-on)
The `on:` section uses standard GitHub Actions syntax to define workflow triggers, with additional fields for security and approval controls:
* Standard GitHub Actions triggers (push, pull\_request, issues, schedule, etc.)
* `reaction:` - Add emoji reactions to triggering items
* `status-comment:` - Post a started/completed comment with a workflow run link (automatically enabled for `slash_command` and `label_command` triggers; must be explicitly set to `true` for other trigger types)
* `stop-after:` - Automatically disable triggers after a deadline
* `manual-approval:` - Require manual approval using environment protection rules
* `forks:` - Configure fork filtering for pull\_request triggers
* `skip-roles:` - Skip workflow execution for specific repository roles
* `skip-bots:` - Skip workflow execution for specific GitHub actors
* `skip-if-match:` - Skip execution when a search query has matches (supports `scope: none`; use top-level `on.github-token` / `on.github-app` for custom auth)
* `skip-if-no-match:` - Skip execution when a search query has no matches (supports `scope: none`; use top-level `on.github-token` / `on.github-app` for custom auth)
* `steps:` - Inject custom deterministic steps into the pre-activation job (saves one workflow job vs. multi-job pattern)
* `permissions:` - Grant additional GitHub token scopes to the pre-activation job (for use with `on.steps:` API calls)
* `github-token:` - Custom token for activation job reactions, status comments, and skip-if search queries
* `github-app:` - GitHub App for minting a short-lived token used by the activation job and all skip-if search steps
See [Trigger Events](/gh-aw/reference/triggers/) for complete documentation.
### Description (`description:`)
[Section titled “Description (description:)”](#description-description)
Provides a human-readable description of the workflow rendered as a comment in the generated lock file.
```yaml
description: "Workflow that analyzes pull requests and provides feedback"
```
### Source Tracking (`source:`)
[Section titled “Source Tracking (source:)”](#source-tracking-source)
Tracks workflow origin in format `owner/repo/path@ref`. Automatically populated when using `gh aw add` to install workflows from external repositories. Optional for manually created workflows.
```yaml
source: "githubnext/agentics/workflows/ci-doctor.md@v1.0.0"
```
### Private Workflows (`private:`)
[Section titled “Private Workflows (private:)”](#private-workflows-private)
Mark a workflow as private to prevent it from being installed into other repositories via `gh aw add`.
```yaml
private: true
```
When `private: true` is set, attempting to add the workflow from another repository will fail with an error:
```plaintext
workflow 'owner/repo/internal-tooling' is private and cannot be added to other repositories
```
Use this field for internal tooling, sensitive automation, or workflows that depend on repository-specific context and are not intended for external reuse.
Note
The `private:` field only blocks installation via `gh aw add`. It does not affect the visibility of the workflow file itself — that is controlled by your repository’s access settings.
### Resources (`resources:`)
[Section titled “Resources (resources:)”](#resources-resources)
Declares additional workflow or action files to fetch alongside this workflow when running `gh aw add`. Use this field when the workflow depends on companion workflows or custom actions stored in the same directory.
```yaml
resources:
- triage-issue.md # companion workflow
- label-issue.md # companion workflow
- shared/helper-action.yml # supporting GitHub Action
```
Entries are relative paths from the workflow’s location in the source repository. GitHub Actions expression syntax (`${{`) is not allowed in resource paths.
When a user runs `gh aw add` to install this workflow, each listed file is also downloaded and placed alongside the main workflow in the target repository. This ensures companion workflows and custom actions the main workflow depends on are available after installation.
In addition to files explicitly listed in `resources:`, `gh aw add` automatically fetches workflows referenced in the [`dispatch-workflow`](/gh-aw/reference/safe-outputs/#workflow-dispatch-dispatch-workflow) safe output.
### Labels (`labels:`)
[Section titled “Labels (labels:)”](#labels-labels)
Optional array of strings for categorizing and organizing workflows. Labels are displayed in `gh aw status` command output and can be filtered using the `--label` flag.
```yaml
labels: ["automation", "ci", "diagnostics"]
```
Labels help organize workflows by purpose, team, or functionality. They appear in status command table output as `[automation ci diagnostics]` and as a JSON array in `--json` mode. Filter workflows by label using `gh aw status --label automation`.
### Metadata (`metadata:`)
[Section titled “Metadata (metadata:)”](#metadata-metadata)
Optional key-value pairs for storing custom metadata compatible with the [GitHub Copilot custom agent spec](https://docs.github.com/en/copilot/reference/custom-agents-configuration).
```yaml
metadata:
author: John Doe
version: 1.0.0
category: automation
```
**Constraints:**
* Keys: 1-64 characters
* Values: Maximum 1024 characters
* Only string values are supported
Metadata provides a flexible way to add descriptive information to workflows without affecting execution.
### APM Dependencies (`shared/apm.md` import)
[Section titled “APM Dependencies (shared/apm.md import)”](#apm-dependencies-sharedapmmd-import)
Import `shared/apm.md` to install [APM (Agent Package Manager)](https://microsoft.github.io/apm/) packages before workflow execution. APM manages AI agent primitives such as skills, prompts, instructions, agents, hooks, and plugins (including the Claude `plugin.json` format).
```aw
imports:
- uses: shared/apm.md
with:
packages:
- microsoft/apm-sample-package
- github/awesome-copilot/skills/review-and-refactor
- microsoft/apm-sample-package#v2.0 # version-pinned
```
Note
The `dependencies:` frontmatter field is deprecated and no longer supported. Migrate to the `imports: - uses: shared/apm.md` approach shown above.
See **[APM Dependencies Reference](/gh-aw/reference/dependencies/)** for the full format specification, version pinning syntax, package reference formats, reproducibility and governance details, and local debugging instructions.
### Runtimes (`runtimes:`)
[Section titled “Runtimes (runtimes:)”](#runtimes-runtimes)
Override default runtime versions for languages and tools used in workflows. The compiler automatically detects runtime requirements from tool configurations and workflow steps, then installs the specified versions.
**Format**: Object with runtime name as key and configuration as value
**Fields per runtime**:
* `version`: Runtime version string (required)
* `action-repo`: Custom GitHub Actions setup action (optional, overrides default)
* `action-version`: Version of the setup action (optional, overrides default)
**Supported runtimes**:
| Runtime | Default Version | Default Setup Action |
| --------- | --------------- | -------------------------- |
| `node` | 24 | `actions/setup-node@v6` |
| `python` | 3.12 | `actions/setup-python@v5` |
| `go` | 1.25 | `actions/setup-go@v5` |
| `uv` | latest | `astral-sh/setup-uv@v5` |
| `bun` | 1.1 | `oven-sh/setup-bun@v2` |
| `deno` | 2.x | `denoland/setup-deno@v2` |
| `ruby` | 3.3 | `ruby/setup-ruby@v1` |
| `java` | 21 | `actions/setup-java@v4` |
| `dotnet` | 8.0 | `actions/setup-dotnet@v4` |
| `elixir` | 1.17 | `erlef/setup-beam@v1` |
| `haskell` | 9.10 | `haskell-actions/setup@v2` |
**Examples**:
Override Node.js version:
```yaml
runtimes:
node:
version: "22"
```
Use specific Python version with custom setup action:
```yaml
runtimes:
python:
version: "3.12"
action-repo: "actions/setup-python"
action-version: "v5"
```
Multiple runtime overrides:
```yaml
runtimes:
node:
version: "20"
python:
version: "3.11"
go:
version: "1.22"
```
**Default Behavior**: If not specified, workflows use default runtime versions as defined in the system. The compiler automatically detects which runtimes are needed based on tool configurations (e.g., `bash: ["node"]`, `bash: ["python"]`) and workflow steps.
**Use Cases**:
* Pin specific runtime versions for reproducibility
* Use preview/beta runtime versions for testing
* Use custom setup actions (forks, enterprise mirrors)
* Override system defaults for compatibility requirements
**Note**: Runtimes from imported shared workflows are automatically merged with your workflow’s runtime configuration.
### Permissions (`permissions:`)
[Section titled “Permissions (permissions:)”](#permissions-permissions)
The `permissions:` section uses a syntax similar to standard GitHub Actions permissions syntax to specify the GitHub read permissions relevant to the agentic (natural language) part of the execution of the workflow. See [GitHub Tools Read Permissions](/gh-aw/reference/permissions/).
### Repository Access Roles (`on.roles:`)
[Section titled “Repository Access Roles (on.roles:)”](#repository-access-roles-onroles)
Controls who can trigger agentic workflows based on repository permission level. Defaults to `[admin, maintainer, write]`.
```yaml
on:
issues:
types: [opened]
roles: [admin, maintainer, write] # Default
```
```yaml
on:
workflow_dispatch:
roles: all # Allow any user (! use with caution)
```
Available roles: `admin`, `maintainer`/`maintain`, `write`, `triage`, `read`, `all`. Workflows with unsafe triggers (`push`, `issues`, `pull_request`) automatically enforce permission checks. Failed checks cancel the workflow with a warning.
Tip
Run `gh aw fix workflow.md --write` to automatically migrate top-level `roles:` to `on.roles:` using the built-in codemod.
### Bot Filtering (`on.bots:`)
[Section titled “Bot Filtering (on.bots:)”](#bot-filtering-onbots)
Configure which GitHub bot accounts can trigger workflows. Useful for allowing specific automation bots while maintaining security controls.
```yaml
on:
issues:
types: [opened]
bots:
- "dependabot[bot]"
- "renovate[bot]"
- "agentic-workflows-dev[bot]"
```
**Behavior**:
* When specified, only the listed bot accounts can trigger the workflow
* The bot must be active (installed) on the repository to trigger the workflow
* Combine with `on.roles:` for comprehensive access control
* Applies to all workflow triggers (`pull_request`, `issues`, etc.)
* When `on.roles: all` is set, bot filtering is not enforced
**Common bot names**:
* `dependabot[bot]` - GitHub Dependabot for dependency updates
* `renovate[bot]` - Renovate bot for automated dependency management
* `github-actions[bot]` - GitHub Actions bot
* `agentic-workflows-dev[bot]` - Development bot for testing workflows
Tip
Run `gh aw fix workflow.md --write` to automatically migrate top-level `bots:` to `on.bots:` using the built-in codemod.
### Skip Roles (`on.skip-roles`)
[Section titled “Skip Roles (on.skip-roles)”](#skip-roles-onskip-roles)
Skip workflow execution for users with specific repository permission levels. Useful for exempting team members from automated checks that should only apply to external contributors.
```yaml
on:
issues:
types: [opened]
skip-roles: [admin, maintainer, write]
```
**Available roles**: `admin`, `maintainer`/`maintain`, `write`, `triage`, `read`
**Behavior**:
* Workflow is cancelled during pre-activation when triggered by users with listed roles
* Check runs before agent execution to avoid unnecessary compute costs
* Merged as union when importing workflows (all skip-roles from imported workflows are combined)
* Useful for AI moderation workflows that should only check external user content
**Example use case**: An AI content moderation workflow that checks issues for policy violations but exempts trusted team members with write access or higher.
### Skip Bots (`on.skip-bots`)
[Section titled “Skip Bots (on.skip-bots)”](#skip-bots-onskip-bots)
Skip workflow execution when triggered by specific GitHub actors (users or bots). Complements `skip-roles` by filtering based on actor identity rather than permission level.
```yaml
on:
issues:
types: [opened]
skip-bots: [github-actions, copilot, dependabot]
```
**Bot name matching**: Automatic flexible matching handles bot names with or without the `[bot]` suffix. For example, specifying `github-actions` matches both `github-actions` and `github-actions[bot]` actors automatically.
**Behavior**:
* Workflow is cancelled during pre-activation when `github.actor` matches any listed actor
* Check runs before agent execution to avoid unnecessary compute costs
* Merged as union when importing workflows (all skip-bots from imported workflows are combined)
* Accepts both user accounts and bot accounts
**String or array format**:
```yaml
# Single bot
skip-bots: github-actions
# Multiple bots
skip-bots: [github-actions, copilot, renovate]
```
**Example use cases**:
* Skip AI workflows when triggered by automation bots to avoid bot-to-bot interactions
* Prevent workflow loops where one workflow’s output triggers another
* Exempt specific known bots from content checks or policy enforcement
### Strict Mode (`strict:`)
[Section titled “Strict Mode (strict:)”](#strict-mode-strict)
Enables enhanced security validation for production workflows. **Enabled by default**.
```yaml
strict: true # Enable (default)
strict: false # Disable for development/testing
```
**Enforcement areas:**
1. Refuses write permissions (`contents:write`, `issues:write`, `pull-requests:write`) - use [safe-outputs](/gh-aw/reference/safe-outputs/) instead
2. Requires explicit [network configuration](/gh-aw/reference/network/)
3. Refuses wildcard `*` in `network.allowed` domains
4. Requires ecosystem identifiers (e.g., `python`, `node`) instead of individual ecosystem domains (e.g., `pypi.org`, `npmjs.org`) for all engines
5. Requires network config for custom MCP servers with containers
6. Enforces GitHub Actions pinned to commit SHAs
7. Refuses deprecated frontmatter fields
When strict mode rejects individual ecosystem domains, helpful error messages suggest the appropriate ecosystem identifier (e.g., “Did you mean: ‘pypi.org’ belongs to ecosystem ‘python’?”).
**Configuration:**
* **Frontmatter**: `strict: true/false` (per-workflow)
* **CLI flag**: `gh aw compile --strict` (all workflows, overrides frontmatter)
Caution
Workflows compiled with `strict: false` cannot run on public repositories. The workflow fails at runtime with an error message prompting recompilation with strict mode.
See [Network Permissions - Strict Mode Validation](/gh-aw/reference/network/#strict-mode-validation) for details on network validation and [CLI Commands](/gh-aw/setup/cli/#compile) for compilation options.
### Feature Flags (`features:`)
[Section titled “Feature Flags (features:)”](#feature-flags-features)
Enable experimental or optional features as key-value pairs.
```yaml
features:
my-experimental-feature: true
action-mode: "script"
```
#### Action Mode (`features.action-mode`)
[Section titled “Action Mode (features.action-mode)”](#action-mode-featuresaction-mode)
Controls how the workflow compiler generates custom action references in compiled workflows. Can be set to `"dev"`, `"release"`, `"action"`, or `"script"`.
```yaml
features:
action-mode: "script"
```
**Available modes:**
* **`dev`** (default): References custom actions using local paths (e.g., `uses: ./actions/setup`). Best for development and testing workflows in the gh-aw repository.
* **`release`**: References custom actions using SHA-pinned remote paths within `github/gh-aw` (e.g., `uses: github/gh-aw/actions/setup@sha`). Used for production workflows with version pinning.
* **`action`**: References custom actions from the `github/gh-aw-actions` external repository at the same release version (e.g., `uses: github/gh-aw-actions/setup@sha`). Uses SHA pinning when available, with a version-tag fallback. Use this when deploying workflows from the `github/gh-aw-actions` distribution repository.
* **`script`**: Generates direct shell script calls instead of using GitHub Actions `uses:` syntax. The compiler:
1. Checks out the `github/gh-aw` repository’s `actions` folder to `/tmp/gh-aw/actions-source`
2. Runs the setup script directly: `bash /tmp/gh-aw/actions-source/actions/setup/setup.sh`
3. Uses shallow clone (`depth: 1`) for efficiency
**When to use script mode:**
* Testing custom action scripts during development
* Debugging action installation issues
* Environments where local action references are not available
* Advanced debugging scenarios requiring direct script execution
**Example:**
```yaml
---
name: Debug Workflow
on: workflow_dispatch
features:
action-mode: "script"
permissions:
contents: read
---
Debug workflow using script mode for custom actions.
```
**Note:** The `action-mode` can also be overridden via the CLI flag `--action-mode` or the environment variable `GH_AW_ACTION_MODE`. The precedence is: CLI flag > feature flag > environment variable > auto-detection.
#### DIFC Proxy (`tools.github.integrity-proxy`)
[Section titled “DIFC Proxy (tools.github.integrity-proxy)”](#difc-proxy-toolsgithubintegrity-proxy)
Controls DIFC (Data Integrity and Flow Control) proxy injection. When `tools.github.min-integrity` is configured, the compiler inserts proxy steps around the agent that enforce integrity-level isolation at the network boundary. The proxy is **enabled by default** — set `integrity-proxy: false` to opt out.
```yaml
tools:
github:
min-integrity: approved
# integrity-proxy: false # uncomment to disable proxy injection
```
Without `min-integrity`, `integrity-proxy` has no effect. When both are configured, the proxy enforces network-boundary integrity filtering in addition to the MCP gateway-level filtering. Set `integrity-proxy: false` when you only need gateway-level filtering.
Migration
The deprecated `features.difc-proxy: true` flag is replaced by this field. Run `gh aw fix` to automatically migrate existing workflows.
### AI Engine (`engine:`)
[Section titled “AI Engine (engine:)”](#ai-engine-engine)
Specifies which AI engine interprets the markdown section. See [AI Engines](/gh-aw/reference/engines/) for details.
```yaml
engine: copilot
```
### Network Permissions (`network:`)
[Section titled “Network Permissions (network:)”](#network-permissions-network)
Controls network access using ecosystem identifiers and domain allowlists. See [Network Permissions](/gh-aw/reference/network/) for full documentation.
```yaml
network:
allowed:
- defaults # Basic infrastructure
- python # Python/PyPI ecosystem
- "api.example.com" # Custom domain
```
### MCP Scripts (`mcp-scripts:`)
[Section titled “MCP Scripts (mcp-scripts:)”](#mcp-scripts-mcp-scripts)
Enables defining custom MCP tools inline using JavaScript or shell scripts. See [MCP Scripts](/gh-aw/reference/mcp-scripts/) for complete documentation on creating custom tools with controlled secret access.
### Safe Outputs (`safe-outputs:`)
[Section titled “Safe Outputs (safe-outputs:)”](#safe-outputs-safe-outputs)
Enables automatic issue creation, comment posting, and other safe outputs. See [Safe Outputs Processing](/gh-aw/reference/safe-outputs/).
### Run Configuration (`run-name:`, `runs-on:`, `runs-on-slim:`, `timeout-minutes:`)
[Section titled “Run Configuration (run-name:, runs-on:, runs-on-slim:, timeout-minutes:)”](#run-configuration-run-name-runs-on-runs-on-slim-timeout-minutes)
Standard GitHub Actions properties:
```yaml
run-name: "Custom workflow run name" # Defaults to workflow name
runs-on: ubuntu-latest # Defaults to ubuntu-latest (main job only)
runs-on-slim: ubuntu-slim # Defaults to ubuntu-slim (framework jobs only)
timeout-minutes: 30 # Defaults to 20 minutes
```
`runs-on` applies to the main agent job only. `runs-on-slim` applies to all framework/generated jobs (activation, safe-outputs, unlock, etc.) and defaults to `ubuntu-slim`. `safe-outputs.runs-on` takes precedence over `runs-on-slim` for safe-output jobs specifically.
`timeout-minutes` accepts either an integer or a GitHub Actions expression string. This allows `workflow_call` reusable workflows to parameterize the timeout via caller inputs:
```yaml
# Literal integer
timeout-minutes: 30
# Expression — useful in reusable (workflow_call) workflows
timeout-minutes: ${{ inputs.timeout }}
```
**Supported runners for `runs-on:`**
| Runner | Status |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `ubuntu-latest` | ✓ Default. Recommended for most workflows. |
| `ubuntu-24.04` / `ubuntu-22.04` | ✓ Supported. |
| `ubuntu-24.04-arm` | ✓ Supported. Linux ARM64 runner. |
| `macos-*` | ✗ Not supported. Docker is unavailable on macOS runners (no nested virtualization). See [FAQ](/gh-aw/reference/faq/). |
| `windows-*` | ✗ Not supported. AWF requires Linux. |
### Workflow Concurrency Control (`concurrency:`)
[Section titled “Workflow Concurrency Control (concurrency:)”](#workflow-concurrency-control-concurrency)
Automatically generates concurrency policies for the agent job. See [Concurrency Control](/gh-aw/reference/concurrency/).
## Environment Variables (`env:`)
[Section titled “Environment Variables (env:)”](#environment-variables-env)
Standard GitHub Actions `env:` syntax for workflow-level environment variables:
```yaml
env:
CUSTOM_VAR: "value"
```
Environment variables can be defined at multiple scopes (workflow, job, step, engine, safe-outputs, etc.) with clear precedence rules. See [Environment Variables](/gh-aw/reference/environment-variables/) for complete documentation on all 13 env scopes and precedence order.
Caution
Do not use `${{ secrets.* }}` expressions in the workflow-level `env:` section. Environment variables defined here are passed directly to the agent container, which means secret values would be visible to the AI model. In strict mode, this is a compilation error. In non-strict mode, it emits a warning.
Use engine-specific secret configuration instead of the `env:` section to pass secrets securely.
## Secrets (`secrets:`)
[Section titled “Secrets (secrets:)”](#secrets-secrets)
Defines secret values passed to workflow execution. Secrets are typically used to provide sensitive configuration to MCP servers or workflow components. Values must be GitHub Actions expressions that reference secrets (e.g., `${{ secrets.API_KEY }}`).
```yaml
secrets:
API_TOKEN: ${{ secrets.API_TOKEN }}
DATABASE_URL: ${{ secrets.DB_URL }}
```
Secrets can also include descriptions for documentation:
```yaml
secrets:
API_TOKEN:
value: ${{ secrets.API_TOKEN }}
description: "API token for external service"
DATABASE_URL:
value: ${{ secrets.DB_URL }}
description: "Production database connection string"
```
**Security best practices:**
* Always use GitHub Actions secret expressions (`${{ secrets.NAME }}`)
* Never commit plaintext secrets to workflow files
* Use environment-specific secrets when possible (via `environment:` field)
* Limit secret access to only the components that need them
**Note:** For passing secrets to reusable workflows, use the `jobs..secrets` field instead. The top-level `secrets:` field is for workflow-level secret configuration.
## Environment Protection (`environment:`)
[Section titled “Environment Protection (environment:)”](#environment-protection-environment)
Specifies the environment for deployment protection rules and environment-specific secrets. Standard GitHub Actions syntax.
```yaml
environment: production
```
See [GitHub Actions environment docs](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment).
## Container Configuration (`container:`)
[Section titled “Container Configuration (container:)”](#container-configuration-container)
Specifies a container to run job steps in.
```yaml
container: node:18
```
See [GitHub Actions container docs](https://docs.github.com/en/actions/how-tos/write-workflows/choose-where-workflows-run/run-jobs-in-a-container).
## Service Containers (`services:`)
[Section titled “Service Containers (services:)”](#service-containers-services)
Defines service containers that run alongside your job (databases, caches, etc.).
```yaml
services:
postgres:
image: postgres:13
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
```
Note
The AWF agent runs inside an isolated Docker container. Service containers expose ports on the runner host, not within the agent’s network namespace. To connect to a service from the agent, use `host.docker.internal` as the hostname instead of `localhost`. For example, a Postgres service configured with port `5432:5432` is accessible at `host.docker.internal:5432`.
See [GitHub Actions service docs](https://docs.github.com/en/actions/using-containerized-services).
## Conditional Execution (`if:`)
[Section titled “Conditional Execution (if:)”](#conditional-execution-if)
Standard GitHub Actions `if:` syntax:
```yaml
if: github.event_name == 'push'
```
## Repository Checkout (`checkout:`)
[Section titled “Repository Checkout (checkout:)”](#repository-checkout-checkout)
Configure how `actions/checkout` is invoked in the agent job. Override default checkout settings or check out multiple repositories for cross-repository workflows.
Set `checkout: false` to disable the default repository checkout entirely — useful for workflows that access repositories through MCP servers or other mechanisms that do not require a local clone:
```yaml
checkout: false
```
See [Cross-Repository Operations](/gh-aw/reference/cross-repository/) for complete documentation on checkout configuration options (including `fetch:`, `checkout: false`), merging behavior, and cross-repo examples.
## Custom Steps (`steps:`)
[Section titled “Custom Steps (steps:)”](#custom-steps-steps)
Add custom steps before agentic execution. If unspecified, a default checkout step is added automatically.
```yaml
steps:
- name: Install dependencies
run: npm ci
```
Use custom steps to precompute data, filter triggers, or prepare context for AI agents. See [Deterministic & Agentic Patterns](/gh-aw/guides/deterministic-agentic-patterns/) for combining computation with AI reasoning.
Custom steps run outside the firewall sandbox. These steps execute with standard GitHub Actions security.
## Post-Execution Steps (`post-steps:`)
[Section titled “Post-Execution Steps (post-steps:)”](#post-execution-steps-post-steps)
Add custom steps after agentic execution. Run after AI engine completes regardless of success/failure (unless conditional expressions are used).
```yaml
post-steps:
- name: Upload Results
if: always()
uses: actions/upload-artifact@v4
with:
name: workflow-results
path: /tmp/gh-aw/
retention-days: 7
```
Useful for artifact uploads, summaries, cleanup, or triggering downstream workflows.
Post-execution steps run OUTSIDE the firewall sandbox. These steps execute with standard GitHub Actions security.
## Custom Jobs (`jobs:`)
[Section titled “Custom Jobs (jobs:)”](#custom-jobs-jobs)
Define custom jobs that run before agentic execution.
```yaml
jobs:
super_linter:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Run Super-Linter
uses: super-linter/super-linter@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
The agentic execution job waits for all custom jobs to complete. Custom jobs can share data through artifacts or job outputs. See [Deterministic & Agentic Patterns](/gh-aw/guides/deterministic-agentic-patterns/) for multi-job workflows.
Custom jobs run outside the firewall sandbox. These jobs execute with standard GitHub Actions security.
### Supported Job-Level Fields
[Section titled “Supported Job-Level Fields”](#supported-job-level-fields)
The following job-level fields are supported in custom jobs:
| Field | Description |
| ------------------- | ------------------------------------------------------------------- |
| `name` | Display name for the job |
| `needs` | Jobs that must complete before this job runs |
| `runs-on` | Runner label — string, array, or object form |
| `if` | Conditional expression to control job execution |
| `permissions` | GitHub token permissions for this job |
| `outputs` | Values exposed to downstream jobs |
| `env` | Environment variables available to all steps |
| `timeout-minutes` | Maximum job duration (GitHub Actions default: 360) |
| `concurrency` | Concurrency group to prevent parallel runs |
| `continue-on-error` | Allow the workflow to continue if this job fails |
| `container` | Docker container to run steps in |
| `services` | Service containers (e.g. databases) |
| `steps` | List of steps — supports complete GitHub Actions step specification |
| `uses` | Reusable workflow to call |
| `with` | Input parameters for a reusable workflow |
| `secrets` | Secrets passed to a reusable workflow |
The `strategy` field (matrix builds) is not supported.
`runs-on` accepts a string, an array of runner labels, or the object form:
```yaml
jobs:
build:
runs-on:
group: my-runner-group
labels: [self-hosted, linux]
steps:
- uses: actions/checkout@v6
```
The following example uses `timeout-minutes` and `env`:
```yaml
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15
env:
NODE_ENV: production
steps:
- uses: actions/checkout@v6
- run: npm ci && npm run build
```
### Job Outputs
[Section titled “Job Outputs”](#job-outputs)
Custom jobs can expose outputs accessible in the agentic execution prompt via `${{ needs.job-name.outputs.output-name }}`:
```yaml
jobs:
release:
outputs:
release_id: ${{ steps.get_release.outputs.release_id }}
version: ${{ steps.get_release.outputs.version }}
steps:
- id: get_release
run: echo "version=${{ github.event.release.tag_name }}" >> $GITHUB_OUTPUT
---
Generate highlights for release ${{ needs.release.outputs.version }}.
```
Job outputs must be string values.
## Cache Configuration (`cache:`)
[Section titled “Cache Configuration (cache:)”](#cache-configuration-cache)
Cache configuration using standard GitHub Actions `actions/cache` syntax:
Single cache:
```yaml
cache:
key: node-modules-${{ hashFiles('package-lock.json') }}
path: node_modules
restore-keys: |
node-modules-
```
## Related Documentation
[Section titled “Related Documentation”](#related-documentation)
See also: [Trigger Events](/gh-aw/reference/triggers/), [AI Engines](/gh-aw/reference/engines/), [CLI Commands](/gh-aw/setup/cli/), [Workflow Structure](/gh-aw/reference/workflow-structure/), [Network Permissions](/gh-aw/reference/network/), [Command Triggers](/gh-aw/reference/command-triggers/), [MCPs](/gh-aw/guides/mcps/), [Tools](/gh-aw/reference/tools/), [Imports](/gh-aw/reference/imports/)
# Frontmatter Reference
> Complete JSON Schema-based reference for all GitHub Agentic Workflows frontmatter configuration options with YAML examples.
This document provides a comprehensive reference for all available frontmatter configuration options in GitHub Agentic Workflows. The examples below are generated from the JSON Schema and include inline comments describing each field.
Note
This documentation is automatically generated from the JSON Schema. For a more user-friendly guide, see [Frontmatter](/gh-aw/reference/frontmatter/).
## Schema Description
[Section titled “Schema Description”](#schema-description)
JSON Schema for validating agentic workflow frontmatter configuration
## Complete Frontmatter Reference
[Section titled “Complete Frontmatter Reference”](#complete-frontmatter-reference)
```yaml
---
# Workflow name that appears in the GitHub Actions interface. If not specified,
# defaults to the filename without extension.
# (optional)
name: "My Workflow"
# Optional workflow description that is rendered as a comment in the generated
# GitHub Actions YAML file (.lock.yml)
# (optional)
description: "Description of the workflow"
# Optional source reference indicating where this workflow was added from. Format:
# owner/repo/path@ref (e.g., githubnext/agentics/workflows/ci-doctor.md@v1.0.0).
# Rendered as a comment in the generated lock file.
# (optional)
source: "example-value"
# Optional tracker identifier to tag all created assets (issues, discussions,
# comments, pull requests). Must be at least 8 characters and contain only
# alphanumeric characters, hyphens, and underscores. This identifier will be
# inserted in the body/description of all created assets to enable searching and
# retrieving assets associated with this workflow.
# (optional)
tracker-id: "example-value"
# Optional array of labels to categorize and organize workflows. Labels can be
# used to filter workflows in status/list commands.
# (optional)
labels: []
# Array of strings
# Optional metadata field for storing custom key-value pairs compatible with the
# custom agent spec. Key names are limited to 64 characters, and values are
# limited to 1024 characters.
# (optional)
metadata:
{}
# Workflow specifications to import. Supports array form (list of paths) or object
# form with 'aw' (agentic workflow paths) and 'apm-packages' (APM packages)
# subfields.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Array of workflow specifications to import (similar to @include
# directives but defined in frontmatter). Format: owner/repo/path@ref (e.g.,
# githubnext/agentics/workflows/shared/common.md@v1.0.0). Can be strings or
# objects with path and inputs. Any markdown files under .github/agents directory
# are treated as custom agent files and only one agent file is allowed per
# workflow.
imports: []
# Array items: undefined
# Option 2: Object form of imports with 'aw' subfield for shared agentic workflow
# paths and 'apm-packages' subfield for APM packages.
imports:
# Array of shared agentic workflow specifications to import. Format:
# owner/repo/path@ref or relative paths.
# (optional)
aw: []
# APM package references to install. Supports array format (list of package slugs)
# or object format with packages and configuration fields. Replaces the top-level
# 'dependencies' field.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple array of APM package references.
apm-packages: []
# Array items: APM package reference in the format 'org/repo' or
# 'org/repo/path/to/skill'
# Option 2: Object format with packages and optional configuration.
apm-packages:
# List of APM package references to install.
packages: []
# Array of APM package reference in the format 'org/repo' or
# 'org/repo/path/to/skill'
# If true, agent restore step clears primitive dirs before unpacking.
# (optional)
isolated: true
# GitHub App credentials for minting installation access tokens used by APM to
# access cross-org private repositories.
# (optional)
github-app:
# GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.
app-id: "example-value"
# GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to
# mint a GitHub App token.
private-key: "example-value"
# Optional owner of the GitHub App installation (defaults to current repository
# owner if not specified)
# (optional)
owner: "example-value"
# Optional list of repositories to grant access to (defaults to current repository
# if not specified)
# (optional)
repositories: []
# Array of strings
# Optional extra GitHub App-only permissions to merge into the minted token. Only
# takes effect for tools.github.github-app; ignored in other github-app contexts.
# (optional)
permissions:
# Permission level for repository administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission for repository administration.
# (optional)
administration: "read"
# Permission level for Codespaces (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces: "read"
# Permission level for Codespaces lifecycle administration (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
codespaces-lifecycle-admin: "read"
# Permission level for Codespaces metadata (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces-metadata: "read"
# Permission level for user email addresses (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
email-addresses: "read"
# Permission level for repository environments (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
environments: "read"
# Permission level for git signing (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
git-signing: "read"
# Permission level for organization members (read/none; "write" is rejected by the
# compiler). Required for org team membership API calls.
# (optional)
members: "read"
# Permission level for organization administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-administration: "read"
# Permission level for organization announcement banners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-announcement-banners: "read"
# Permission level for organization Codespaces (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-codespaces: "read"
# Permission level for organization Copilot (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-copilot: "read"
# Permission level for organization custom org roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-org-roles: "read"
# Permission level for organization custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-properties: "read"
# Permission level for organization custom repository roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-repository-roles: "read"
# Permission level for organization events (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-events: "read"
# Permission level for organization webhooks (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-hooks: "read"
# Permission level for organization members management (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-members: "read"
# Permission level for organization packages (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-packages: "read"
# Permission level for organization personal access token requests (read/none;
# "write" is rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-token-requests: "read"
# Permission level for organization personal access tokens (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-tokens: "read"
# Permission level for organization plan (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-plan: "read"
# Permission level for organization self-hosted runners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-self-hosted-runners: "read"
# Permission level for organization user blocking (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-user-blocking: "read"
# Permission level for repository custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
repository-custom-properties: "read"
# Permission level for repository webhooks (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
repository-hooks: "read"
# Permission level for single file access (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
single-file: "read"
# Permission level for team discussions (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
team-discussions: "read"
# Permission level for Dependabot vulnerability alerts (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
vulnerability-alerts: "read"
# Permission level for GitHub Actions workflow files (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
workflows: "read"
# Environment variables to set on the APM pack step.
# (optional)
env:
{}
# GitHub token expression to authenticate APM with private package repositories.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Optional list of additional workflow or action files that should be fetched
# alongside this workflow when running 'gh aw add'. Entries are relative paths
# (from the same directory as this workflow in the source repository) to agentic
# workflow .md files or GitHub Actions .yml/.yaml files. GitHub Actions expression
# syntax (${{) is not allowed in resource paths.
# (optional)
resources: []
# Array of Relative path to a workflow .md file or action .yml/.yaml file. Must be
# a static path; GitHub Actions expression syntax (${{) is not allowed.
# If true, inline all imports (including those without inputs) at compilation time
# in the generated lock.yml instead of using runtime-import macros. When enabled,
# the frontmatter hash covers the entire markdown body so any change to the
# content will invalidate the hash.
# (optional)
inlined-imports: true
# Workflow triggers that define when the agentic workflow should run. Supports
# standard GitHub Actions trigger events plus special command triggers for
# /commands (required)
# This field supports multiple formats (oneOf):
# Option 1: Simple trigger event name (e.g., 'push', 'issues', 'pull_request',
# 'discussion', 'schedule', 'fork', 'create', 'delete', 'public', 'watch',
# 'workflow_call'), schedule shorthand (e.g., 'daily', 'weekly'), or slash command
# shorthand (e.g., '/my-bot' expands to slash_command + workflow_dispatch)
on: "example-value"
# Option 2: Complex trigger configuration with event-specific filters and options
on:
# Special slash command trigger for /command workflows (e.g., '/my-bot' in issue
# comments). Creates conditions to match slash commands automatically. Note: Can
# be combined with issues/pull_request events if those events only use 'labeled'
# or 'unlabeled' types.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null command configuration - defaults to using the workflow filename
# (without .md extension) as the command name
slash_command: null
# Option 2: Command name as a string (shorthand format, e.g., 'customname' for
# '/customname' triggers). Command names must not start with '/' as the slash is
# automatically added when matching commands.
slash_command: "example-value"
# Option 3: Command configuration object with custom command name
slash_command:
# Name of the slash command that triggers the workflow (e.g., '/help',
# '/analyze'). Used for comment-based workflow activation.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single command name for slash commands (e.g., 'helper-bot' for
# '/helper-bot' triggers). Command names must not start with '/' as the slash is
# automatically added when matching commands. Defaults to workflow filename
# without .md extension if not specified.
name: "My Workflow"
# Option 2: Array of command names that trigger this workflow (e.g., ['cmd.add',
# 'cmd.remove'] for '/cmd.add' and '/cmd.remove' triggers). Each command name must
# not start with '/'.
name: []
# Array items: Command name without leading slash
# Events where the command should be active. Default is all comment-related events
# ('*'). Use GitHub Actions event names.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single event name or '*' for all events. Use GitHub Actions event
# names: 'issues', 'issue_comment', 'pull_request_comment', 'pull_request',
# 'pull_request_review_comment', 'discussion', 'discussion_comment'.
events: "*"
# Option 2: Array of event names where the command should be active (requires at
# least one). Use GitHub Actions event names.
events: []
# Array items: GitHub Actions event name.
# DEPRECATED: Use 'slash_command' instead. Special command trigger for /command
# workflows (e.g., '/my-bot' in issue comments). Creates conditions to match slash
# commands automatically.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null command configuration - defaults to using the workflow filename
# (without .md extension) as the command name
command: null
# Option 2: Command name as a string (shorthand format, e.g., 'customname' for
# '/customname' triggers). Command names must not start with '/' as the slash is
# automatically added when matching commands.
command: "example-value"
# Option 3: Command configuration object with custom command name
command:
# Name of the slash command that triggers the workflow (e.g., '/deploy', '/test').
# Used for command-based workflow activation.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Custom command name for slash commands (e.g., 'helper-bot' for
# '/helper-bot' triggers). Command names must not start with '/' as the slash is
# automatically added when matching commands. Defaults to workflow filename
# without .md extension if not specified.
name: "My Workflow"
# Option 2: Array of command names that trigger this workflow (e.g., ['cmd.add',
# 'cmd.remove'] for '/cmd.add' and '/cmd.remove' triggers). Each command name must
# not start with '/'.
name: []
# Array items: Command name without leading slash
# Events where the command should be active. Default is all comment-related events
# ('*'). Use GitHub Actions event names.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single event name or '*' for all events. Use GitHub Actions event
# names: 'issues', 'issue_comment', 'pull_request_comment', 'pull_request',
# 'pull_request_review_comment', 'discussion', 'discussion_comment'.
events: "*"
# Option 2: Array of event names where the command should be active (requires at
# least one). Use GitHub Actions event names.
events: []
# Array items: GitHub Actions event name.
# On Label Command trigger: fires when a specific label is added to an issue, pull
# request, or discussion. The triggering label is automatically removed at
# workflow start so it can be applied again to re-trigger. Use the 'events' field
# to restrict which item types (issues, pull_request, discussion) activate the
# trigger.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Label name as a string (shorthand format). The workflow fires when
# this label is added to any supported item type (issue, pull request, or
# discussion).
label_command: "example-value"
# Option 2: Label command configuration object with label name(s) and optional
# event filtering.
label_command:
# Label name(s) that trigger the workflow when added to an issue, pull request, or
# discussion.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single label name that acts as a command (e.g., 'deploy' triggers the
# workflow when the 'deploy' label is added).
name: "My Workflow"
# Option 2: Array of label names — any of these labels will trigger the workflow.
name: []
# Array items: A label name
# Alternative to 'name': label name(s) that trigger the workflow.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single label name.
names: "example-value"
# Option 2: Array of label names — any of these labels will trigger the workflow.
names: []
# Array items: A label name
# Item types where the label-command trigger should be active. Default is all
# supported types: issues, pull_request, discussion.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single item type or '*' for all types.
events: "*"
# Option 2: Array of item types where the trigger is active.
events: []
# Array items: Item type.
# Whether to automatically remove the triggering label after the workflow starts.
# Defaults to true. Set to false to keep the label on the item and skip the
# label-removal step. When false, the issues:write and discussions:write
# permissions required for label removal are also omitted.
# (optional)
remove_label: true
# Push event trigger that runs the workflow when code is pushed to the repository
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: undefined
# Option 2: undefined
# Option 3: undefined
# Pull request event trigger that runs the workflow when pull requests are
# created, updated, or closed
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: undefined
# Option 2: undefined
# Option 3: undefined
# Issues event trigger that runs when repository issues are created, updated, or
# managed
# (optional)
issues:
# Types of issue events
# (optional)
types: []
# Array of strings
# Array of issue type names that trigger the workflow. Filters workflow execution
# to specific issue categories.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single label name to filter labeled/unlabeled events (e.g., 'bug')
names: "example-value"
# Option 2: List of label names to filter labeled/unlabeled events. Only applies
# when 'labeled' or 'unlabeled' is in the types array
names: []
# Array items: Label name
# Whether to lock the issue for the agent when the workflow runs (prevents
# concurrent modifications)
# (optional)
lock-for-agent: true
# Issue comment event trigger
# (optional)
issue_comment:
# Types of issue comment events
# (optional)
types: []
# Array of strings
# Whether to lock the parent issue for the agent when the workflow runs (prevents
# concurrent modifications)
# (optional)
lock-for-agent: true
# Discussion event trigger that runs the workflow when repository discussions are
# created, updated, or managed
# (optional)
discussion:
# Types of discussion events
# (optional)
types: []
# Array of strings
# Discussion comment event trigger that runs the workflow when comments on
# discussions are created, updated, or deleted
# (optional)
discussion_comment:
# Types of discussion comment events
# (optional)
types: []
# Array of strings
# Scheduled trigger events using fuzzy schedules or standard cron expressions.
# Supports shorthand string notation (e.g., 'daily', 'daily around 2pm') or array
# of schedule objects. Fuzzy schedules automatically distribute execution times to
# prevent load spikes.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Shorthand schedule string using fuzzy or cron format. Examples:
# 'daily', 'daily around 14:00', 'daily between 9:00 and 17:00', 'weekly', 'weekly
# on monday', 'weekly on friday around 5pm', 'hourly', 'every 2h', 'every 10
# minutes', '0 9 * * 1'. Fuzzy schedules distribute execution times to prevent
# load spikes. For fixed times, use standard cron syntax. Minimum interval is 5
# minutes.
schedule: "example-value"
# Option 2: Array of schedule objects with cron expressions (standard cron or
# fuzzy format)
schedule: []
# Array items: object
# Manual workflow dispatch trigger
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple workflow dispatch trigger
workflow_dispatch: null
# Option 2: object
workflow_dispatch:
# Input parameters for manual dispatch
# (optional)
inputs:
{}
# Workflow run trigger
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: undefined
# Option 2: undefined
# Option 3: undefined
# Release event trigger
# (optional)
release:
# Types of release events
# (optional)
types: []
# Array of strings
# Pull request review comment event trigger
# (optional)
pull_request_review_comment:
# Types of pull request review comment events
# (optional)
types: []
# Array of strings
# Branch protection rule event trigger that runs when branch protection rules are
# changed
# (optional)
branch_protection_rule:
# Types of branch protection rule events
# (optional)
types: []
# Array of strings
# Check run event trigger that runs when a check run is created, rerequested,
# completed, or has a requested action
# (optional)
check_run:
# Types of check run events
# (optional)
types: []
# Array of strings
# Check suite event trigger that runs when check suite activity occurs
# (optional)
check_suite:
# Types of check suite events
# (optional)
types: []
# Array of strings
# Create event trigger that runs when a Git reference (branch or tag) is created
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple create event trigger
create: null
# Option 2: object
create:
{}
# Delete event trigger that runs when a Git reference (branch or tag) is deleted
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple delete event trigger
delete: null
# Option 2: object
delete:
{}
# Deployment event trigger that runs when a deployment is created
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple deployment event trigger
deployment: null
# Option 2: object
deployment:
{}
# Deployment status event trigger that runs when a deployment status is updated
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple deployment status event trigger
deployment_status: null
# Option 2: object
deployment_status:
{}
# Fork event trigger that runs when someone forks the repository
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple fork event trigger
fork: null
# Option 2: object
fork:
{}
# Gollum event trigger that runs when someone creates or updates a Wiki page
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple gollum event trigger
gollum: null
# Option 2: object
gollum:
{}
# Label event trigger that runs when a label is created, edited, or deleted
# (optional)
label:
# Types of label events
# (optional)
types: []
# Array of strings
# Merge group event trigger that runs when a pull request is added to a merge
# queue
# (optional)
merge_group:
# Types of merge group events
# (optional)
types: []
# Array of strings
# Milestone event trigger that runs when a milestone is created, closed, opened,
# edited, or deleted
# (optional)
milestone:
# Types of milestone events
# (optional)
types: []
# Array of strings
# Page build event trigger that runs when someone pushes to a GitHub Pages
# publishing source branch
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple page build event trigger
page_build: null
# Option 2: object
page_build:
{}
# Public event trigger that runs when a repository changes from private to public
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple public event trigger
public: null
# Option 2: object
public:
{}
# Pull request target event trigger that runs in the context of the base
# repository (secure for fork PRs)
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: undefined
# Option 2: undefined
# Option 3: undefined
# Pull request review event trigger that runs when a pull request review is
# submitted, edited, or dismissed
# (optional)
pull_request_review:
# Types of pull request review events
# (optional)
types: []
# Array of strings
# Registry package event trigger that runs when a package is published or updated
# (optional)
registry_package:
# Types of registry package events
# (optional)
types: []
# Array of strings
# Repository dispatch event trigger for custom webhook events
# (optional)
repository_dispatch:
# Custom event types to trigger on
# (optional)
types: []
# Array of strings
# Status event trigger that runs when the status of a Git commit changes
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple status event trigger
status: null
# Option 2: object
status:
{}
# Watch event trigger that runs when someone stars the repository
# (optional)
watch:
# Types of watch events
# (optional)
types: []
# Array of strings
# Workflow call event trigger that allows this workflow to be called by another
# workflow
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple workflow call event trigger
workflow_call: null
# Option 2: object
workflow_call:
# Input parameters that can be passed to the workflow when it is called
# (optional)
inputs:
{}
# Secrets that can be passed to the workflow when it is called
# (optional)
secrets:
{}
# Time when workflow should stop running. Supports multiple formats: absolute
# dates (YYYY-MM-DD HH:MM:SS, June 1 2025, 1st June 2025, 06/01/2025, etc.) or
# relative time deltas (+25h, +3d, +1d12h30m). Maximum values for time deltas:
# 12mo, 52w, 365d, 8760h (365 days). Note: Minute unit 'm' is not allowed for
# stop-after; minimum unit is hours 'h'.
# (optional)
stop-after: "example-value"
# Conditionally skip workflow execution when a GitHub search query has matches.
# Can be a string (query only, implies max=1) or an object with 'query', optional
# 'max', and 'scope' fields. Use top-level on.github-token or on.github-app for
# custom authentication.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: GitHub search query string to check before running workflow (implies
# max=1). If the search returns any results, the workflow will be skipped. Query
# is automatically scoped to the current repository. Example: 'is:issue is:open
# label:bug'
skip-if-match: "example-value"
# Option 2: Skip-if-match configuration object with query, maximum match count,
# and optional scope. For custom authentication use the top-level on.github-token
# or on.github-app fields.
skip-if-match:
# GitHub search query string to check before running workflow. Query is
# automatically scoped to the current repository.
query: "example-value"
# Maximum number of items that must be matched for the workflow to be skipped.
# Defaults to 1 if not specified. Supports integer or GitHub Actions expression
# (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Scope for the search query. Set to 'none' to disable the automatic
# 'repo:owner/repo' scoping, enabling org-wide or cross-repo queries.
# (optional)
scope: "none"
# Conditionally skip workflow execution when a GitHub search query has no matches
# (or fewer than minimum). Can be a string (query only, implies min=1) or an
# object with 'query', optional 'min', and 'scope' fields. Use top-level
# on.github-token or on.github-app for custom authentication.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: GitHub search query string to check before running workflow (implies
# min=1). If the search returns no results, the workflow will be skipped. Query is
# automatically scoped to the current repository. Example: 'is:pr is:open
# label:ready-to-deploy'
skip-if-no-match: "example-value"
# Option 2: Skip-if-no-match configuration object with query, minimum match count,
# and optional scope. For custom authentication use the top-level on.github-token
# or on.github-app fields.
skip-if-no-match:
# GitHub search query string to check before running workflow. Query is
# automatically scoped to the current repository.
query: "example-value"
# Minimum number of items that must be matched for the workflow to proceed.
# Defaults to 1 if not specified.
# (optional)
min: 1
# Scope for the search query. Set to 'none' to disable the automatic
# 'repo:owner/repo' scoping, enabling org-wide or cross-repo queries.
# (optional)
scope: "none"
# Skip workflow execution if any CI checks on the target branch are failing or
# pending. Accepts true (check all) or an object to filter specific checks by name
# and optionally specify a branch or allow pending checks.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Bare key with no value — equivalent to true. Skips workflow execution
# if any CI checks on the target branch are currently failing.
skip-if-check-failing: null
# Option 2: Skip workflow execution if any CI checks on the target branch are
# currently failing. For pull_request events, checks the base branch. For other
# events, checks the current ref.
skip-if-check-failing: true
# Option 3: Skip-if-check-failing configuration object with optional
# include/exclude filter lists, an optional branch name, and an allow-pending
# flag.
skip-if-check-failing:
# List of check names to evaluate. When specified, only these named checks are
# considered. If omitted, all checks are evaluated.
# (optional)
include: []
# Array of strings
# List of check names to ignore. Checks in this list are not considered when
# determining whether to skip the workflow.
# (optional)
exclude: []
# Array of strings
# Branch name to check for failing CI checks. When omitted, defaults to the base
# branch of a pull_request event or the current ref for other events.
# (optional)
branch: "example-value"
# When true, pending or in-progress checks are not treated as failing. By default
# (false), any check that has not yet completed is treated as failing and will
# block the workflow.
# (optional)
allow-pending: true
# Skip workflow execution for users with specific repository roles. Useful for
# workflows that should only run for external contributors or specific permission
# levels.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single role to skip workflow for (e.g., 'admin'). If the triggering
# user has this role, the workflow will be skipped.
skip-roles: "example-value"
# Option 2: List of roles to skip workflow for (e.g., ['admin', 'maintainer',
# 'write']). If the triggering user has any of these roles, the workflow will be
# skipped.
skip-roles: []
# Array items: string
# Skip workflow execution for specific GitHub users. Useful for preventing
# workflows from running for specific accounts (e.g., bots, specific team
# members).
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single GitHub username to skip workflow for (e.g., 'user1'). If the
# triggering user matches, the workflow will be skipped.
skip-bots: "example-value"
# Option 2: List of GitHub usernames to skip workflow for (e.g., ['user1',
# 'user2']). If the triggering user is in this list, the workflow will be skipped.
skip-bots: []
# Array items: string
# Repository access roles required to trigger agentic workflows. Defaults to
# ['admin', 'maintainer', 'write'] for security. Use 'all' to allow any
# authenticated user (! security consideration).
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Allow any authenticated user to trigger the workflow (! disables
# permission checking entirely - use with caution)
roles: "all"
# Option 2: List of repository permission levels that can trigger the workflow.
# Permission checks are automatically applied to potentially unsafe triggers.
roles: []
# Array items: Repository permission level: 'admin' (full access),
# 'maintainer'/'maintain' (repository management), 'write' (push access), 'triage'
# (issue management), 'read' (read-only access)
# Allow list of bot identifiers that can trigger the workflow even if they don't
# meet the required role permissions. When the actor is in this list, the bot must
# be active (installed) on the repository to trigger the workflow.
# (optional)
bots: []
# Array of Bot identifier/name (e.g., 'dependabot[bot]', 'renovate[bot]',
# 'github-actions[bot]')
# Environment name that requires manual approval before the workflow can run. Must
# match a valid environment configured in the repository settings.
# (optional)
manual-approval: "example-value"
# AI reaction to add/remove on triggering item (one of: +1, -1, laugh, confused,
# heart, hooray, rocket, eyes, none). Use 'none' to disable reactions. Defaults to
# 'eyes' if not specified.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: string
reaction: "+1"
# Option 2: YAML parses +1 and -1 without quotes as integers. These are converted
# to +1 and -1 strings respectively.
reaction: 1
# Whether to post status comments (started/completed) on the triggering item. When
# true, adds a comment with workflow run link and updates it on completion. When
# false or not specified, no status comments are posted. Must be explicitly set to
# true to enable status comments - there is no automatic bundling with
# ai-reaction.
# (optional)
status-comment: true
# Custom GitHub token for pre-activation reactions, activation status comments,
# and skip-if search queries. When specified, overrides the default GITHUB_TOKEN
# for these operations.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# GitHub App configuration for minting a token used in pre-activation reactions,
# activation status comments, and skip-if search queries. When configured, a
# single GitHub App installation access token is minted and shared across all
# these operations instead of using the default GITHUB_TOKEN. Can be defined in a
# shared agentic workflow and inherited by importing workflows.
# (optional)
github-app:
# GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.
app-id: "example-value"
# GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to
# mint a GitHub App token.
private-key: "example-value"
# Optional owner of the GitHub App installation (defaults to current repository
# owner if not specified)
# (optional)
owner: "example-value"
# Optional list of repositories to grant access to (defaults to current repository
# if not specified)
# (optional)
repositories: []
# Array of strings
# Optional extra GitHub App-only permissions to merge into the minted token. Only
# takes effect for tools.github.github-app; ignored in other github-app contexts.
# (optional)
permissions:
# Permission level for repository administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission for repository administration.
# (optional)
administration: "read"
# Permission level for Codespaces (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces: "read"
# Permission level for Codespaces lifecycle administration (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
codespaces-lifecycle-admin: "read"
# Permission level for Codespaces metadata (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces-metadata: "read"
# Permission level for user email addresses (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
email-addresses: "read"
# Permission level for repository environments (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
environments: "read"
# Permission level for git signing (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
git-signing: "read"
# Permission level for organization members (read/none; "write" is rejected by the
# compiler). Required for org team membership API calls.
# (optional)
members: "read"
# Permission level for organization administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-administration: "read"
# Permission level for organization announcement banners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-announcement-banners: "read"
# Permission level for organization Codespaces (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-codespaces: "read"
# Permission level for organization Copilot (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-copilot: "read"
# Permission level for organization custom org roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-org-roles: "read"
# Permission level for organization custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-properties: "read"
# Permission level for organization custom repository roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-repository-roles: "read"
# Permission level for organization events (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-events: "read"
# Permission level for organization webhooks (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-hooks: "read"
# Permission level for organization members management (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-members: "read"
# Permission level for organization packages (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-packages: "read"
# Permission level for organization personal access token requests (read/none;
# "write" is rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-token-requests: "read"
# Permission level for organization personal access tokens (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-tokens: "read"
# Permission level for organization plan (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-plan: "read"
# Permission level for organization self-hosted runners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-self-hosted-runners: "read"
# Permission level for organization user blocking (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-user-blocking: "read"
# Permission level for repository custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
repository-custom-properties: "read"
# Permission level for repository webhooks (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
repository-hooks: "read"
# Permission level for single file access (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
single-file: "read"
# Permission level for team discussions (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
team-discussions: "read"
# Permission level for Dependabot vulnerability alerts (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
vulnerability-alerts: "read"
# Permission level for GitHub Actions workflow files (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
workflows: "read"
# Steps to inject into the pre-activation job. These steps run after all built-in
# checks (membership, stop-time, skip-if, etc.) and their results are exposed as
# pre-activation outputs. Use 'id' on steps to reference their results via
# needs.pre_activation.outputs._result.
# (optional)
steps: []
# Array items:
# Optional name for the step
# (optional)
name: "My Workflow"
# Optional step ID. When set, the step result is exposed as
# needs.pre_activation.outputs._result
# (optional)
id: "example-value"
# Shell command to run
# (optional)
run: "example-value"
# Action to use (e.g., 'actions/checkout@v4')
# (optional)
uses: "example-value"
# Input parameters for the action
# (optional)
with:
{}
# Environment variables for the step
# (optional)
env:
{}
# Conditional expression for the step
# (optional)
if: "example-value"
# Whether to continue if the step fails
# (optional)
continue-on-error: true
# Additional permissions for the pre-activation job. Use to declare extra scopes
# required by on.steps (e.g., issues: read for GitHub API calls in steps).
# (optional)
# Map of permission scope to level
# (optional)
permissions:
# (optional)
actions: "read"
# (optional)
checks: "read"
# (optional)
contents: "read"
# (optional)
deployments: "read"
# (optional)
discussions: "read"
# (optional)
issues: "read"
# (optional)
packages: "read"
# (optional)
pages: "read"
# (optional)
pull-requests: "read"
# (optional)
repository-projects: "read"
# (optional)
security-events: "read"
# (optional)
statuses: "read"
# When set to false, disables the frontmatter hash check step in the activation
# job. Default is true (check is enabled). Useful when the workflow source files
# are managed outside the default GitHub repo context (e.g. cross-repo org
# rulesets) and the stale check is not needed.
# (optional)
stale-check: true
# GitHub token permissions for the workflow. Controls what the GITHUB_TOKEN can
# access during execution. Use the principle of least privilege - only grant the
# minimum permissions needed.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple permissions string: 'read-all' (all read permissions) or
# 'write-all' (all write permissions)
permissions: "read-all"
# Option 2: undefined
# Custom name for workflow runs that appears in the GitHub Actions interface
# (supports GitHub expressions like ${{ github.event.issue.title }})
# (optional)
run-name: "example-value"
# Groups together all the jobs that run in the workflow
# (optional)
jobs:
{}
# Runner type for workflow execution (GitHub Actions standard field). Supports
# multiple forms: simple string for single runner label (e.g., 'ubuntu-latest'),
# array for runner selection with fallbacks, or object for GitHub-hosted runner
# groups with specific labels. For agentic workflows, runner selection matters
# when AI workloads require specific compute resources or when using self-hosted
# runners with specialized capabilities. Typically configured at the job level
# instead. See
# https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple runner label string. Use for standard GitHub-hosted runners
# (e.g., 'ubuntu-latest', 'windows-latest', 'macos-latest') or self-hosted runner
# labels. Most common form for agentic workflows.
runs-on: "example-value"
# Option 2: Array of runner labels for selection with fallbacks. GitHub Actions
# will use the first available runner that matches any label in the array. Useful
# for high-availability setups or when multiple runner types are acceptable.
runs-on: []
# Array items: string
# Option 3: Runner group configuration for GitHub-hosted runners. Use this form to
# target specific runner groups (e.g., larger runners with more CPU/memory) or
# self-hosted runner pools with specific label requirements. Agentic workflows may
# benefit from larger runners for complex AI processing tasks.
runs-on:
# Runner group name for self-hosted runners or GitHub-hosted runner groups
# (optional)
group: "example-value"
# List of runner labels for self-hosted runners or GitHub-hosted runner selection
# (optional)
labels: []
# Array of strings
# Runner for all framework/generated jobs (activation, pre-activation,
# safe-outputs, unlock, APM, etc.). Provides a compile-stable override for
# generated job runners without requiring a safe-outputs section. Overridden by
# safe-outputs.runs-on when both are set. Defaults to 'ubuntu-slim'. Use this when
# your infrastructure does not provide the default runner or when you need
# consistent runner selection across all jobs.
# (optional)
runs-on-slim: "example-value"
# Workflow timeout in minutes (GitHub Actions standard field). Defaults to 20
# minutes for agentic workflows. Has sensible defaults and can typically be
# omitted. Supports GitHub Actions expressions (e.g. '${{ inputs.timeout }}') for
# reusable workflow_call workflows.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
timeout-minutes: 1
# Option 2: GitHub Actions expression that resolves to an integer (e.g. '${{
# inputs.timeout }}')
timeout-minutes: "example-value"
# Concurrency control to limit concurrent workflow runs (GitHub Actions standard
# field). Supports two forms: simple string for basic group isolation, or object
# with cancel-in-progress option for advanced control. Agentic workflows enhance
# this with automatic per-engine concurrency policies (defaults to single job per
# engine across all workflows) and token-based rate limiting. Default behavior:
# workflows in the same group queue sequentially unless cancel-in-progress is
# true. See https://docs.github.com/en/actions/using-jobs/using-concurrency
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple concurrency group name to prevent multiple runs in the same
# group. Use expressions like '${{ github.workflow }}' for per-workflow isolation
# or '${{ github.ref }}' for per-branch isolation. Agentic workflows automatically
# generate enhanced concurrency policies using 'gh-aw-{engine-id}' as the default
# group to limit concurrent AI workloads across all workflows using the same
# engine.
concurrency: "example-value"
# Option 2: Concurrency configuration object with group isolation and cancellation
# control. Use object form when you need fine-grained control over whether to
# cancel in-progress runs. For agentic workflows, this is useful to prevent
# multiple AI agents from running simultaneously and consuming excessive resources
# or API quotas.
concurrency:
# Concurrency group name. Workflows in the same group cannot run simultaneously.
# Supports GitHub Actions expressions for dynamic group names based on branch,
# workflow, or other context.
# (optional)
group: "example-value"
# Whether to cancel in-progress workflows in the same concurrency group when a new
# one starts. Default: false (queue new runs). Set to true for agentic workflows
# where only the latest run matters (e.g., PR analysis that becomes stale when new
# commits are pushed).
# (optional)
cancel-in-progress: true
# Additional discriminator expression appended to compiler-generated job-level
# concurrency groups (agent, output jobs). Use this when multiple workflow
# instances are dispatched concurrently with different inputs (fan-out pattern) to
# prevent job-level concurrency groups from colliding. For example, '${{
# inputs.finding_id }}' ensures each dispatched run gets a unique job-level group.
# Supports GitHub Actions expressions. This field is stripped from the compiled
# lock file (it is a gh-aw extension, not a GitHub Actions field).
# (optional)
job-discriminator: "example-value"
# Environment variables for the workflow
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: object
env:
{}
# Option 2: string
env: "example-value"
# Feature flags and configuration options for experimental or optional features in
# the workflow. Each feature can be a boolean flag or a string value. The
# 'action-tag' feature (string) specifies the tag or SHA to use when referencing
# actions/setup in compiled workflows (for testing purposes only).
# (optional)
features:
{}
# DEPRECATED: Use 'disable-model-invocation' instead. Controls whether the custom
# agent should infer additional context from the conversation. This field is
# maintained for backward compatibility with existing custom agent files.
# (optional)
infer: true
# Controls whether the custom agent should disable model invocation. When set to
# true, the agent will not make additional model calls. This is the preferred
# field name for custom agent files (replaces the deprecated 'infer' field).
# (optional)
disable-model-invocation: true
# Secret values passed to workflow execution. Secrets can be defined as simple
# strings (GitHub Actions expressions) or objects with 'value' and 'description'
# properties. Typically used to provide secrets to MCP servers or custom engines.
# Note: For passing secrets to reusable workflows, use the jobs..secrets
# field instead.
# (optional)
secrets:
{}
# Environment that the job references (for protected environments and deployments)
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Environment name as a string
environment: "example-value"
# Option 2: Environment object with name and optional URL
environment:
# The name of the environment configured in the repo
name: "My Workflow"
# A deployment URL
# (optional)
url: "example-value"
# Container to run the job steps in
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Docker image name (e.g., 'node:18', 'ubuntu:latest')
container: "example-value"
# Option 2: Container configuration object
container:
# The Docker image to use as the container
image: "example-value"
# Credentials for private registries
# (optional)
credentials:
# Username for Docker registry authentication when pulling private container
# images.
# (optional)
username: "example-value"
# Password or access token for Docker registry authentication. Should use secrets
# syntax: ${{ secrets.DOCKER_PASSWORD }}
# (optional)
password: "example-value"
# Environment variables for the container
# (optional)
env:
{}
# Ports to expose on the container
# (optional)
ports: []
# Volumes for the container
# (optional)
volumes: []
# Array of strings
# Additional Docker container options
# (optional)
options: "example-value"
# Service containers for the job
# (optional)
services:
{}
# Network access control for AI engines using ecosystem identifiers and domain
# allowlists. Supports wildcard patterns like '*.example.com' to match any
# subdomain. Controls web fetch and search capabilities. IMPORTANT: For workflows
# that build/install/test code, always include the language ecosystem identifier
# alongside 'defaults' — 'defaults' alone only covers basic infrastructure, not
# package registries. Key ecosystem identifiers by runtime: 'dotnet' (.NET/NuGet),
# 'python' (pip/PyPI), 'node' (npm/yarn), 'go' (go modules), 'java'
# (Maven/Gradle), 'ruby' (Bundler), 'rust' (Cargo), 'swift' (Swift PM). Example: a
# .NET project needs network: { allowed: [defaults, dotnet] }.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Use default network permissions (basic infrastructure: certificates,
# JSON schema, Ubuntu, etc.)
network: "defaults"
# Option 2: Custom network access configuration with ecosystem identifiers and
# specific domains
network:
# List of allowed domains or ecosystem identifiers (e.g., 'defaults', 'python',
# 'node', '*.example.com'). Wildcard patterns match any subdomain AND the base
# domain.
# (optional)
allowed: []
# Array of Domain name or ecosystem identifier. Supports wildcards like
# '*.example.com' (matches sub.example.com, deep.nested.example.com, and
# example.com itself). Ecosystem identifiers by runtime: 'dotnet' (.NET/NuGet),
# 'python' (pip/PyPI), 'node' (npm/yarn), 'go' (go modules), 'java'
# (Maven/Gradle), 'ruby' (RubyGems), 'rust' (Cargo), 'swift' (Swift PM), 'php'
# (Composer), 'dart' (pub.dev), 'haskell' (Hackage), 'perl' (CPAN), 'containers'
# (Docker/GHCR), 'github' (GitHub domains), 'terraform' (HashiCorp),
# 'linux-distros' (apt/yum), 'playwright' (browser testing), 'defaults' (basic
# infrastructure).
# List of blocked domains or ecosystem identifiers (e.g., 'python', 'node',
# 'tracker.example.com'). Blocked domains take precedence over allowed domains.
# (optional)
blocked: []
# Array of Domain name or ecosystem identifier to block. Supports wildcards like
# '*.example.com' (matches sub.example.com, deep.nested.example.com, and
# example.com itself) and ecosystem names like 'python', 'node'.
# Sandbox configuration for AI engines. Controls agent sandbox (AWF) and MCP
# gateway. The MCP gateway is always enabled and cannot be disabled.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: String format for sandbox type: 'default' for no sandbox, 'awf' for
# Agent Workflow Firewall. Note: Legacy 'srt' and 'sandbox-runtime' values are
# automatically migrated to 'awf'
sandbox: "default"
# Option 2: Object format for full sandbox configuration with agent and mcp
# options
sandbox:
# Legacy sandbox type field (use agent instead). Note: Legacy 'srt' and
# 'sandbox-runtime' values are automatically migrated to 'awf'
# (optional)
type: "default"
# Agent sandbox type: 'awf' uses AWF (Agent Workflow Firewall), or false to
# disable agent sandbox. Defaults to 'awf' if not specified. Note: Disabling the
# agent sandbox (false) removes firewall protection but keeps the MCP gateway
# enabled.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Set to false to disable the agent sandbox (firewall). Warning: This
# removes firewall protection but keeps the MCP gateway enabled. Not allowed in
# strict mode.
agent: true
# Option 2: Sandbox type: 'awf' for Agent Workflow Firewall
agent: "awf"
# Option 3: Custom sandbox runtime configuration
agent:
# Agent identifier (replaces 'type' field in new format): 'awf' for Agent Workflow
# Firewall
# (optional)
id: "awf"
# Legacy: Sandbox type to use (use 'id' instead)
# (optional)
type: "awf"
# Container mounts to add when using AWF. Each mount is specified using Docker
# mount syntax: 'source:destination:mode' where mode can be 'ro' (read-only) or
# 'rw' (read-write). Example: '/host/path:/container/path:ro'
# (optional)
mounts: []
# Array of Mount specification in format 'source:destination:mode'
# Memory limit for the AWF container (e.g., '4g', '8g'). Passed as --memory-limit
# to AWF. If not specified, AWF's default memory limit of 6g is used.
# (optional)
memory: "example-value"
# Custom sandbox runtime configuration. Note: Network configuration is controlled
# by the top-level 'network' field, not here.
# (optional)
config:
# Filesystem access control configuration for the agent within the sandbox.
# Controls read/write permissions and path restrictions.
# (optional)
filesystem:
# List of paths to deny read access
# (optional)
denyRead: []
# Array of strings
# List of paths to allow write access
# (optional)
allowWrite: []
# Array of strings
# List of paths to deny write access
# (optional)
denyWrite: []
# Array of strings
# Map of command patterns to paths that should ignore violations
# (optional)
ignoreViolations:
{}
# Enable weaker nested sandbox mode (recommended: true for Docker access)
# (optional)
enableWeakerNestedSandbox: true
# Legacy custom Sandbox Runtime configuration (use agent.config instead). Note:
# Network configuration is controlled by the top-level 'network' field, not here.
# (optional)
config:
# Filesystem access control configuration for sandboxed workflows. Controls
# read/write permissions and path restrictions for file operations.
# (optional)
filesystem:
# Array of path patterns that deny read access in the sandboxed environment. Takes
# precedence over other read permissions.
# (optional)
denyRead: []
# Array of strings
# Array of path patterns that allow write access in the sandboxed environment.
# Paths outside these patterns are read-only.
# (optional)
allowWrite: []
# Array of strings
# Array of path patterns that deny write access in the sandboxed environment.
# Takes precedence over other write permissions.
# (optional)
denyWrite: []
# Array of strings
# When true, log sandbox violations without blocking execution. Useful for
# debugging and gradual enforcement of sandbox policies.
# (optional)
ignoreViolations:
{}
# When true, allows nested sandbox processes to run with relaxed restrictions.
# Required for certain containerized tools that spawn subprocesses.
# (optional)
enableWeakerNestedSandbox: true
# MCP Gateway configuration for routing MCP server calls through a unified HTTP
# gateway. Requires the 'mcp-gateway' feature flag to be enabled. Per MCP Gateway
# Specification v1.0.0: Only container-based execution is supported.
# (optional)
mcp:
# Volume mounts for the MCP gateway container. Each mount is specified using
# Docker mount syntax: 'source:destination:mode' where mode can be 'ro'
# (read-only) or 'rw' (read-write). Example: '/host/data:/container/data:ro'
# (optional)
mounts: []
# Array of Mount specification in format 'source:destination:mode'
# Environment variables for MCP gateway
# (optional)
env:
{}
# Port number for the MCP gateway HTTP server (default: 8080)
# (optional)
port: 1
# API key for authenticating with the MCP gateway (supports ${{ secrets.* }}
# syntax)
# (optional)
api-key: "example-value"
# Gateway domain for URL generation (default: 'host.docker.internal' when agent is
# enabled, 'localhost' when disabled)
# (optional)
domain: "localhost"
# Conditional execution expression
# (optional)
if: "example-value"
# Custom workflow steps
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: object
steps:
{}
# Option 2: array
steps: []
# Array items: undefined
# Custom workflow steps to run after AI execution
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: object
post-steps:
{}
# Option 2: array
post-steps: []
# Array items: undefined
# AI engine configuration that specifies which AI processor interprets and
# executes the markdown content of the workflow. Defaults to 'copilot'.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Engine name: built-in ('claude', 'codex', 'copilot', 'gemini') or a
# named catalog entry
engine: "example-value"
# Option 2: Extended engine configuration object with advanced options for model
# selection, turn limiting, environment variables, and custom steps
engine:
# AI engine identifier: built-in ('claude', 'codex', 'copilot', 'gemini') or a
# named catalog entry
id: "example-value"
# Optional version of the AI engine action (e.g., 'beta', 'stable', 20). Has
# sensible defaults and can typically be omitted. Numeric values are automatically
# converted to strings at runtime. GitHub Actions expressions (e.g., '${{
# inputs.engine-version }}') are accepted and compiled with injection-safe env var
# handling.
# (optional)
version: null
# Optional specific LLM model to use (e.g., 'claude-3-5-sonnet-20241022',
# 'gpt-4'). Has sensible defaults and can typically be omitted.
# (optional)
model: "example-value"
# Maximum number of chat iterations per run. Helps prevent runaway loops and
# control costs. Has sensible defaults and can typically be omitted. Note: Only
# supported by the claude engine.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Maximum number of chat iterations per run as an integer value
max-turns: 1
# Option 2: Maximum number of chat iterations per run as a string value
max-turns: "example-value"
# Maximum number of continuations for multi-run autopilot mode. Default is 1
# (single run, no autopilot). Values greater than 1 enable --autopilot mode for
# the copilot engine with --max-autopilot-continues set to this value. Note: Only
# supported by the copilot engine.
# (optional)
max-continuations: 1
# Agent job concurrency configuration. Defaults to single job per engine across
# all workflows (group: 'gh-aw-{engine-id}'). Supports full GitHub Actions
# concurrency syntax.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple concurrency group name. Gets converted to GitHub Actions
# concurrency format with the specified group.
concurrency: "example-value"
# Option 2: GitHub Actions concurrency configuration for the agent job. Controls
# how many agentic workflow runs can run concurrently.
concurrency:
# Concurrency group identifier. Use GitHub Actions expressions like ${{
# github.workflow }} or ${{ github.ref }}. Defaults to 'gh-aw-{engine-id}' if not
# specified.
group: "example-value"
# Whether to cancel in-progress runs of the same concurrency group. Defaults to
# false for agentic workflow runs.
# (optional)
cancel-in-progress: true
# Custom user agent string for GitHub MCP server configuration (codex engine only)
# (optional)
user-agent: "example-value"
# Custom executable path for the AI engine CLI. When specified, the workflow will
# skip the standard installation steps and use this command instead. The command
# should be the full path to the executable or a command available in PATH.
# (optional)
command: "example-value"
# Custom environment variables to pass to the AI engine, including secret
# overrides (e.g., OPENAI_API_KEY: ${{ secrets.CUSTOM_KEY }})
# (optional)
env:
{}
# Additional TOML configuration text that will be appended to the generated
# config.toml in the action (codex engine only)
# (optional)
config: "example-value"
# Agent identifier to pass to copilot --agent flag (copilot engine only).
# Specifies which custom agent to use for the workflow.
# (optional)
agent: "example-value"
# Custom API endpoint hostname for the agentic engine. Used for GitHub Enterprise
# Cloud (GHEC), GitHub Enterprise Server (GHES), or custom AI endpoints. Example:
# 'api.acme.ghe.com' for GHEC, 'api.enterprise.githubcopilot.com' for GHES, or
# custom endpoint hostnames.
# (optional)
api-target: "example-value"
# Optional array of command-line arguments to pass to the AI engine CLI. These
# arguments are injected after all other args but before the prompt.
# (optional)
args: []
# Array of strings
# Custom model token weights for effective token computation. Overrides or
# extends the built-in model multipliers from model_multipliers.json. Useful
# for custom models or adjusted cost ratios.
# (optional)
token-weights:
# Per-model cost multipliers relative to the reference model
# (claude-sonnet-4.5 = 1.0). Keys are model names (case-insensitive,
# prefix matching supported).
# (optional)
multipliers:
my-custom-model: 2.5
# Per-token-class weights applied before the model multiplier. Defaults:
# input: 1.0, cached-input: 0.1, output: 4.0, reasoning: 4.0,
# cache-write: 1.0
# (optional)
token-class-weights:
input: 1.0
cached-input: 0.1
output: 4.0
reasoning: 4.0
cache-write: 1.0
# Option 3: Inline engine definition: specifies a runtime adapter and optional
# provider settings directly in the workflow frontmatter, without requiring a
# named catalog entry
engine:
# Runtime adapter reference for the inline engine definition
runtime:
# Runtime adapter identifier (e.g. 'codex', 'claude', 'copilot', 'gemini')
id: "example-value"
# Optional version of the runtime adapter (e.g. '0.105.0', 'beta')
# (optional)
version: null
# Optional provider configuration for the inline engine definition
# (optional)
provider:
# Provider identifier (e.g. 'openai', 'anthropic', 'github', 'google')
# (optional)
id: "example-value"
# Optional specific LLM model to use (e.g. 'gpt-5', 'claude-3-5-sonnet-20241022')
# (optional)
model: "example-value"
# Authentication configuration for the provider
# (optional)
auth:
# Name of the GitHub Actions secret that contains the API key for this provider
# (optional)
secret: "example-value"
# Authentication strategy for the provider (default: api-key when secret is set)
# (optional)
strategy: "api-key"
# OAuth 2.0 token endpoint URL. Required when strategy is
# 'oauth-client-credentials'.
# (optional)
token-url: "example-value"
# GitHub Actions secret name that holds the OAuth client ID. Required when
# strategy is 'oauth-client-credentials'.
# (optional)
client-id: "example-value"
# GitHub Actions secret name that holds the OAuth client secret. Required when
# strategy is 'oauth-client-credentials'.
# (optional)
client-secret: "example-value"
# JSON field name in the token response that contains the access token. Defaults
# to 'access_token'.
# (optional)
token-field: "example-value"
# HTTP header name to inject the API key or token into (e.g. 'api-key',
# 'x-api-key'). Required when strategy is not 'bearer'.
# (optional)
header-name: "example-value"
# Request shaping configuration for non-standard provider URL and body
# transformations
# (optional)
request:
# URL path template with {model} and other variable placeholders (e.g.
# '/openai/deployments/{model}/chat/completions')
# (optional)
path-template: "example-value"
# Static or template query-parameter values appended to every request
# (optional)
query:
{}
# Key/value pairs injected into the JSON request body before sending
# (optional)
body-inject:
{}
# Option 4: Engine definition: full declarative metadata for a named engine entry
# (used in builtin engine shared workflow files such as @builtin:engines/*.md)
engine:
# Unique engine identifier (e.g. 'copilot', 'claude', 'codex', 'gemini')
id: "example-value"
# Human-readable display name for the engine
display-name: "example-value"
# Human-readable description of the engine
# (optional)
description: "Description of the workflow"
# Runtime adapter identifier. Maps to the CodingAgentEngine registered in the
# engine registry. Defaults to id when omitted.
# (optional)
runtime-id: "example-value"
# Provider metadata for the engine
# (optional)
provider:
# Provider name (e.g. 'anthropic', 'github', 'google', 'openai')
# (optional)
name: "My Workflow"
# Default authentication configuration for the provider
# (optional)
auth:
# Name of the GitHub Actions secret that contains the API key
# (optional)
secret: "example-value"
# Authentication strategy
# (optional)
strategy: "api-key"
# OAuth 2.0 token endpoint URL
# (optional)
token-url: "example-value"
# GitHub Actions secret name for the OAuth client ID
# (optional)
client-id: "example-value"
# GitHub Actions secret name for the OAuth client secret
# (optional)
client-secret: "example-value"
# JSON field name in the token response containing the access token
# (optional)
token-field: "example-value"
# HTTP header name to inject the API key or token into
# (optional)
header-name: "example-value"
# Request shaping configuration
# (optional)
request:
# URL path template with variable placeholders
# (optional)
path-template: "example-value"
# Static query parameters
# (optional)
query:
{}
# Key/value pairs injected into the JSON request body
# (optional)
body-inject:
{}
# Model selection configuration for the engine
# (optional)
models:
# Default model identifier
# (optional)
default: "example-value"
# List of supported model identifiers
# (optional)
supported: []
# Array of strings
# Authentication bindings — maps logical roles (e.g. 'api-key') to GitHub Actions
# secret names
# (optional)
auth: []
# Array items:
# Logical authentication role (e.g. 'api-key', 'token')
role: "example-value"
# Name of the GitHub Actions secret that provides credentials for this role
secret: "example-value"
# Additional engine-specific options
# (optional)
options:
{}
# MCP server definitions
# (optional)
mcp-servers:
{}
# Tools and MCP (Model Context Protocol) servers available to the AI engine for
# GitHub API access, browser automation, file editing, and more
# (optional)
tools:
# GitHub API tools for repository operations (issues, pull requests, content
# management)
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Empty GitHub tool configuration (enables all read-only GitHub API
# functions)
github: null
# Option 2: Boolean to explicitly enable (true) or disable (false) the GitHub MCP
# server. When set to false, the GitHub MCP server is not mounted.
github: true
# Option 3: Simple GitHub tool configuration (enables all GitHub API functions)
github: "example-value"
# Option 4: GitHub tools object configuration with restricted function access
github:
# List of allowed GitHub API functions (e.g., 'create_issue', 'update_issue',
# 'add_comment')
# (optional)
allowed: []
# Array of strings
# MCP server mode: 'local' (Docker-based, default) or 'remote' (hosted at
# api.githubcopilot.com)
# (optional)
mode: "local"
# Optional version specification for the GitHub MCP server (used with 'local'
# type). Can be a string (e.g., 'v1.0.0', 'latest') or number (e.g., 20, 3.11).
# Numeric values are automatically converted to strings at runtime.
# (optional)
version: null
# Optional additional arguments to append to the generated MCP server command
# (used with 'local' type)
# (optional)
args: []
# Array of strings
# Enable read-only mode to restrict GitHub MCP server to read-only operations only
# (optional)
read-only: true
# Enable lockdown mode to limit content surfaced from public repositories (only
# items authored by users with push access). Default: false
# (optional)
lockdown: true
# Controls DIFC proxy injection for pre-agent gh CLI steps when guard policies
# (min-integrity) are configured. Default: true (enabled). Set to false to disable
# proxy injection and rely solely on MCP gateway-level filtering.
# (optional)
integrity-proxy: true
# Optional custom GitHub token (e.g., '${{ secrets.CUSTOM_PAT }}'). For 'remote'
# type, defaults to GH_AW_GITHUB_TOKEN if not specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Array of GitHub MCP server toolset names to enable specific groups of GitHub API
# functionalities
# (optional)
toolsets: []
# Array of Toolset name
# Volume mounts for the containerized GitHub MCP server (format:
# 'host:container:mode' where mode is 'ro' for read-only or 'rw' for read-write).
# Applies to local mode only. Example: '/data:/data:ro'
# (optional)
mounts: []
# Array of Mount specification in format 'host:container:mode'
# Guard policy: repository access configuration. Restricts which repositories the
# agent can access. Use 'all' to allow all repos, 'public' for public repositories
# only, or an array of repository patterns (e.g., 'owner/repo', 'owner/*',
# 'owner/prefix*').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Allow access to all repositories ('all') or only public repositories
# ('public')
allowed-repos: "all"
# Option 2: Allow access to specific repositories using patterns (e.g.,
# 'owner/repo', 'owner/*', 'owner/prefix*')
allowed-repos: []
# Array items: Repository pattern in the format 'owner/repo', 'owner/*' (all repos
# under owner), or 'owner/prefix*' (repos with name prefix)
# Guard policy: minimum required integrity level for repository access. Restricts
# the agent to users with at least the specified permission level.
# (optional)
min-integrity: "none"
# Guard policy: GitHub usernames whose content is unconditionally blocked. Items
# from these users receive 'blocked' integrity (below 'none') and are always
# denied, even when 'min-integrity' is 'none'. Cannot be overridden by
# 'approval-labels'. Requires 'min-integrity' to be set. Accepts an array of
# usernames, a comma-separated string, a newline-separated string, or a GitHub
# Actions expression (e.g. '${{ vars.BLOCKED_USERS }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Array of GitHub usernames to block
blocked-users: []
# Array items: GitHub username to block
# Option 2: Comma- or newline-separated list of usernames, or a GitHub Actions
# expression resolving to such a list (e.g. '${{ vars.BLOCKED_USERS }}')
blocked-users: "example-value"
# Guard policy: GitHub usernames whose content is elevated to 'approved' integrity
# regardless of author_association. Allows specific external contributors to
# bypass 'min-integrity' checks without lowering the global policy. Precedence:
# blocked-users > trusted-users > approval-labels > author_association. Requires
# 'min-integrity' to be set. Accepts an array of usernames, a comma-separated
# string, a newline-separated string, or a GitHub Actions expression (e.g. '${{
# vars.TRUSTED_USERS }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Array of GitHub usernames to trust
trusted-users: []
# Array items: GitHub username to elevate to approved integrity
# Option 2: Comma- or newline-separated list of usernames, or a GitHub Actions
# expression resolving to such a list (e.g. '${{ vars.TRUSTED_USERS }}')
trusted-users: "example-value"
# Guard policy: GitHub label names that promote a content item's effective
# integrity to 'approved' when present. Enables human-review gates where a
# maintainer labels an item to allow it through. Uses max(base, approved) so it
# never lowers integrity. Does not override 'blocked-users'. Requires
# 'min-integrity' to be set. Accepts an array of label names, a comma-separated
# string, a newline-separated string, or a GitHub Actions expression (e.g. '${{
# vars.APPROVAL_LABELS }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Array of GitHub label names
approval-labels: []
# Array items: GitHub label name
# Option 2: Comma- or newline-separated list of label names, or a GitHub Actions
# expression resolving to such a list (e.g. '${{ vars.APPROVAL_LABELS }}')
approval-labels: "example-value"
# GitHub App configuration for token minting. When configured, a GitHub App
# installation access token is minted at workflow start and used instead of the
# default token. This token overrides any custom github-token setting and provides
# fine-grained permissions matching the agent job requirements.
# (optional)
github-app:
# GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.
app-id: "example-value"
# GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to
# mint a GitHub App token.
private-key: "example-value"
# Optional owner of the GitHub App installation (defaults to current repository
# owner if not specified)
# (optional)
owner: "example-value"
# Optional list of repositories to grant access to (defaults to current repository
# if not specified)
# (optional)
repositories: []
# Array of strings
# Optional extra GitHub App-only permissions to merge into the minted token. Only
# takes effect for tools.github.github-app; ignored in other github-app contexts.
# (optional)
permissions:
# Permission level for repository administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission for repository administration.
# (optional)
administration: "read"
# Permission level for Codespaces (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces: "read"
# Permission level for Codespaces lifecycle administration (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
codespaces-lifecycle-admin: "read"
# Permission level for Codespaces metadata (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces-metadata: "read"
# Permission level for user email addresses (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
email-addresses: "read"
# Permission level for repository environments (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
environments: "read"
# Permission level for git signing (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
git-signing: "read"
# Permission level for organization members (read/none; "write" is rejected by the
# compiler). Required for org team membership API calls.
# (optional)
members: "read"
# Permission level for organization administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-administration: "read"
# Permission level for organization announcement banners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-announcement-banners: "read"
# Permission level for organization Codespaces (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-codespaces: "read"
# Permission level for organization Copilot (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-copilot: "read"
# Permission level for organization custom org roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-org-roles: "read"
# Permission level for organization custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-properties: "read"
# Permission level for organization custom repository roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-repository-roles: "read"
# Permission level for organization events (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-events: "read"
# Permission level for organization webhooks (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-hooks: "read"
# Permission level for organization members management (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-members: "read"
# Permission level for organization packages (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-packages: "read"
# Permission level for organization personal access token requests (read/none;
# "write" is rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-token-requests: "read"
# Permission level for organization personal access tokens (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-tokens: "read"
# Permission level for organization plan (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-plan: "read"
# Permission level for organization self-hosted runners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-self-hosted-runners: "read"
# Permission level for organization user blocking (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-user-blocking: "read"
# Permission level for repository custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
repository-custom-properties: "read"
# Permission level for repository webhooks (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
repository-hooks: "read"
# Permission level for single file access (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
single-file: "read"
# Permission level for team discussions (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
team-discussions: "read"
# Permission level for Dependabot vulnerability alerts (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
vulnerability-alerts: "read"
# Permission level for GitHub Actions workflow files (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
workflows: "read"
# Bash shell command execution tool. Supports wildcards: '*' (all commands),
# 'command *' (command with any args, e.g., 'date *', 'echo *'). Default safe
# commands: echo, ls, pwd, cat, head, tail, grep, wc, sort, uniq, date.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable bash tool with all shell commands allowed (security
# consideration: use restricted list in production)
bash: null
# Option 2: Enable bash tool - true allows all commands (equivalent to ['*']),
# false disables the tool
bash: true
# Option 3: List of allowed commands and patterns. Wildcards: '*' allows all
# commands, 'command *' allows command with any args (e.g., 'date *', 'echo *').
bash: []
# Array items: Command or pattern: 'echo' (exact match), 'echo *' (command with
# any args)
# Web content fetching tool for downloading web pages and API responses (subject
# to network permissions)
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable web fetch tool with default configuration
web-fetch: null
# Option 2: Web fetch tool configuration object
web-fetch:
{}
# Web search tool for performing internet searches and retrieving search results
# (subject to network permissions)
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable web search tool with default configuration
web-search: null
# Option 2: Web search tool configuration object
web-search:
{}
# File editing tool for reading, creating, and modifying files in the repository
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable edit tool
edit: null
# Option 2: Edit tool configuration object
edit:
{}
# Playwright browser automation tool for web scraping, testing, and UI
# interactions in containerized browsers
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable Playwright tool with default settings
playwright: null
# Option 2: Playwright tool configuration with custom version and arguments
playwright:
# Optional Playwright container version (e.g., 'v1.41.0', 1.41, 20). Numeric
# values are automatically converted to strings at runtime.
# (optional)
version: null
# Optional additional arguments to append to the generated MCP server command
# (optional)
args: []
# Array of strings
# GitHub Agentic Workflows MCP server for workflow introspection and analysis.
# Provides tools for checking status, compiling workflows, downloading logs, and
# auditing runs.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable agentic-workflows tool with default settings
agentic-workflows: true
# Option 2: Enable agentic-workflows tool with default settings (same as true)
agentic-workflows: null
# qmd documentation search tool (https://github.com/tobi/qmd). Builds a local
# vector search index in a dedicated indexing job and shares it with the agent job
# via GitHub Actions cache. The agent job mounts a search MCP server over the
# pre-built index and does not need contents:read permission.
# (optional)
qmd:
# List of named documentation collections built from checked-out repositories.
# Each entry can optionally specify its own checkout configuration to target a
# different repository.
# (optional)
checkouts: []
# List of GitHub search queries whose results are downloaded and added to the qmd
# index.
# (optional)
searches: []
# GitHub Actions cache key used to persist the qmd index across workflow runs.
# When set without any indexing sources (checkouts/searches), qmd operates in
# read-only mode: the index is restored from cache and all indexing steps are
# skipped.
# (optional)
cache-key: "example-value"
# Enable GPU acceleration for the embedding model (node-llama-cpp). Defaults to
# false: NODE_LLAMA_CPP_GPU=false is injected into the indexing step so GPU
# probing is skipped on CPU-only runners. Set to true only when the indexing
# runner has a GPU.
# (optional)
gpu: true
# Override the runner image for the qmd indexing job. Defaults to the same runner
# as the agent job. Use this when the indexing job requires a different runner
# (e.g. a GPU runner).
# (optional)
runs-on: "example-value"
# Cache memory MCP configuration for persistent memory storage
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable cache-memory with default settings
cache-memory: true
# Option 2: Enable cache-memory with default settings (same as true)
cache-memory: null
# Option 3: Cache-memory configuration object
cache-memory:
# Custom cache key for memory MCP data (restore keys are auto-generated by
# splitting on '-')
# (optional)
key: "example-value"
# Optional description for the cache that will be shown in the agent prompt
# (optional)
description: "Description of the workflow"
# Number of days to retain uploaded artifacts (1-90 days, default: repository
# setting)
# (optional)
retention-days: 1
# If true, only restore the cache without saving it back. Uses
# actions/cache/restore instead of actions/cache. No artifact upload step will be
# generated.
# (optional)
restore-only: true
# Cache restore key scope: 'workflow' (default, only restores from same workflow)
# or 'repo' (restores from any workflow in the repository). Use 'repo' with
# caution as it allows cross-workflow cache sharing.
# (optional)
scope: "workflow"
# List of allowed file extensions (e.g., [".json", ".txt"]). Default: [".json",
# ".jsonl", ".txt", ".md", ".csv"]
# (optional)
allowed-extensions: []
# Array of strings
# Option 4: Array of cache-memory configurations for multiple caches
cache-memory: []
# Array items: object
# Timeout in seconds for tool/MCP server operations. Applies to all tools and MCP
# servers if supported by the engine. Default: 60 seconds (for both Claude and
# Codex). Supports GitHub Actions expressions for reusable workflow_call
# workflows.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
timeout: 1
# Option 2: GitHub Actions expression (e.g. '${{ inputs.tool-timeout }}')
timeout: "example-value"
# Timeout in seconds for MCP server startup. Applies to MCP server initialization
# if supported by the engine. Default: 120 seconds. Supports GitHub Actions
# expressions for reusable workflow_call workflows.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
startup-timeout: 1
# Option 2: GitHub Actions expression (e.g. '${{ inputs.startup-timeout }}')
startup-timeout: "example-value"
# Repo memory configuration for git-based persistent storage
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable repo-memory with default settings
repo-memory: true
# Option 2: Enable repo-memory with default settings (same as true)
repo-memory: null
# Option 3: Repo-memory configuration object
repo-memory:
# Branch prefix for memory storage (default: 'memory'). Must be 4-32 characters,
# alphanumeric with hyphens/underscores, and cannot be 'copilot'. Branch will be
# named {branch-prefix}/{id}
# (optional)
branch-prefix: "example-value"
# Target repository for memory storage (default: current repository). Format:
# owner/repo
# (optional)
target-repo: "example-value"
# Git branch name for memory storage (default: {branch-prefix}/default or
# memory/default if branch-prefix not set)
# (optional)
branch-name: "example-value"
# Glob patterns for files to include in repository memory. Supports wildcards
# (e.g., '**/*.md', 'docs/**/*.json') to filter cached files.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single file glob pattern for allowed files
file-glob: "example-value"
# Option 2: Array of file glob patterns for allowed files
file-glob: []
# Array items: string
# Maximum size per file in bytes (default: 10240 = 10KB)
# (optional)
max-file-size: 1
# Maximum file count per commit (default: 100)
# (optional)
max-file-count: 1
# Maximum total patch size in bytes (default: 10240 = 10KB, max: 102400 = 100KB).
# The total size of the git diff must not exceed this value.
# (optional)
max-patch-size: 1
# Optional description for the memory that will be shown in the agent prompt
# (optional)
description: "Description of the workflow"
# Create orphaned branch if it doesn't exist (default: true)
# (optional)
create-orphan: true
# Use the GitHub Wiki git repository instead of the regular repository. When
# enabled, files are stored in and read from the wiki, and the agent will be
# instructed to follow GitHub Wiki markdown syntax (default: false)
# (optional)
wiki: true
# List of allowed file extensions (e.g., [".json", ".txt"]). Default: [".json",
# ".jsonl", ".txt", ".md", ".csv"]
# (optional)
allowed-extensions: []
# Array of strings
# Option 4: Array of repo-memory configurations for multiple memory locations
repo-memory: []
# Array items: object
# Command name for the workflow
# (optional)
command: "example-value"
# Cache configuration for workflow (uses actions/cache syntax)
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single cache configuration
cache:
# An explicit key for restoring and saving the cache
key: "example-value"
# File path or directory to cache for faster workflow execution. Can be a single
# path or an array of paths to cache multiple locations.
# This field supports multiple formats (oneOf):
# Option 1: A single path to cache
path: "example-value"
# Option 2: Multiple paths to cache
path: []
# Array items: string
# Optional list of fallback cache key patterns to use if exact cache key is not
# found. Enables partial cache restoration for better performance.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: A single restore key
restore-keys: "example-value"
# Option 2: Multiple restore keys
restore-keys: []
# Array items: string
# The chunk size used to split up large files during upload, in bytes
# (optional)
upload-chunk-size: 1
# Fail the workflow if cache entry is not found
# (optional)
fail-on-cache-miss: true
# If true, only checks if cache entry exists and skips download
# (optional)
lookup-only: true
# Optional custom name for the cache step (overrides auto-generated name)
# (optional)
name: "My Workflow"
# Option 2: Multiple cache configurations
cache: []
# Array items: object
# Safe output processing configuration that automatically creates GitHub issues,
# comments, and pull requests from AI workflow output without requiring write
# permissions in the main job
# (optional)
safe-outputs:
# List of allowed domains for URL redaction in safe output handlers. Supports
# ecosystem identifiers (e.g., "python", "node", "default-safe-outputs") like
# network.allowed. These domains are unioned with the engine defaults and
# network.allowed when computing the final allowed domain set. localhost and
# github.com are always included.
# (optional)
allowed-domains: []
# Array of strings
# List of allowed repositories for GitHub references (e.g., #123 or
# owner/repo#456). Use 'repo' to allow current repository. References to other
# repositories will be escaped with backticks. If not specified, all references
# are allowed.
# (optional)
allowed-github-references: []
# Array of strings
# Enable AI agents to create GitHub issues from workflow output. Supports title
# prefixes, automatic labeling, assignees, and cross-repository creation. Does not
# require 'issues: write' permission.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for automatically creating GitHub issues from AI
# workflow output. The main job does not need 'issues: write' permission.
create-issue:
# Optional prefix to add to the beginning of the issue title (e.g., '[ai] ' or
# '[analysis] ')
# (optional)
title-prefix: "example-value"
# Optional list of labels to automatically attach to created issues (e.g.,
# ['automation', 'ai-generated'])
# (optional)
labels: []
# Array of strings
# Optional list of allowed labels that can be used when creating issues. If
# omitted, any labels are allowed (including creating new ones). When specified,
# the agent can only use labels from this list.
# (optional)
allowed-labels: []
# Array of strings
# GitHub usernames to assign the created issue to. Can be a single username string
# or array of usernames. Use 'copilot' to assign to GitHub Copilot.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single GitHub username to assign the created issue to (e.g., 'user1'
# or 'copilot'). Use 'copilot' to assign to GitHub Copilot using the @copilot
# special value.
assignees: "example-value"
# Option 2: List of GitHub usernames to assign the created issue to (e.g.,
# ['user1', 'user2', 'copilot']). Use 'copilot' to assign to GitHub Copilot using
# the @copilot special value.
assignees: []
# Array items: string
# Maximum number of issues to create (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository issue creation.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that issues can be
# created in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to create the issue in. The target repository (current
# or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# Time until the issue expires and should be automatically closed. Supports
# integer (days), relative time format, or false to disable expiration. Minimum
# duration: 2 hours. When set, a maintenance workflow will be generated.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Number of days until expires
expires: 1
# Option 2: Relative time (e.g., '2h', '7d', '2w', '1m', '1y'); minimum 2h for
# hour values
expires: "example-value"
# Option 3: Set to false to explicitly disable expiration
expires: false
# If true, group issues as sub-issues under a parent issue. The workflow ID is
# used as the group identifier. Parent issues are automatically created and
# managed, with a maximum of 64 sub-issues per parent.
# (optional)
group: true
# When true, automatically close older issues with the same workflow-id marker as
# 'not planned' with a comment linking to the new issue. Searches for issues
# containing the workflow-id marker in their body. Maximum 10 issues will be
# closed. Only runs if issue creation succeeds.
# (optional)
close-older-issues: true
# Optional explicit deduplication key for close-older matching. When set, a `` marker is embedded in the issue body and used as
# the primary key for searching and filtering older issues instead of the
# workflow-id markers. This gives deterministic isolation across caller workflows
# and is stable across workflow renames. The value is normalized to identifier
# style (lowercase alphanumeric, dashes, underscores).
# (optional)
close-older-key: "example-value"
# When true, if an open issue with the same close-older-key (or workflow-id marker
# when no key is set) was already created today (UTC), post the new content as a
# comment on that existing issue instead of creating a new one. Groups multiple
# same-day runs into a single issue. Works best when combined with
# close-older-issues: true.
# (optional)
group-by-day: true
# Controls whether AI-generated footer is added to the issue. When false, the
# visible footer content is omitted but XML markers (workflow-id, tracker-id,
# metadata) are still included for searchability. Defaults to true.
# (optional)
footer: true
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable issue creation with default configuration
create-issue: null
# Enable creation of GitHub Copilot coding agent tasks from workflow output.
# Allows workflows to spawn new agent sessions for follow-up work.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: DEPRECATED: Use 'create-agent-session' instead. Configuration for
# creating GitHub Copilot coding agent sessions from agentic workflow output using
# gh agent-task CLI. The main job does not need write permissions.
create-agent-task:
# Base branch for the agent session pull request. Defaults to the current branch
# or repository default branch.
# (optional)
base: "example-value"
# Maximum number of agent sessions to create (default: 1) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository agent session
# creation. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that agent sessions can
# be created in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to create the agent session in. The target repository
# (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable agent session creation with default configuration
create-agent-task: null
# Enable creation of GitHub Copilot coding agent sessions from workflow output.
# Allows workflows to start interactive agent conversations.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating GitHub Copilot coding agent sessions from
# agentic workflow output using gh agent-task CLI. The main job does not need
# write permissions.
create-agent-session:
# Base branch for the agent session pull request. Defaults to the current branch
# or repository default branch.
# (optional)
base: "example-value"
# Maximum number of agent sessions to create (default: 1) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository agent session
# creation. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that agent sessions can
# be created in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to create the agent session in. The target repository
# (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable agent session creation with default configuration
create-agent-session: null
# Enable AI agents to add items to GitHub Projects, update custom fields, and
# manage project structure. Use this for organizing work into projects with status
# tracking, priority management, and custom metadata.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for managing GitHub Projects boards. Enable agents to
# add issues and pull requests to projects, update custom field values (status,
# priority, effort, dates), create project fields and views. By default it is
# update-only: if the project does not exist, the job fails with instructions to
# create it. To allow workflows to create missing projects, explicitly opt in via
# agent output field create_if_missing=true. Requires a Personal Access Token
# (PAT) or GitHub App token with Projects permissions (default GITHUB_TOKEN cannot
# be used). Agent output includes: project (full URL or temporary project ID like
# aw_XXXXXXXXXXXX or #aw_XXXXXXXXXXXX from create_project), content_type
# (issue|pull_request|draft_issue), content_number, fields, create_if_missing. For
# specialized operations, agent can also provide: operation
# (create_fields|create_view), field_definitions (array of field configs when
# operation=create_fields), view (view config object when operation=create_view).
update-project:
# Maximum number of project operations to perform (default: 10). Each operation
# may add a project item, or update its fields. Supports integer or GitHub Actions
# expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Target project URL for update-project operations. This is required in the
# configuration for documentation purposes. Agent messages MUST explicitly include
# the project field in their output - the configured value is not used as a
# fallback. Must be a valid GitHub Projects v2 URL.
project: "example-value"
# Default repository in format 'owner/repo' for cross-repository content
# resolution. When specified, the agent can use 'target_repo' in agent output to
# resolve issues or PRs from this repository. Wildcards ('*') are not allowed.
# Supports GitHub Actions expression syntax (e.g., '${{ vars.TARGET_REPO }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: string
target-repo: "example-value"
# Option 2: GitHub Actions expression that resolves to owner/repo at runtime
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' allowed for
# cross-repository content resolution via 'target_repo'. The target-repo (or
# current repo) is always implicitly allowed. Supports wildcard patterns (e.g.,
# 'org/*', '*/repo', '*') and GitHub Actions expression syntax for individual
# entries.
# (optional)
allowed-repos: []
# Optional array of project views to create. Each view must have a name and
# layout. Views are created during project setup.
# (optional)
views: []
# Array items:
# The name of the view (e.g., 'Sprint Board', 'Roadmap')
name: "My Workflow"
# The layout type of the view
layout: "table"
# Optional filter query for the view (e.g., 'is:issue is:open', 'label:bug')
# (optional)
filter: "example-value"
# Optional array of field IDs that should be visible in the view (table/board
# only, not applicable to roadmap)
# (optional)
visible-fields: []
# Optional human description for the view. Not supported by the GitHub Views API
# and may be ignored.
# (optional)
description: "Description of the workflow"
# Optional array of project custom fields to create up-front.
# (optional)
field-definitions: []
# Array items:
# The field name to create (e.g., 'status', 'priority')
name: "My Workflow"
# The GitHub Projects v2 custom field type
data-type: "DATE"
# Options for SINGLE_SELECT fields. GitHub does not support adding options later.
# (optional)
options: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable project management with default configuration (max=10)
update-project: null
# Enable AI agents to create new GitHub Projects for organizing and tracking work
# across issues and pull requests.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating new GitHub Projects boards. Enables agents
# to create new project boards with optional custom fields, views, and an initial
# item. Requires a Personal Access Token (PAT) or GitHub App token with Projects
# write permission (default GITHUB_TOKEN cannot be used). Agent output includes:
# title (project name), owner (org/user login, uses default if omitted),
# owner_type ('org' or 'user'), optional item_url (issue to add as first item),
# and optional field_definitions. Returns a temporary project ID for use in
# subsequent update_project operations.
create-project:
# Maximum number of create operations to perform (default: 1). Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Must have Projects write
# permission. Overrides global github-token if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Optional default target owner (organization or user login, e.g., 'myorg' or
# 'username') for the new project. If specified, the agent can omit the owner
# field in the tool call and this default will be used. The agent can still
# override by providing an owner in the tool call.
# (optional)
target-owner: "example-value"
# Optional prefix for auto-generated project titles (default: 'Project'). When the
# agent doesn't provide a title, the project title is auto-generated as
# ': ' or ' #' based on the
# issue context.
# (optional)
title-prefix: "example-value"
# Optional array of project views to create automatically after project creation.
# Each view must have a name and layout. Views are created immediately after the
# project is created.
# (optional)
views: []
# Array items:
# The name of the view (e.g., 'Sprint Board', 'Roadmap')
name: "My Workflow"
# The layout type of the view
layout: "table"
# Optional filter query for the view (e.g., 'is:issue is:open', 'label:bug')
# (optional)
filter: "example-value"
# Optional array of field IDs that should be visible in the view (table/board
# only, not applicable to roadmap)
# (optional)
visible-fields: []
# Optional human description for the view. Not supported by the GitHub Views API
# and may be ignored.
# (optional)
description: "Description of the workflow"
# Optional array of project custom fields to create automatically after project
# creation.
# (optional)
field-definitions: []
# Array items:
# The field name to create (e.g., 'Priority', 'Classification')
name: "My Workflow"
# The GitHub Projects v2 custom field type
data-type: "DATE"
# Options for SINGLE_SELECT fields. GitHub does not support adding options later.
# (optional)
options: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable project creation with default configuration (max=1)
create-project: null
# Enable AI agents to post status updates to GitHub Projects for progress tracking
# and stakeholder communication.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for posting status updates to GitHub Projects. Status
# updates provide stakeholder communication about project progress, health, and
# timeline. Each update appears in the project's Updates tab and creates a
# historical record. Requires a Personal Access Token (PAT) or GitHub App token
# with Projects read & write permission (default GITHUB_TOKEN cannot be used).
# Typically used by scheduled workflows or orchestrators to post regular progress
# summaries with status indicators (on-track, at-risk, off-track, complete,
# inactive), dates, and progress details.
create-project-status-update:
# Maximum number of status updates to create (default: 1). Typically 1 per
# orchestrator run. Supports integer or GitHub Actions expression (e.g. '${{
# inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified. Must have Projects: Read+Write permission.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Target project URL for status update operations. This is required in the
# configuration for documentation purposes. Agent messages MUST explicitly include
# the project field in their output - the configured value is not used as a
# fallback. Must be a valid GitHub Projects v2 URL.
project: "example-value"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable project status updates with default configuration (max=1)
create-project-status-update: null
# Enable AI agents to create GitHub Discussions from workflow output. Supports
# categorization, labeling, and automatic closure of older discussions. Does not
# require 'discussions: write' permission.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating GitHub discussions from agentic workflow
# output
create-discussion:
# Optional prefix for the discussion title
# (optional)
title-prefix: "example-value"
# Optional discussion category. Can be a category ID (string or numeric value),
# category name, or category slug/route. If not specified, uses the first
# available category. Matched first against category IDs, then against category
# names, then against category slugs. Numeric values are automatically converted
# to strings at runtime.
# (optional)
category: null
# Optional list of labels to attach to created discussions. Also used for matching
# when close-older-discussions is enabled - discussions must have ALL specified
# labels (AND logic).
# (optional)
labels: []
# Array of strings
# Optional list of allowed labels that can be used when creating discussions. If
# omitted, any labels are allowed (including creating new ones). When specified,
# the agent can only use labels from this list.
# (optional)
allowed-labels: []
# Array of strings
# Maximum number of discussions to create (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository discussion
# creation. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that discussions can be
# created in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to create the discussion in. The target repository
# (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# When true, automatically close older discussions matching the same title prefix
# or labels as 'outdated' with a comment linking to the new discussion. Requires
# title-prefix or labels to be set. Maximum 10 discussions will be closed. Only
# runs if discussion creation succeeds. When fallback-to-issue is enabled and
# discussion creation fails, older issues will be closed instead.
# (optional)
close-older-discussions: true
# Optional explicit deduplication key for close-older matching. When set, a `` marker is embedded in the discussion body and used
# as the primary key for searching and filtering older discussions instead of the
# workflow-id markers. This gives deterministic isolation across caller workflows
# and is stable across workflow renames. The value is normalized to identifier
# style (lowercase alphanumeric, dashes, underscores).
# (optional)
close-older-key: "example-value"
# When true (default), fallback to creating an issue if discussion creation fails
# due to permissions. The fallback issue will include a note indicating it was
# intended to be a discussion. If close-older-discussions is enabled, the
# close-older-issues logic will be applied to the fallback issue.
# (optional)
fallback-to-issue: true
# Controls whether AI-generated footer is added to the discussion. When false, the
# visible footer content is omitted but XML markers (workflow-id, tracker-id,
# metadata) are still included for searchability. Defaults to true.
# (optional)
footer: true
# Time until the discussion expires and should be automatically closed. Supports
# integer (days), relative time format like '2h' (2 hours), '7d' (7 days), '2w' (2
# weeks), '1m' (1 month), '1y' (1 year), or false to disable expiration. Minimum
# duration: 2 hours. When set, a maintenance workflow will be generated. Defaults
# to 7 days if not specified.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Number of days until expires
expires: 1
# Option 2: Relative time (e.g., '2h', '7d', '2w', '1m', '1y'); minimum 2h for
# hour values
expires: "example-value"
# Option 3: Set to false to explicitly disable expiration
expires: false
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable discussion creation with default configuration
create-discussion: null
# Enable AI agents to close GitHub Discussions based on workflow analysis or
# conditions.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for closing GitHub discussions with comment and
# resolution from agentic workflow output
close-discussion:
# Only close discussions that have all of these labels
# (optional)
required-labels: []
# Array of strings
# Only close discussions with this title prefix
# (optional)
required-title-prefix: "example-value"
# Only close discussions in this category
# (optional)
required-category: "example-value"
# Target for closing: 'triggering' (default, current discussion), or '*' (any
# discussion with discussion_number field)
# (optional)
target: "example-value"
# Maximum number of discussions to close (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository operations. Takes
# precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable discussion closing with default configuration
close-discussion: null
# Enable AI agents to edit and update existing GitHub Discussion content, titles,
# and metadata.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for updating GitHub discussions from agentic workflow
# output
update-discussion:
# Target for updates: 'triggering' (default), '*' (any discussion), or explicit
# discussion number
# (optional)
target: "example-value"
# Allow updating discussion title - presence of key indicates field can be updated
# (optional)
title: null
# Allow updating discussion body - presence of key indicates field can be updated
# (optional)
body: null
# Allow updating discussion labels - presence of key indicates field can be
# updated
# (optional)
labels: null
# Optional list of allowed labels. If omitted, any labels are allowed (including
# creating new ones).
# (optional)
allowed-labels: []
# Array of strings
# Maximum number of discussions to update (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository discussion
# updates. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# Controls whether AI-generated footer is added when updating the discussion body.
# When false, the visible footer content is omitted. Defaults to true. Only
# applies when 'body' is enabled.
# (optional)
footer: true
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Option 2: Enable discussion updating with default configuration
update-discussion: null
# Enable AI agents to close GitHub issues based on workflow analysis, resolution
# detection, or automated triage.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for closing GitHub issues with comment from agentic
# workflow output
close-issue:
# Only close issues that have all of these labels
# (optional)
required-labels: []
# Array of strings
# Only close issues with this title prefix
# (optional)
required-title-prefix: "example-value"
# Target for closing: 'triggering' (default, current issue), or '*' (any issue
# with issue_number field)
# (optional)
target: "example-value"
# Maximum number of issues to close (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository operations. Takes
# precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that issues can be closed
# in. When specified, the agent can use a 'repo' field in the output to specify
# which repository to close the issue in. The target repository (current or
# target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable issue closing with default configuration
close-issue: null
# Enable AI agents to close pull requests based on workflow analysis or automated
# review decisions.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for closing GitHub pull requests without merging, with
# comment from agentic workflow output
close-pull-request:
# Only close pull requests that have any of these labels
# (optional)
required-labels: []
# Array of strings
# Only close pull requests with this title prefix
# (optional)
required-title-prefix: "example-value"
# Target for closing: 'triggering' (default, current PR), or '*' (any PR with
# pull_request_number field)
# (optional)
target: "example-value"
# Maximum number of pull requests to close (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository operations. Takes
# precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable pull request closing with default configuration
close-pull-request: null
# Enable AI agents to mark draft pull requests as ready for review when criteria
# are met.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for marking draft pull requests as ready for review,
# with comment from agentic workflow output
mark-pull-request-as-ready-for-review:
# Only mark pull requests that have any of these labels
# (optional)
required-labels: []
# Array of strings
# Only mark pull requests with this title prefix
# (optional)
required-title-prefix: "example-value"
# Target for marking: 'triggering' (default, current PR), or '*' (any PR with
# pull_request_number field)
# (optional)
target: "example-value"
# Maximum number of pull requests to mark as ready (default: 1) Supports integer
# or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository operations. Takes
# precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable marking pull requests as ready for review with default
# configuration
mark-pull-request-as-ready-for-review: null
# Enable AI agents to add comments to GitHub issues, pull requests, or
# discussions. Supports templating, cross-repository commenting, and automatic
# mentions.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for automatically creating GitHub issue or pull request
# comments from AI workflow output. The main job does not need write permissions.
add-comment:
# Maximum number of comments to create (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target for comments: 'triggering' (default), '*' (any issue), or explicit issue
# number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository comments. Takes
# precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that comments can be
# created in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to create the comment in. The target repository
# (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# When true, minimizes/hides all previous comments from the same agentic workflow
# (identified by tracker-id) before creating the new comment. Default: false.
# (optional)
hide-older-comments: true
# List of allowed reasons for hiding older comments when hide-older-comments is
# enabled. Default: all reasons allowed (spam, abuse, off_topic, outdated,
# resolved).
# (optional)
allowed-reasons: []
# Array of strings
# Controls whether the workflow requests discussions:write permission for
# add-comment and includes discussions in the event trigger condition. Default:
# true (includes discussions:write). Set to false if your GitHub App lacks
# Discussions permission to prevent 422 errors during token generation.
# (optional)
discussions: true
# Controls whether the workflow requests issues:write permission for add-comment
# and includes issues in the event trigger condition. Default: true (includes
# issues:write). Set to false to disable issue commenting.
# (optional)
issues: true
# Controls whether the workflow requests pull-requests:write permission for
# add-comment and includes pull requests in the event trigger condition. Default:
# true (includes pull-requests:write). Set to false to disable pull request
# commenting.
# (optional)
pull-requests: true
# Controls whether AI-generated footer is added to the comment. When false, the
# visible footer content is omitted but XML markers (workflow-id, metadata) are
# still included for searchability. Defaults to true.
# (optional)
footer: true
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable issue comment creation with default configuration
add-comment: null
# Enable AI agents to create GitHub pull requests from workflow-generated code
# changes, patches, or analysis results.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating GitHub pull requests from agentic workflow
# output. Supports creating multiple PRs in a single run when max > 1.
create-pull-request:
# Maximum number of pull requests to create (default: 1). Each PR requires
# distinct changes on a separate branch. Supports integer or GitHub Actions
# expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Optional prefix for the pull request title
# (optional)
title-prefix: "example-value"
# Optional list of labels to attach to the pull request
# (optional)
labels: []
# Array of strings
# Optional list of allowed labels that can be used when creating pull requests. If
# omitted, any labels are allowed (including creating new ones). When specified,
# the agent can only use labels from this list.
# (optional)
allowed-labels: []
# Array of strings
# Optional reviewer(s) to assign to the pull request. Accepts either a single
# string or an array of usernames. Use 'copilot' to request a code review from
# GitHub Copilot.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single reviewer username to assign to the pull request. Use 'copilot'
# to request a code review from GitHub Copilot using the
# copilot-pull-request-reviewer[bot].
reviewers: "example-value"
# Option 2: List of reviewer usernames to assign to the pull request. Use
# 'copilot' to request a code review from GitHub Copilot using the
# copilot-pull-request-reviewer[bot].
reviewers: []
# Array items: string
# Whether to create pull request as draft (defaults to true). Accepts a boolean or
# a GitHub Actions expression.
# (optional)
draft: null
# Behavior when no changes to push: 'warn' (default - log warning but succeed),
# 'error' (fail the action), or 'ignore' (silent success)
# (optional)
if-no-changes: "warn"
# When true, allows creating a pull request without any initial changes or git
# patch. This is useful for preparing a feature branch that an agent can push
# changes to later. The branch will be created from the base branch without
# applying any patch. Defaults to false.
# (optional)
allow-empty: true
# Target repository in format 'owner/repo' for cross-repository pull request
# creation. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that pull requests can be
# created in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to create the pull request in. The target repository
# (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Time until the pull request expires and should be automatically closed (only for
# same-repo PRs without target-repo). Supports integer (days) or relative time
# format. Minimum duration: 2 hours.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Number of days until expires
expires: 1
# Option 2: Relative time (e.g., '2h', '7d', '2w', '1m', '1y'); minimum 2h for
# hour values
expires: "example-value"
# Enable auto-merge for the pull request. When enabled, the PR will be
# automatically merged once all required checks pass and required approvals are
# met. Defaults to false.
# (optional)
auto-merge: true
# Base branch for the pull request. Defaults to the workflow's branch
# (github.ref_name) if not specified. Useful for cross-repository PRs targeting
# non-default branches (e.g., 'vnext', 'release/v1.0').
# (optional)
base-branch: "example-value"
# Controls whether AI-generated footer is added to the pull request. When false,
# the visible footer content is omitted but XML markers (workflow-id, tracker-id,
# metadata) are still included for searchability. Defaults to true.
# (optional)
footer: true
# Controls the fallback behavior when pull request creation fails. When true
# (default), an issue is created as a fallback with the patch content. When false,
# no issue is created and the workflow fails with an error. Setting to false also
# removes the issues:write permission requirement.
# (optional)
fallback-as-issue: true
# When true (default), automatically appends a closing keyword ("Fixes #N") to the
# PR description when the workflow is triggered from an issue and no closing
# keyword is already present. This causes GitHub to auto-close the triggering
# issue when the PR is merged. Set to false to prevent this behavior, e.g., for
# partial-work PRs or multi-PR workflows. Accepts a boolean or a GitHub Actions
# expression.
# (optional)
auto-close-issue: null
# Token used to push an empty commit after PR creation to trigger CI events. Works
# around the GITHUB_TOKEN limitation where pushes don't trigger workflow runs.
# Defaults to the magic secret GH_AW_CI_TRIGGER_TOKEN if set in the repository.
# Use a secret expression (e.g. '${{ secrets.CI_TOKEN }}') for a custom token, or
# 'app' for GitHub App auth.
# (optional)
github-token-for-extra-empty-commit: "example-value"
# Controls protected-file protection. blocked (default): hard-block any patch that
# modifies package manifests (e.g. package.json, go.mod), engine instruction files
# (e.g. AGENTS.md, CLAUDE.md) or .github/ files. allowed: allow all changes.
# fallback-to-issue: push the branch but create a review issue instead of a PR, so
# a human can review the manifest changes before merging.
# (optional)
protected-files: "blocked"
# Exclusive allowlist of glob patterns. When set, every file in the patch must
# match at least one pattern — files outside the list are always refused,
# including normal source files. This is a restriction, not an exception: setting
# allowed-files: [".github/workflows/*"] blocks all other files. To allow multiple
# sets of files, list all patterns explicitly. Acts independently of the
# protected-files policy; both checks must pass. To modify a protected file, it
# must both match allowed-files and be permitted by protected-files (e.g.
# protected-files: allowed). Supports * (any characters except /) and ** (any
# characters including /).
# (optional)
allowed-files: []
# Array of strings
# When true, the random salt suffix is not appended to the agent-specified branch
# name. Invalid characters are still replaced for security, and casing is always
# preserved regardless of this setting. Useful when the target repository enforces
# branch naming conventions (e.g. Jira keys in uppercase such as
# 'bugfix/BR-329-red'). Defaults to false.
# (optional)
preserve-branch-name: true
# List of glob patterns for files to exclude from the patch. Each pattern is
# passed to `git format-patch` as a `:(exclude)` magic pathspec, so
# matching files are stripped by git at generation time and will not appear in the
# commit. Excluded files are also not subject to `allowed-files` or
# `protected-files` checks. Supports * (any characters except /) and ** (any
# characters including /).
# (optional)
excluded-files: []
# Array of strings
# Transport format for packaging changes. "am" (default) uses git format-patch/git
# am. "bundle" uses git bundle, which preserves merge commit topology, per-commit
# authorship, and merge-resolution-only content.
# (optional)
patch-format: "am"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable pull request creation with default configuration
create-pull-request: null
# Enable AI agents to add review comments to specific lines in pull request diffs
# during code review workflows.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating GitHub pull request review comments from
# agentic workflow output
create-pull-request-review-comment:
# Maximum number of review comments to create (default: 10) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Side of the diff for comments: 'LEFT' or 'RIGHT' (default: 'RIGHT')
# (optional)
side: "LEFT"
# Target for review comments: 'triggering' (default, only on triggering PR), '*'
# (any PR, requires pull_request_number in agent output), or explicit PR number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository PR review
# comments. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that PR review comments
# can be created in. When specified, the agent can use a 'repo' field in the
# output to specify which repository to create the review comment in. The target
# repository (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable PR review comment creation with default configuration
create-pull-request-review-comment: null
# Enable AI agents to submit consolidated pull request reviews with a status
# decision. Works with create-pull-request-review-comment to batch inline comments
# into a single review.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for submitting a consolidated PR review with a status
# decision (APPROVE, REQUEST_CHANGES, COMMENT). All
# create-pull-request-review-comment outputs are collected and submitted as part
# of this review.
submit-pull-request-review:
# Maximum number of reviews to submit (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Controls when AI-generated footer is added to the review body. Accepts boolean
# (true/false) or string ('always', 'none', 'if-body'). The 'if-body' mode is
# useful for clean approval reviews without body text. Defaults to 'always'.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Controls whether AI-generated footer is added to the review body. true
# maps to 'always', false maps to 'none'.
footer: true
# Option 2: Controls when AI-generated footer is added to the review body:
# 'always' (default), 'none' (never), or 'if-body' (only when review has body
# text).
footer: "always"
# Target PR for the review: 'triggering' (default, current PR), '*' (any PR,
# requires pull_request_number in agent output), or explicit PR number (e.g. ${{
# github.event.inputs.pr_number }}). Required when workflow is not triggered by a
# pull request (e.g. workflow_dispatch).
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository PR review
# submission. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that PR reviews can be
# submitted in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to submit the review in. The target repository (current
# or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable PR review submission with default configuration
submit-pull-request-review: null
# Enable AI agents to reply to existing review comments on pull requests.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for replying to existing pull request review comments
reply-to-pull-request-review-comment:
# Maximum number of replies to create (default: 10) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target for replies: 'triggering' (default), '*' (any PR), or explicit PR number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository operations
# (optional)
target-repo: "example-value"
# List of additional repositories that replies can target
# (optional)
allowed-repos: []
# Array of strings
# Controls whether AI-generated footer is added to the reply body. When false, the
# footer is omitted. Defaults to true.
# (optional)
footer: true
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable with default configuration
reply-to-pull-request-review-comment: null
# Enable AI agents to resolve review threads on the triggering pull request after
# addressing feedback.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for resolving review threads on pull requests.
# Resolution is scoped to the triggering PR only — threads on other PRs cannot be
# resolved.
resolve-pull-request-review-thread:
# Maximum number of review threads to resolve (default: 10) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable review thread resolution with default configuration
resolve-pull-request-review-thread: null
# Enable AI agents to create GitHub Advanced Security code scanning alerts for
# detected vulnerabilities or security issues.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating repository security advisories (SARIF
# format) from agentic workflow output
create-code-scanning-alert:
# Maximum number of security findings to include (default: unlimited) Supports
# integer or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Driver name for SARIF tool.driver.name field (default: 'GitHub Agentic Workflows
# Security Scanner')
# (optional)
driver: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Target repository in format 'owner/repo' for cross-repository code scanning
# alert creation. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that code scanning alerts
# can be created in. When specified, the agent can use a 'repo' field in the
# output to specify which repository to create the alert in. The target repository
# (current or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable code scanning alert creation with default configuration
# (unlimited findings)
create-code-scanning-alert: null
# Enable AI agents to create autofixes for code scanning alerts using the GitHub
# REST API.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for creating autofixes for code scanning alerts
autofix-code-scanning-alert:
# Maximum number of autofixes to create (default: 10) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable code scanning autofix creation with default configuration (max:
# 10)
autofix-code-scanning-alert: null
# Enable AI agents to add labels to GitHub issues or pull requests based on
# workflow analysis or classification.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null configuration allows any labels. Labels will be created if they
# don't already exist in the repository.
add-labels: null
# Option 2: Configuration for adding labels to issues/PRs from agentic workflow
# output. Labels will be created if they don't already exist in the repository.
add-labels:
# Optional list of allowed labels that can be added. Labels will be created if
# they don't already exist in the repository. If omitted, any labels are allowed
# (including creating new ones).
# (optional)
allowed: []
# Array of strings
# Optional list of blocked label patterns (supports glob patterns like '~*',
# '*[bot]'). Labels matching these patterns will be rejected. Applied before
# allowed list filtering for security.
# (optional)
blocked: []
# Array of strings
# Optional maximum number of labels to add (default: 3) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target for labels: 'triggering' (default), '*' (any issue/PR), or explicit
# issue/PR number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository label addition.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# List of additional repositories in format 'owner/repo' that labels can be added
# to. When specified, the agent can use a 'repo' field in the output to specify
# which repository to add labels to. The target repository (current or
# target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to remove labels from GitHub issues or pull requests.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null configuration allows any labels to be removed.
remove-labels: null
# Option 2: Configuration for removing labels from issues/PRs from agentic
# workflow output.
remove-labels:
# Optional list of allowed labels that can be removed. If omitted, any labels can
# be removed.
# (optional)
allowed: []
# Array of strings
# Optional list of blocked label patterns (supports glob patterns like '~*',
# '*[bot]'). Labels matching these patterns will be rejected. Applied before
# allowed list filtering for security.
# (optional)
blocked: []
# Array of strings
# Optional maximum number of labels to remove (default: 3) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target for labels: 'triggering' (default), '*' (any issue/PR), or explicit
# issue/PR number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository label removal.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# List of additional repositories in format 'owner/repo' that labels can be
# removed from. When specified, the agent can use a 'repo' field in the output to
# specify which repository to remove labels from. The target repository (current
# or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to request reviews from users or teams on pull requests based
# on code changes or expertise matching.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null configuration allows any reviewers
add-reviewer: null
# Option 2: Configuration for adding reviewers to pull requests from agentic
# workflow output
add-reviewer:
# Optional list of allowed reviewers. If omitted, any reviewers are allowed.
# (optional)
reviewers: []
# Array of strings
# Optional maximum number of reviewers to add (default: 3) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target for reviewers: 'triggering' (default), '*' (any PR), or explicit PR
# number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository reviewer addition.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to assign GitHub milestones to issues or pull requests based on
# workflow analysis or project planning.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null configuration allows assigning any milestones
assign-milestone: null
# Option 2: Configuration for assigning issues to milestones from agentic workflow
# output
assign-milestone:
# Optional list of allowed milestone titles that can be assigned. If omitted, any
# milestones are allowed.
# (optional)
allowed: []
# Array of strings
# Optional maximum number of milestone assignments (default: 1) Supports integer
# or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository milestone
# assignment. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to assign issues or pull requests to GitHub Copilot (@copilot)
# for automated handling.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null configuration uses default agent (copilot)
assign-to-agent: null
# Option 2: Configuration for assigning GitHub Copilot coding agent to issues from
# agentic workflow output
assign-to-agent:
# Default agent name to assign (default: 'copilot')
# (optional)
name: "My Workflow"
# Default AI model to use for the agent (e.g., 'auto', 'claude-sonnet-4.5',
# 'claude-opus-4.5', 'claude-opus-4.6', 'gpt-5.1-codex-max', 'gpt-5.2-codex').
# Defaults to 'auto' if not specified.
# (optional)
model: "example-value"
# Default custom agent ID to use when assigning custom agents. This is used for
# specialized agent configurations beyond the standard Copilot agent.
# (optional)
custom-agent: "example-value"
# Default custom instructions to provide to the agent. These instructions will
# guide the agent's behavior when working on the task.
# (optional)
custom-instructions: "example-value"
# Optional list of allowed agent names. If specified, only these agents can be
# assigned. When configured, existing agent assignees not in the list are removed
# while regular user assignees are preserved.
# (optional)
allowed: []
# Array of strings
# Optional maximum number of agent assignments (default: 1) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target issue/PR to assign agents to. Use 'triggering' (default) for the
# triggering issue/PR, '*' to require explicit issue_number/pull_number, or a
# specific issue/PR number. With 'triggering', auto-resolves from
# github.event.issue.number or github.event.pull_request.number.
# (optional)
target: null
# Target repository in format 'owner/repo' for cross-repository agent assignment.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# Target repository where the pull request should be created, in format
# 'owner/repo'. If omitted, the PR will be created in the same repository as the
# issue (specified by target-repo or the workflow's repository). This allows
# issues and code to live in different repositories.
# (optional)
pull-request-repo: "example-value"
# List of additional repositories that pull requests can be created in beyond
# pull-request-repo. Each entry should be in 'owner/repo' format. The repository
# specified by pull-request-repo is automatically allowed without needing to be
# listed here.
# (optional)
allowed-pull-request-repos: []
# Array of strings
# If true, the workflow continues gracefully when agent assignment fails (e.g.,
# due to missing token or insufficient permissions), logging a warning instead of
# failing. Default is false. Useful for workflows that should not fail when agent
# assignment is optional.
# (optional)
ignore-if-error: true
# Base branch for pull request creation in the target repository. Defaults to the
# target repo's default branch. Only relevant when pull-request-repo is
# configured.
# (optional)
base-branch: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to assign issues or pull requests to specific GitHub users
# based on workflow logic or expertise matching.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable user assignment with default configuration
assign-to-user: null
# Option 2: Configuration for assigning users to issues from agentic workflow
# output
assign-to-user:
# Optional list of allowed usernames. If specified, only these users can be
# assigned.
# (optional)
allowed: []
# Array of strings
# Optional list of blocked usernames or patterns (e.g., 'copilot', '*[bot]').
# Users matching these patterns cannot be assigned. Supports exact matches and
# glob patterns.
# (optional)
blocked: []
# Array of strings
# Optional maximum number of user assignments (default: 1) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target issue to assign users to. Use 'triggering' (default) for the triggering
# issue, '*' to allow any issue, or a specific issue number.
# (optional)
target: null
# Target repository in format 'owner/repo' for cross-repository user assignment.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# If true, unassign all current assignees before assigning new ones. Useful for
# reassigning issues from one user to another (default: false).
# (optional)
unassign-first: true
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# List of allowed repositories in format 'owner/repo' for cross-repository user
# assignment operations. Use with 'repo' field in tool calls.
# (optional)
allowed-repos: []
# Array of strings
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to unassign users from issues or pull requests. Useful for
# reassigning work or removing users from issues.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable user unassignment with default configuration
unassign-from-user: null
# Option 2: Configuration for removing assignees from issues in agentic workflow
# output
unassign-from-user:
# Optional list of allowed usernames. If specified, only these users can be
# unassigned.
# (optional)
allowed: []
# Array of strings
# Optional list of blocked usernames or patterns (e.g., 'copilot', '*[bot]').
# Users matching these patterns cannot be unassigned. Supports exact matches and
# glob patterns.
# (optional)
blocked: []
# Array of strings
# Optional maximum number of unassignment operations (default: 1) Supports integer
# or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target issue to unassign users from. Use 'triggering' (default) for the
# triggering issue, '*' to allow any issue, or a specific issue number.
# (optional)
target: null
# Target repository in format 'owner/repo' for cross-repository user unassignment.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of allowed repositories in format 'owner/repo' for cross-repository
# unassignment operations. Use with 'repo' field in tool calls.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to create hierarchical relationships between issues using
# GitHub's sub-issue (tasklist) feature.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable sub-issue linking with default configuration
link-sub-issue: null
# Option 2: Configuration for linking issues as sub-issues from agentic workflow
# output
link-sub-issue:
# Maximum number of sub-issue links to create (default: 5) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Optional list of labels that parent issues must have to be eligible for linking
# (optional)
parent-required-labels: []
# Array of strings
# Optional title prefix that parent issues must have to be eligible for linking
# (optional)
parent-title-prefix: "example-value"
# Optional list of labels that sub-issues must have to be eligible for linking
# (optional)
sub-required-labels: []
# Array of strings
# Optional title prefix that sub-issues must have to be eligible for linking
# (optional)
sub-title-prefix: "example-value"
# Target repository in format 'owner/repo' for cross-repository sub-issue linking.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to edit and update existing GitHub issue content, titles,
# labels, assignees, and metadata.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for updating GitHub issues from agentic workflow output
update-issue:
# Allow updating issue status (open/closed) - presence of key indicates field can
# be updated
# (optional)
status: null
# Target for updates: 'triggering' (default), '*' (any issue), or explicit issue
# number
# (optional)
target: "example-value"
# Allow updating issue title - presence of key indicates field can be updated
# (optional)
title: null
# Allow updating issue body. Set to true to enable body updates, false to disable.
# For backward compatibility, null (body:) also enables body updates.
# (optional)
body: null
# Controls whether AI-generated footer is added when updating the issue body. When
# false, the visible footer content is omitted but XML markers are still included.
# Defaults to true. Only applies when 'body' is enabled.
# (optional)
footer: true
# Maximum number of issues to update (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository issue updates.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# Required prefix for issue title. Only issues with this title prefix can be
# updated.
# (optional)
title-prefix: "example-value"
# List of additional repositories in format 'owner/repo' that issues can be
# updated in. When specified, the agent can use a 'repo' field in the output to
# specify which repository to update the issue in. The target repository (current
# or target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable issue updating with default configuration
update-issue: null
# Enable AI agents to edit and update existing pull request content, titles,
# labels, reviewers, and metadata.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for updating GitHub pull requests from agentic workflow
# output. Both title and body updates are enabled by default.
update-pull-request:
# Target for updates: 'triggering' (default), '*' (any PR), or explicit PR number
# (optional)
target: "example-value"
# Allow updating pull request title - defaults to true, set to false to disable
# (optional)
title: true
# Allow updating pull request body - defaults to true, set to false to disable
# (optional)
body: true
# Default operation for body updates: 'append' (add to end), 'prepend' (add to
# start), or 'replace' (overwrite completely). Defaults to 'replace' if not
# specified.
# (optional)
operation: "append"
# Controls whether AI-generated footer is added when updating the pull request
# body. When false, the visible footer content is omitted but XML markers are
# still included. Defaults to true. Only applies when 'body' is enabled.
# (optional)
footer: true
# Maximum number of pull requests to update (default: 1) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository pull request
# updates. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable pull request updating with default configuration (title and
# body updates enabled)
update-pull-request: null
# Enable AI agents to push commits directly to pull request branches for automated
# fixes or improvements.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Use default configuration (branch: 'triggering', if-no-changes:
# 'warn')
push-to-pull-request-branch: null
# Option 2: Configuration for pushing changes to a specific branch from agentic
# workflow output. Supports pushing to multiple PRs in a single run when max > 1.
push-to-pull-request-branch:
# Maximum number of push operations to perform (default: 1). Each push targets a
# different pull request branch. Supports integer or GitHub Actions expression
# (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# The branch to push changes to (defaults to 'triggering')
# (optional)
branch: "example-value"
# Target for push operations: 'triggering' (default), '*' (any pull request), or
# explicit pull request number
# (optional)
target: "example-value"
# Required prefix for pull request title. Only pull requests with this prefix will
# be accepted.
# (optional)
title-prefix: "example-value"
# Required labels for pull request validation. Only pull requests with all these
# labels will be accepted.
# (optional)
labels: []
# Array of strings
# Behavior when no changes to push: 'warn' (default - log warning but succeed),
# 'error' (fail the action), or 'ignore' (silent success)
# (optional)
if-no-changes: "warn"
# Optional suffix to append to generated commit titles (e.g., ' [skip ci]' to
# prevent triggering CI on the commit)
# (optional)
commit-title-suffix: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Token used to push an empty commit after pushing changes to trigger CI events.
# Works around the GITHUB_TOKEN limitation where pushes don't trigger workflow
# runs. Defaults to the magic secret GH_AW_CI_TRIGGER_TOKEN if set in the
# repository. Use a secret expression (e.g. '${{ secrets.CI_TOKEN }}') for a
# custom token, or 'app' for GitHub App auth.
# (optional)
github-token-for-extra-empty-commit: "example-value"
# Target repository in format 'owner/repo' for cross-repository push to pull
# request branch. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' that push to pull request
# branch can target. When specified, the agent can use a 'repo' field in the
# output to specify which repository to push to. The target repository (current or
# target-repo) is always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# Controls protected-file protection. blocked (default): hard-block any patch that
# modifies package manifests (e.g. package.json, go.mod), engine instruction files
# (e.g. AGENTS.md, CLAUDE.md) or .github/ files. allowed: allow all changes.
# fallback-to-issue: create a review issue instead of pushing to the PR branch, so
# a human can review the changes before applying.
# (optional)
protected-files: "blocked"
# Exclusive allowlist of glob patterns. When set, every file in the patch must
# match at least one pattern — files outside the list are always refused,
# including normal source files. This is a restriction, not an exception: setting
# allowed-files: [".github/workflows/*"] blocks all other files. To allow multiple
# sets of files, list all patterns explicitly. Acts independently of the
# protected-files policy; both checks must pass. To modify a protected file, it
# must both match allowed-files and be permitted by protected-files (e.g.
# protected-files: allowed). Supports * (any characters except /) and ** (any
# characters including /).
# (optional)
allowed-files: []
# Array of strings
# List of glob patterns for files to exclude from the patch. Each pattern is
# passed to `git format-patch` as a `:(exclude)` magic pathspec, so
# matching files are stripped by git at generation time and will not appear in the
# commit. Excluded files are also not subject to `allowed-files` or
# `protected-files` checks. Supports * (any characters except /) and ** (any
# characters including /).
# (optional)
excluded-files: []
# Array of strings
# Transport format for packaging changes. "am" (default) uses git format-patch/git
# am. "bundle" uses git bundle, which preserves merge commit topology, per-commit
# authorship, and merge-resolution-only content.
# (optional)
patch-format: "am"
# Enable AI agents to minimize (hide) comments on issues or pull requests based on
# relevance, spam detection, or moderation rules.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable comment hiding with default configuration
hide-comment: null
# Option 2: Configuration for hiding comments on GitHub issues, pull requests, or
# discussions from agentic workflow output
hide-comment:
# Maximum number of comments to hide (default: 5) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository in format 'owner/repo' for cross-repository comment hiding.
# Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of allowed reasons for hiding comments. Default: all reasons allowed (spam,
# abuse, off_topic, outdated, resolved).
# (optional)
allowed-reasons: []
# Array of strings
# Controls whether the workflow requests discussions:write permission for
# hide-comment. Default: true (includes discussions:write). Set to false if your
# GitHub App lacks Discussions permission to prevent 422 errors during token
# generation.
# (optional)
discussions: true
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Enable AI agents to set or clear the type of GitHub issues. Use an empty string
# to clear the current type.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Null configuration allows setting any issue type
set-issue-type: null
# Option 2: Configuration for setting the type of GitHub issues from agentic
# workflow output
set-issue-type:
# Optional list of allowed issue type names (e.g. 'Bug', 'Feature'). If omitted,
# any type is allowed. Empty string is always allowed to clear the type.
# (optional)
allowed: []
# Array of strings
# Optional maximum number of set-issue-type operations (default: 5). Supports
# integer or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target for issue type: 'triggering' (default), '*' (any issue), or explicit
# issue number
# (optional)
target: "example-value"
# Target repository in format 'owner/repo' for cross-repository issue type
# setting. Takes precedence over trial target repo settings.
# (optional)
target-repo: "example-value"
# List of additional repositories in format 'owner/repo' where issue types can be
# set. When specified, the agent can use a 'repo' field in the output to specify
# which repository to target. The target repository (current or target-repo) is
# always implicitly allowed.
# (optional)
allowed-repos: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Dispatch workflow_dispatch events to other workflows. Used by orchestrators to
# delegate work to worker workflows with controlled maximum dispatch count.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for dispatching workflow_dispatch events to other
# workflows. Orchestrators use this to delegate work to worker workflows.
dispatch-workflow:
# List of workflow names (without .md extension) to allow dispatching. Each
# workflow must exist in .github/workflows/.
workflows: []
# Array of strings
# Maximum number of workflow dispatch operations per run (default: 1, max: 50)
# Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for dispatching workflows. Overrides global github-token if
# specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Target repository in format 'owner/repo' for cross-repository workflow dispatch.
# When specified, the workflow will be dispatched to the target repository instead
# of the current one.
# (optional)
target-repo: "example-value"
# Git ref (branch, tag, or SHA) to use when dispatching the workflow. For
# workflow_call relay scenarios this is auto-injected by the compiler from
# needs.activation.outputs.target_ref. Overrides the caller's GITHUB_REF.
# (optional)
target-ref: "example-value"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Shorthand array format: list of workflow names (without .md extension)
# to allow dispatching
dispatch-workflow: []
# Array items: string
# Dispatch repository_dispatch events to external repositories. Each sub-key
# defines a named dispatch tool with its own event_type, target repository, input
# schema, and execution limits.
# (optional)
dispatch_repository:
{}
# Call reusable workflows via workflow_call fan-out. The compiler generates static
# conditional jobs; the agent selects which worker to activate. Use this for
# orchestrator/dispatcher patterns within the same repository.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for calling reusable workflows via workflow_call
# fan-out. The compiler generates conditional `uses:` jobs at compile time; the
# agent selects which worker to activate at runtime.
call-workflow:
# List of workflow names (without .md extension) to allow calling. Each workflow
# must exist in .github/workflows/ and declare a workflow_call trigger.
workflows: []
# Array of strings
# Maximum number of workflow_call fan-out operations per run (default: 1, max:
# 50). Supports integer or GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token passed to called workflows. Overrides global github-token if
# specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Shorthand array format: list of workflow names (without .md extension)
# to allow calling
call-workflow: []
# Array items: string
# Enable AI agents to report when required MCP tools are unavailable. Used for
# workflow diagnostics and tool discovery.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for reporting missing tools from agentic workflow output
missing-tool:
# Maximum number of missing tool reports (default: unlimited) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Whether to create or update GitHub issues when tools are missing (default: true)
# (optional)
create-issue: true
# Prefix for issue titles when creating issues for missing tools (default:
# '[missing tool]')
# (optional)
title-prefix: "example-value"
# Labels to add to created issues for missing tools
# (optional)
labels: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable missing tool reporting with default configuration
missing-tool: null
# Option 3: Explicitly disable missing tool reporting (false). Missing tool
# reporting is enabled by default when safe-outputs is configured.
missing-tool: true
# Enable AI agents to report when required data or context is missing. Used for
# workflow troubleshooting and data validation.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for reporting missing data required to achieve workflow
# goals. Encourages AI agents to be truthful about data gaps instead of
# hallucinating information.
missing-data:
# Maximum number of missing data reports (default: unlimited) Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Whether to create or update GitHub issues when data is missing (default: true)
# (optional)
create-issue: true
# Prefix for issue titles when creating issues for missing data (default:
# '[missing data]')
# (optional)
title-prefix: "example-value"
# Labels to add to created issues for missing data
# (optional)
labels: []
# Array of strings
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable missing data reporting with default configuration
missing-data: null
# Option 3: Explicitly disable missing data reporting (false). Missing data
# reporting is enabled by default when safe-outputs is configured.
missing-data: true
# Enable AI agents to explicitly indicate no action is needed. Used for workflow
# control flow and conditional logic.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for no-op safe output (logging only, no GitHub API
# calls). Always available as a fallback to ensure human-visible artifacts.
noop:
# Maximum number of noop messages (default: 1) Supports integer or GitHub Actions
# expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Controls whether noop runs are reported as issue comments (default: true). Set
# to false to disable posting to the no-op runs issue.
# (optional)
report-as-issue: true
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable noop output with default configuration (max: 1)
noop: null
# Option 3: Explicitly disable noop output (false). Noop is enabled by default
# when safe-outputs is configured.
noop: true
# Enable AI agents to publish files (images, charts, reports) to an orphaned git
# branch for persistent storage and web access.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for publishing assets to an orphaned git branch
upload-asset:
# Branch name (default: 'assets/${{ github.workflow }}')
# (optional)
branch: "example-value"
# Maximum file size in KB (default: 10240 = 10MB)
# (optional)
max-size: 1
# Allowed file extensions (default: common non-executable types)
# (optional)
allowed-exts: []
# Array of strings
# Maximum number of assets to upload (default: 10) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# GitHub token to use for this specific output type. Overrides global github-token
# if specified.
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable asset publishing with default configuration
upload-asset: null
# Enable AI agents to edit and update GitHub release content, including release
# notes, assets, and metadata.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Configuration for updating GitHub release descriptions
update-release:
# Maximum number of releases to update (default: 1) Supports integer or GitHub
# Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Target repository for cross-repo release updates (format: owner/repo). If not
# specified, updates releases in the workflow's repository.
# (optional)
target-repo: "example-value"
# Controls whether AI-generated footer is added when updating the release body.
# When false, the visible footer content is omitted. Defaults to true.
# (optional)
footer: true
# If true, emit step summary messages instead of making GitHub API calls for this
# specific output type (preview mode)
# (optional)
staged: true
# Option 2: Enable release updates with default configuration
update-release: null
# If true, emit step summary messages instead of making GitHub API calls (preview
# mode)
# (optional)
staged: true
# Environment variables to pass to safe output jobs
# (optional)
env:
{}
# GitHub token to use for safe output jobs. Typically a secret reference like ${{
# secrets.GITHUB_TOKEN }} or ${{ secrets.CUSTOM_PAT }}
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# GitHub App credentials for minting installation access tokens. When configured,
# a token will be generated using the app credentials and used for all safe output
# operations.
# (optional)
github-app:
# GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.
app-id: "example-value"
# GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to
# mint a GitHub App token.
private-key: "example-value"
# Optional owner of the GitHub App installation (defaults to current repository
# owner if not specified)
# (optional)
owner: "example-value"
# Optional list of repositories to grant access to (defaults to current repository
# if not specified)
# (optional)
repositories: []
# Array of strings
# Optional extra GitHub App-only permissions to merge into the minted token. Only
# takes effect for tools.github.github-app; ignored in other github-app contexts.
# (optional)
permissions:
# Permission level for repository administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission for repository administration.
# (optional)
administration: "read"
# Permission level for Codespaces (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces: "read"
# Permission level for Codespaces lifecycle administration (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
codespaces-lifecycle-admin: "read"
# Permission level for Codespaces metadata (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces-metadata: "read"
# Permission level for user email addresses (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
email-addresses: "read"
# Permission level for repository environments (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
environments: "read"
# Permission level for git signing (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
git-signing: "read"
# Permission level for organization members (read/none; "write" is rejected by the
# compiler). Required for org team membership API calls.
# (optional)
members: "read"
# Permission level for organization administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-administration: "read"
# Permission level for organization announcement banners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-announcement-banners: "read"
# Permission level for organization Codespaces (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-codespaces: "read"
# Permission level for organization Copilot (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-copilot: "read"
# Permission level for organization custom org roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-org-roles: "read"
# Permission level for organization custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-properties: "read"
# Permission level for organization custom repository roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-repository-roles: "read"
# Permission level for organization events (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-events: "read"
# Permission level for organization webhooks (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-hooks: "read"
# Permission level for organization members management (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-members: "read"
# Permission level for organization packages (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-packages: "read"
# Permission level for organization personal access token requests (read/none;
# "write" is rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-token-requests: "read"
# Permission level for organization personal access tokens (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-tokens: "read"
# Permission level for organization plan (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-plan: "read"
# Permission level for organization self-hosted runners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-self-hosted-runners: "read"
# Permission level for organization user blocking (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-user-blocking: "read"
# Permission level for repository custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
repository-custom-properties: "read"
# Permission level for repository webhooks (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
repository-hooks: "read"
# Permission level for single file access (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
single-file: "read"
# Permission level for team discussions (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
team-discussions: "read"
# Permission level for Dependabot vulnerability alerts (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
vulnerability-alerts: "read"
# Permission level for GitHub Actions workflow files (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
workflows: "read"
# Maximum allowed size for git patches in kilobytes (KB). Defaults to 1024 KB (1
# MB). If patch exceeds this size, the job will fail.
# (optional)
max-patch-size: 1
# Enable AI agents to report detected security threats, policy violations, or
# suspicious patterns for security review.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Enable or disable threat detection for safe outputs (defaults to true
# when safe-outputs are configured)
threat-detection: true
# Option 2: Threat detection configuration object
threat-detection:
# Whether threat detection is enabled
# (optional)
enabled: true
# Additional custom prompt instructions to append to threat detection analysis
# (optional)
prompt: "example-value"
# AI engine configuration specifically for threat detection (overrides main
# workflow engine). Set to false to disable AI-based threat detection. Supports
# same format as main engine field when not false.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Disable AI engine for threat detection (only run custom steps)
engine: true
# Option 2: undefined
# Array of extra job steps to run before engine execution
# (optional)
steps: []
# Array of extra job steps to run after engine execution
# (optional)
post-steps: []
# Runner specification for the detection job. Overrides agent.runs-on for the
# detection job only. Defaults to agent.runs-on.
# (optional)
runs-on: "example-value"
# Custom safe-output jobs that can be executed based on agentic workflow output.
# Job names containing dashes will be automatically normalized to underscores
# (e.g., 'send-notification' becomes 'send_notification').
# (optional)
jobs:
{}
# Inline JavaScript script handlers that run inside the consolidated safe-outputs
# job handler loop. Unlike 'jobs' (which create separate GitHub Actions jobs),
# scripts execute in-process alongside the built-in handlers. Users write only the
# body of the main function — the compiler wraps it with 'async function
# main(config = {}) { ... }' and 'module.exports = { main };' automatically.
# Script names containing dashes will be automatically normalized to underscores
# (e.g., 'post-slack-message' becomes 'post_slack_message').
# (optional)
scripts:
{}
# Custom message templates for safe-output footer and notification messages.
# Available placeholders: {workflow_name} (workflow name), {run_url} (GitHub
# Actions run URL), {triggering_number} (issue/PR/discussion number),
# {workflow_source} (owner/repo/path@ref), {workflow_source_url} (GitHub URL to
# source), {operation} (safe-output operation name for staged mode).
# (optional)
messages:
# Custom footer message template for AI-generated content. Available placeholders:
# {workflow_name}, {run_url}, {triggering_number}, {workflow_source},
# {workflow_source_url}. Example: '> Generated by [{workflow_name}]({run_url})'
# (optional)
footer: "example-value"
# Custom installation instructions template appended to the footer. Available
# placeholders: {workflow_source}, {workflow_source_url}. Example: '> Install: `gh
# aw add {workflow_source}`'
# (optional)
footer-install: "example-value"
# Custom footer message template for workflow recompile issues. Available
# placeholders: {workflow_name}, {run_url}, {repository}. Example: '> Workflow
# sync report by [{workflow_name}]({run_url}) for {repository}'
# (optional)
footer-workflow-recompile: "example-value"
# Custom footer message template for comments on workflow recompile issues.
# Available placeholders: {workflow_name}, {run_url}, {repository}. Example: '>
# Update from [{workflow_name}]({run_url}) for {repository}'
# (optional)
footer-workflow-recompile-comment: "example-value"
# Custom title template for staged mode preview. Available placeholders:
# {operation}. Example: ' Preview: {operation}'
# (optional)
staged-title: "example-value"
# Custom description template for staged mode preview. Available placeholders:
# {operation}. Example: 'The following {operation} would occur if staged mode was
# disabled:'
# (optional)
staged-description: "example-value"
# Custom message template for workflow activation comment. Available placeholders:
# {workflow_name}, {run_url}, {event_type}. Default: 'Agentic
# [{workflow_name}]({run_url}) triggered by this {event_type}.'
# (optional)
run-started: "example-value"
# Custom message template for successful workflow completion. Available
# placeholders: {workflow_name}, {run_url}. Default: '✓ Agentic
# [{workflow_name}]({run_url}) completed successfully.'
# (optional)
run-success: "example-value"
# Custom message template for failed workflow. Available placeholders:
# {workflow_name}, {run_url}, {status}. Default: '✗ Agentic
# [{workflow_name}]({run_url}) {status} and wasn't able to produce a result.'
# (optional)
run-failure: "example-value"
# Custom message template for detection job failure. Available placeholders:
# {workflow_name}, {run_url}. Default: '! Security scanning failed for
# [{workflow_name}]({run_url}). Review the logs for details.'
# (optional)
detection-failure: "example-value"
# Custom footer template for agent failure tracking issues. Available
# placeholders: {workflow_name}, {run_url}. Default: '> Agent failure tracked by
# [{workflow_name}]({run_url})'
# (optional)
agent-failure-issue: "example-value"
# Custom footer template for comments on agent failure tracking issues. Available
# placeholders: {workflow_name}, {run_url}. Default: '> Agent failure update from
# [{workflow_name}]({run_url})'
# (optional)
agent-failure-comment: "example-value"
# Custom message template for pull request creation link appended to the
# activation comment. Available placeholders: {item_number}, {item_url}. Default:
# 'Pull request created: [#{item_number}]({item_url})'
# (optional)
pull-request-created: "example-value"
# Custom message template for issue creation link appended to the activation
# comment. Available placeholders: {item_number}, {item_url}. Default: 'Issue
# created: [#{item_number}]({item_url})'
# (optional)
issue-created: "example-value"
# Custom message template for commit push link appended to the activation comment.
# Available placeholders: {commit_sha}, {short_sha}, {commit_url}. Default:
# 'Commit pushed: [`{short_sha}`]({commit_url})'
# (optional)
commit-pushed: "example-value"
# When enabled, workflow completion notifier creates a new comment instead of
# editing the activation comment. Creates an append-only timeline of workflow
# runs. Default: false
# (optional)
append-only-comments: true
# Configuration for @mention filtering in safe outputs. Controls whether and how
# @mentions in AI-generated content are allowed or escaped.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple boolean mode: false = always escape mentions, true = always
# allow mentions (error in strict mode)
mentions: true
# Option 2: Advanced configuration for @mention filtering with fine-grained
# control
mentions:
# Allow mentions of repository team members (collaborators with any permission
# level, excluding bots). Default: true
# (optional)
allow-team-members: true
# Allow mentions inferred from event context (issue/PR authors, assignees,
# commenters). Default: true
# (optional)
allow-context: true
# List of user/bot names always allowed to be mentioned. Bots are not allowed by
# default unless listed here.
# (optional)
allowed: []
# Array of strings
# Maximum number of mentions allowed per message. Default: 50 Supports integer or
# GitHub Actions expression (e.g. '${{ inputs.max }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Global footer control for all safe outputs. When false, omits visible
# AI-generated footer content from all created/updated entities (issues, PRs,
# discussions, releases) while still including XML markers for searchability.
# Individual safe-output types (create-issue, update-issue, etc.) can override
# this by specifying their own footer field. Defaults to true.
# (optional)
footer: true
# When set to false or "false", disables all activation and fallback comments
# entirely (run-started, run-success, run-failure, PR/issue creation links).
# Supports templatable boolean values including GitHub Actions expressions (e.g.
# ${{ inputs.activation-comments }}). Default: true
# (optional)
activation-comments: null
# When true, creates a parent '[aw] Failed runs' issue that tracks all workflow
# failures as sub-issues. Helps organize failure tracking but may be unnecessary
# in smaller repositories. Defaults to false.
# (optional)
group-reports: true
# When false, disables creating failure tracking issues when workflows fail.
# Useful for workflows where failures are expected or handled elsewhere. Defaults
# to true.
# (optional)
report-failure-as-issue: true
# Repository to create failure tracking issues in, in the format 'owner/repo'.
# Useful when the current repository has issues disabled. Defaults to the current
# repository.
# (optional)
failure-issue-repo: "example-value"
# Maximum number of bot trigger references (e.g. 'fixes #123', 'closes #456')
# allowed in output before all of them are neutralized. Default: 10. Supports
# integer or GitHub Actions expression (e.g. '${{ inputs.max-bot-mentions }}').
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: integer
max-bot-mentions: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max-bot-mentions: "example-value"
# Override the id-token permission for the safe-outputs job. Use 'write' to
# force-enable the id-token: write permission (required for OIDC authentication
# with cloud providers). Use 'none' to suppress automatic detection and prevent
# adding id-token: write even when vault/OIDC actions are detected in steps. By
# default, the compiler auto-detects known OIDC/vault actions
# (aws-actions/configure-aws-credentials, azure/login, google-github-actions/auth,
# hashicorp/vault-action, cyberark/conjur-action) and adds id-token: write
# automatically.
# (optional)
id-token: "write"
# Concurrency group for the safe-outputs job. When set, the safe-outputs job will
# use this concurrency group with cancel-in-progress: false. Supports GitHub
# Actions expressions.
# (optional)
concurrency-group: "example-value"
# Override the GitHub deployment environment for the safe-outputs job. When set,
# this environment is used instead of the top-level environment: field. When not
# set, the top-level environment: field is propagated automatically so that
# environment-scoped secrets are accessible in the safe-outputs job.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Environment name as a string
environment: "example-value"
# Option 2: Environment object with name and optional URL
environment:
# The name of the environment configured in the repo
name: "My Workflow"
# A deployment URL
# (optional)
url: "example-value"
# Runner specification for all safe-outputs jobs (activation, create-issue,
# add-comment, etc.). Single runner label (e.g., 'ubuntu-slim', 'ubuntu-latest',
# 'windows-latest', 'self-hosted'). Defaults to 'ubuntu-slim'. See
# https://github.blog/changelog/2025-10-28-1-vcpu-linux-runner-now-available-in-github-actions-in-public-preview/
# (optional)
runs-on: "example-value"
# Custom steps to inject into all safe-output jobs. These steps run after checking
# out the repository and setting up the action, and before any safe-output code
# executes.
# (optional)
steps: []
# Custom GitHub Actions to mount as once-callable MCP tools. Each action is
# resolved at compile time to derive its input schema from action.yml, and a
# guarded `uses:` step is injected in the safe_outputs job. Action names
# containing dashes will be automatically normalized to underscores (e.g.,
# 'add-smoked-label' becomes 'add_smoked_label').
# (optional)
actions:
{}
# Configuration for secret redaction behavior in workflow outputs and artifacts
# (optional)
secret-masking:
# Additional secret redaction steps to inject after the built-in secret redaction.
# Use this to mask secrets in generated files using custom patterns.
# (optional)
steps: []
# Optional observability output settings for workflow runs.
# (optional)
observability: {}
# Allow list of bot identifiers that can trigger the workflow even if they don't
# meet the required role permissions. When the actor is in this list, the bot must
# be active (installed) on the repository to trigger the workflow.
# (optional)
bots: []
# Array of Bot identifier/name (e.g., 'dependabot[bot]', 'renovate[bot]',
# 'github-actions[bot]')
# Rate limiting configuration to restrict how frequently users can trigger the
# workflow. Helps prevent abuse and resource exhaustion from programmatically
# triggered events.
# (optional)
rate-limit:
# Maximum number of workflow runs allowed per user within the time window.
# Required field. Supports integer or GitHub Actions expression (e.g. '${{
# inputs.max }}').
# This field supports multiple formats (oneOf):
# Option 1: integer
max: 1
# Option 2: GitHub Actions expression that resolves to an integer at runtime
max: "example-value"
# Time window in minutes for rate limiting. Defaults to 60 (1 hour). Maximum: 180
# (3 hours).
# (optional)
window: 1
# Optional list of event types to apply rate limiting to. If not specified, rate
# limiting applies to all programmatically triggered events (e.g.,
# workflow_dispatch, issue_comment, pull_request_review).
# (optional)
events: []
# Array of strings
# Optional list of roles that are exempt from rate limiting. Defaults to ['admin',
# 'maintain', 'write'] if not specified. Users with any of these roles will not be
# subject to rate limiting checks. To apply rate limiting to all users, set to an
# empty array: []
# (optional)
ignored-roles: []
# Array of strings
# Enable strict mode validation for enhanced security and compliance. Strict mode
# enforces: (1) Write Permissions - refuses contents:write, issues:write,
# pull-requests:write; requires safe-outputs instead, (2) Network Configuration -
# requires explicit network configuration with no standalone wildcard '*' in
# allowed domains (patterns like '*.example.com' are allowed), (3) Action Pinning
# - enforces actions pinned to commit SHAs instead of tags/branches, (4) MCP
# Network - requires network configuration for custom MCP servers with containers,
# (5) Deprecated Fields - refuses deprecated frontmatter fields. Can be enabled
# per-workflow via 'strict: true' in frontmatter, or disabled via 'strict: false'.
# CLI flag takes precedence over frontmatter (gh aw compile --strict enforces
# strict mode). Defaults to true. See:
# https://github.github.com/gh-aw/reference/frontmatter/#strict-mode-strict
# (optional)
strict: true
# Mark the workflow as private, preventing it from being added to other
# repositories via 'gh aw add'. A workflow with private: true is not meant to be
# shared outside its repository.
# (optional)
private: true
# Control whether the compile-agentic version update check runs in the activation
# job. When true (default), the activation job downloads config.json from the
# gh-aw repository and verifies the compiled version is not blocked and meets the
# minimum supported version. Set to false to disable the check (not allowed in
# strict mode). See:
# https://github.github.com/gh-aw/reference/frontmatter/#check-for-updates
# (optional)
check-for-updates: true
# MCP Scripts configuration for defining custom lightweight MCP tools as
# JavaScript, shell scripts, or Python scripts. Tools are mounted in an MCP server
# and have access to secrets specified by the user. Only one of 'script'
# (JavaScript), 'run' (shell), or 'py' (Python) must be specified per tool.
# (optional)
mcp-scripts:
{}
# Runtime environment version overrides. Allows customizing runtime versions
# (e.g., Node.js, Python) or defining new runtimes. Runtimes from imported shared
# workflows are also merged.
# (optional)
runtimes:
{}
# Checkout configuration for the agent job. Controls how actions/checkout is
# invoked. Can be a single checkout configuration, an array for multiple
# checkouts, or false to disable the default checkout step entirely (dev-mode
# checkouts are unaffected).
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Single checkout configuration for the default workspace
# Option 2: Multiple checkout configurations
checkout: []
# Array items: undefined
# Option 3: Set to false to disable the default checkout step. The agent job will
# not check out any repository (dev-mode checkouts are unaffected).
checkout: false
# APM package references to install. Supports array format (list of package slugs)
# or object format with packages and isolated fields.
# (optional)
# This field supports multiple formats (oneOf):
# Option 1: Simple array of APM package references.
dependencies: []
# Array items: APM package reference in the format 'org/repo' or
# 'org/repo/path/to/skill'
# Option 2: Object format with packages and optional isolated flag.
dependencies:
# List of APM package references to install.
packages: []
# Array of APM package reference in the format 'org/repo' or
# 'org/repo/path/to/skill'
# If true, agent restore step clears primitive dirs before unpacking.
# (optional)
isolated: true
# GitHub App credentials for minting installation access tokens used by APM to
# access cross-org private repositories.
# (optional)
github-app:
# GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.
app-id: "example-value"
# GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to
# mint a GitHub App token.
private-key: "example-value"
# Optional owner of the GitHub App installation (defaults to current repository
# owner if not specified)
# (optional)
owner: "example-value"
# Optional list of repositories to grant access to (defaults to current repository
# if not specified)
# (optional)
repositories: []
# Array of strings
# Optional extra GitHub App-only permissions to merge into the minted token. Only
# takes effect for tools.github.github-app; ignored in other github-app contexts.
# (optional)
permissions:
# Permission level for repository administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission for repository administration.
# (optional)
administration: "read"
# Permission level for Codespaces (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces: "read"
# Permission level for Codespaces lifecycle administration (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
codespaces-lifecycle-admin: "read"
# Permission level for Codespaces metadata (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces-metadata: "read"
# Permission level for user email addresses (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
email-addresses: "read"
# Permission level for repository environments (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
environments: "read"
# Permission level for git signing (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
git-signing: "read"
# Permission level for organization members (read/none; "write" is rejected by the
# compiler). Required for org team membership API calls.
# (optional)
members: "read"
# Permission level for organization administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-administration: "read"
# Permission level for organization announcement banners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-announcement-banners: "read"
# Permission level for organization Codespaces (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-codespaces: "read"
# Permission level for organization Copilot (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-copilot: "read"
# Permission level for organization custom org roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-org-roles: "read"
# Permission level for organization custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-properties: "read"
# Permission level for organization custom repository roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-repository-roles: "read"
# Permission level for organization events (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-events: "read"
# Permission level for organization webhooks (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-hooks: "read"
# Permission level for organization members management (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-members: "read"
# Permission level for organization packages (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-packages: "read"
# Permission level for organization personal access token requests (read/none;
# "write" is rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-token-requests: "read"
# Permission level for organization personal access tokens (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-tokens: "read"
# Permission level for organization plan (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-plan: "read"
# Permission level for organization self-hosted runners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-self-hosted-runners: "read"
# Permission level for organization user blocking (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-user-blocking: "read"
# Permission level for repository custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
repository-custom-properties: "read"
# Permission level for repository webhooks (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
repository-hooks: "read"
# Permission level for single file access (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
single-file: "read"
# Permission level for team discussions (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
team-discussions: "read"
# Permission level for Dependabot vulnerability alerts (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
vulnerability-alerts: "read"
# Permission level for GitHub Actions workflow files (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
workflows: "read"
# Environment variables to set on the APM pack step (e.g., tokens or registry
# URLs).
# (optional)
env:
{}
# GitHub token expression to authenticate APM with private package repositories.
# Uses cascading fallback (GH_AW_PLUGINS_TOKEN → GH_AW_GITHUB_TOKEN →
# GITHUB_TOKEN) when not specified. Takes effect unless github-app is also
# configured (which takes precedence).
# (optional)
github-token: "${{ secrets.GITHUB_TOKEN }}"
# Top-level GitHub App configuration used as a fallback for all nested github-app
# token minting operations (on, safe-outputs, checkout, tools.github,
# dependencies). When a nested section does not define its own github-app, this
# top-level configuration is used automatically.
# (optional)
github-app:
# GitHub App ID (e.g., '${{ vars.APP_ID }}'). Required to mint a GitHub App token.
app-id: "example-value"
# GitHub App private key (e.g., '${{ secrets.APP_PRIVATE_KEY }}'). Required to
# mint a GitHub App token.
private-key: "example-value"
# Optional owner of the GitHub App installation (defaults to current repository
# owner if not specified)
# (optional)
owner: "example-value"
# Optional list of repositories to grant access to (defaults to current repository
# if not specified)
# (optional)
repositories: []
# Array of strings
# Optional extra GitHub App-only permissions to merge into the minted token. Only
# takes effect for tools.github.github-app; ignored in other github-app contexts.
# (optional)
permissions:
# Permission level for repository administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission for repository administration.
# (optional)
administration: "read"
# Permission level for Codespaces (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces: "read"
# Permission level for Codespaces lifecycle administration (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
codespaces-lifecycle-admin: "read"
# Permission level for Codespaces metadata (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
codespaces-metadata: "read"
# Permission level for user email addresses (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
email-addresses: "read"
# Permission level for repository environments (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
environments: "read"
# Permission level for git signing (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
git-signing: "read"
# Permission level for organization members (read/none; "write" is rejected by the
# compiler). Required for org team membership API calls.
# (optional)
members: "read"
# Permission level for organization administration (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-administration: "read"
# Permission level for organization announcement banners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-announcement-banners: "read"
# Permission level for organization Codespaces (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-codespaces: "read"
# Permission level for organization Copilot (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-copilot: "read"
# Permission level for organization custom org roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-org-roles: "read"
# Permission level for organization custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-properties: "read"
# Permission level for organization custom repository roles (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-custom-repository-roles: "read"
# Permission level for organization events (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-events: "read"
# Permission level for organization webhooks (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-hooks: "read"
# Permission level for organization members management (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-members: "read"
# Permission level for organization packages (read/none; "write" is rejected by
# the compiler). GitHub App-only permission.
# (optional)
organization-packages: "read"
# Permission level for organization personal access token requests (read/none;
# "write" is rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-token-requests: "read"
# Permission level for organization personal access tokens (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-personal-access-tokens: "read"
# Permission level for organization plan (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
organization-plan: "read"
# Permission level for organization self-hosted runners (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
organization-self-hosted-runners: "read"
# Permission level for organization user blocking (read/none; "write" is rejected
# by the compiler). GitHub App-only permission.
# (optional)
organization-user-blocking: "read"
# Permission level for repository custom properties (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
repository-custom-properties: "read"
# Permission level for repository webhooks (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
repository-hooks: "read"
# Permission level for single file access (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
single-file: "read"
# Permission level for team discussions (read/none; "write" is rejected by the
# compiler). GitHub App-only permission.
# (optional)
team-discussions: "read"
# Permission level for Dependabot vulnerability alerts (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
vulnerability-alerts: "read"
# Permission level for GitHub Actions workflow files (read/none; "write" is
# rejected by the compiler). GitHub App-only permission.
# (optional)
workflows: "read"
# Schema for validating 'with' input values when this workflow is imported by
# another workflow using the 'uses'/'with' syntax. Defines the expected
# parameters, their types, and whether they are required. Scalar inputs are
# accessible via '${{ github.aw.import-inputs. }}' expressions. Object
# inputs (type: object) allow one-level deep sub-fields accessible via '${{
# github.aw.import-inputs.. }}' expressions.
# (optional)
import-schema:
{}
---
```
## Additional Information
[Section titled “Additional Information”](#additional-information)
* Fields marked with `(optional)` are not required
* Fields with multiple options show all possible formats
* See the [Frontmatter guide](/gh-aw/reference/frontmatter/) for detailed explanations and examples
* See individual reference pages for specific topics like [Triggers](/gh-aw/reference/triggers/), [Tools](/gh-aw/reference/tools/), and [Safe Outputs](/gh-aw/reference/safe-outputs/)
# Frontmatter Hash Specification
> Specification for computing deterministic hashes of agentic workflow frontmatter
# Frontmatter Hash Specification
[Section titled “Frontmatter Hash Specification”](#frontmatter-hash-specification)
This document specifies the algorithm for computing a deterministic hash of agentic workflow frontmatter, including contributions from imported workflows.
## Purpose
[Section titled “Purpose”](#purpose)
The frontmatter hash provides:
1. **Stale lock detection**: Identify when the compiled lock file is out of sync with the source workflow (e.g. after editing the `.md` file without recompiling)
2. **Reproducibility**: Ensure identical configurations produce identical hashes across languages (Go and JavaScript)
3. **Change detection**: Verify that workflow configuration has not changed between compilation and execution
## Hash Algorithm
[Section titled “Hash Algorithm”](#hash-algorithm)
### 1. Input Collection
[Section titled “1. Input Collection”](#1-input-collection)
Collect all frontmatter from the main workflow and all imported workflows in **breadth-first order** (BFS traversal):
1. **Main workflow frontmatter**: The frontmatter from the root workflow file
2. **Imported workflow frontmatter**: Frontmatter from each imported file in BFS processing order
* Includes transitively imported files (imports of imports)
* Agent files (`.github/agents/*.md`) only contribute markdown content, not frontmatter
### 2. Field Selection
[Section titled “2. Field Selection”](#2-field-selection)
Include the following frontmatter fields in the hash computation:
**Core Configuration:**
* `engine` - AI engine specification
* `on` - Workflow triggers
* `permissions` - GitHub Actions permissions
* `tracker-id` - Workflow tracker identifier
**Tool and Integration:**
* `tools` - Tool configurations (GitHub, Playwright, etc.)
* `mcp-servers` - MCP server configurations
* `network` - Network access permissions
* `safe-outputs` - Safe output configurations
* `mcp-scripts` - Safe input configurations
**Runtime Configuration:**
* `runtimes` - Runtime version specifications (Node.js, Python, etc.)
* `services` - Container services
* `cache` - Caching configuration
**Workflow Structure:**
* `steps` - Custom workflow steps
* `post-steps` - Post-execution steps
* `jobs` - GitHub Actions job definitions
**Metadata:**
* `description` - Workflow description
* `labels` - Workflow labels
* `bots` - Authorized bot list
* `timeout-minutes` - Workflow timeout
* `secret-masking` - Secret masking configuration
**Import Metadata:**
* `imports` - List of imported workflow paths (for traceability)
* `inputs` - Input parameter definitions
**Excluded Fields:**
* Markdown body content (not part of frontmatter)
* Comments and whitespace variations
* Field ordering (normalized during processing)
### 3. Canonical JSON Serialization
[Section titled “3. Canonical JSON Serialization”](#3-canonical-json-serialization)
Transform the collected frontmatter into a canonical JSON representation:
#### 3.1 Merge Strategy
[Section titled “3.1 Merge Strategy”](#31-merge-strategy)
For each workflow in BFS order:
1. Parse frontmatter into a structured object
2. Merge with accumulated frontmatter using these rules:
* **Replace**: `engine`, `on`, `tracker-id`, `description`, `timeout-minutes`
* **Deep merge**: `tools`, `mcp-servers`, `network`, `permissions`, `runtimes`, `cache`, `services`
* **Append**: `steps`, `post-steps`, `safe-outputs`, `mcp-scripts`, `jobs`
* **Union**: `labels`, `bots` (deduplicated)
* **Track**: `imports` (list of all imported paths)
#### 3.2 Normalization Rules
[Section titled “3.2 Normalization Rules”](#32-normalization-rules)
Apply these normalization rules to ensure deterministic output:
1. **Key Sorting**: Sort all object keys alphabetically at every level
2. **Array Ordering**: Preserve array order as-is (no sorting of array elements)
3. **Whitespace**: Use minimal whitespace (no pretty-printing)
4. **Number Format**: Represent numbers without exponents (e.g., `120` not `1.2e2`)
5. **Boolean Values**: Use lowercase `true` and `false`
6. **Null Handling**: Include `null` values explicitly
7. **Empty Containers**: Include empty objects `{}` and empty arrays `[]`
8. **String Escaping**: Use JSON standard escaping (quotes, backslashes, control characters)
#### 3.3 Serialization Format
[Section titled “3.3 Serialization Format”](#33-serialization-format)
The canonical JSON includes all frontmatter fields plus version information:
```json
{
"bots": ["copilot"],
"cache": {},
"description": "Daily audit of workflow runs",
"engine": "claude",
"imports": ["shared/mcp/gh-aw.md", "shared/jqschema.md"],
"jobs": {},
"labels": ["audit", "automation"],
"mcp-servers": {},
"network": {"allowed": ["api.github.com"]},
"on": {"schedule": "daily"},
"permissions": {"actions": "read", "contents": "read"},
"post-steps": [],
"runtimes": {"node": {"version": "20"}},
"mcp-scripts": {},
"safe-outputs": {"create-discussion": {"category": "audits"}},
"services": {},
"steps": [],
"template-expressions": ["${{ env.MY_VAR }}"],
"timeout-minutes": 30,
"tools": {"repo-memory": {"branch-name": "memory/audit"}},
"tracker-id": "audit-workflows-daily",
"versions": {
"agents": "v0.0.84",
"awf": "v0.11.2",
"gh-aw": "dev"
}
}
```
### 4. Version Information
[Section titled “4. Version Information”](#4-version-information)
The hash includes version numbers to ensure hash changes when dependencies are upgraded:
* **gh-aw**: The compiler version (e.g., “0.1.0” or “dev”)
* **awf**: The firewall version (e.g., “v0.11.2”)
* **agents**: The MCP gateway version (e.g., “v0.0.84”)
This ensures that upgrading any component invalidates existing hashes.
1. **Serialize**: Convert the merged and normalized frontmatter to canonical JSON
2. **Add Versions**: Include version information for gh-aw, awf (firewall), and agents (MCP gateway)
3. **Hash**: Compute SHA-256 hash of the JSON string (UTF-8 encoded)
4. **Encode**: Represent the hash as a lowercase hexadecimal string (64 characters)
**Example:**
```plaintext
Input JSON: {"engine":"copilot","on":{"schedule":"daily"},"versions":{"agents":"v0.0.84","awf":"v0.11.2","gh-aw":"dev"}}
SHA-256: a1b2c3d4e5f6... (64 hex characters)
```
### 5. Cross-Language Consistency
[Section titled “5. Cross-Language Consistency”](#5-cross-language-consistency)
Both Go and JavaScript implementations MUST:
* Use the same field selection and merging rules
* Produce identical canonical JSON (byte-for-byte)
* Use SHA-256 hash function
* Encode output as lowercase hexadecimal
**Test cases** must verify identical hashes across both implementations for:
* Empty frontmatter
* Single-file workflows (no imports)
* Multi-level imports (2+ levels deep)
* All field types (strings, numbers, booleans, arrays, objects)
* Special characters and escaping
* All workflows in the repository
## Implementation Notes
[Section titled “Implementation Notes”](#implementation-notes)
### Go Implementation
[Section titled “Go Implementation”](#go-implementation)
* Use `encoding/json` with `json.Marshal()`
* Sort keys using a custom marshaler or post-processing
* Use `crypto/sha256` for hashing
* Use `hex.EncodeToString()` for hexadecimal encoding
### JavaScript Implementation
[Section titled “JavaScript Implementation”](#javascript-implementation)
* Use native `JSON.stringify()` with sorted keys
* Use Node.js `crypto.createHash('sha256')` for hashing
* Use `.digest('hex')` for hexadecimal encoding
* Ensure identical key sorting as Go implementation
### Hash Storage and Verification
[Section titled “Hash Storage and Verification”](#hash-storage-and-verification)
1. **Compilation**: The Go compiler computes the hash and writes it to the workflow log file
2. **Execution**: The JavaScript custom action:
* Reads the hash from the log file
* Recomputes the hash from the workflow file
* Compares the two hashes
* Creates a GitHub issue if they differ (indicating frontmatter modification)
## Security Considerations
[Section titled “Security Considerations”](#security-considerations)
* The hash is **not cryptographically secure** for authentication (no HMAC/signing)
* The hash is designed to **detect stale lock files** — it catches cases where the frontmatter has changed since the lock file was last compiled
* The hash **does not guarantee tamper protection**: anyone with write access to the repository can modify both the `.md` source and the `.lock.yml` file together, bypassing detection
* Always validate workflow sources through proper code review processes
## Versioning
[Section titled “Versioning”](#versioning)
This is version 1.0 of the frontmatter hash specification.
Future versions may:
* Add additional fields
* Change normalization rules
* Use different hash algorithms
Version changes will be documented and backward compatibility maintained where possible.
# Fuzzy Schedule Time Syntax Specification
> Formal specification for the fuzzy schedule time syntax following W3C conventions
**Version**: 1.2.0 **Status**: Draft Specification\
**Latest Version**: [fuzzy-schedule-specification](/gh-aw/reference/fuzzy-schedule-specification/)\
**Editor**: GitHub Agentic Workflows Team
***
## Abstract
[Section titled “Abstract”](#abstract)
This specification defines the Fuzzy Schedule Time Syntax, a human-friendly scheduling language for GitHub Agentic Workflows that automatically distributes workflow execution times to prevent server load spikes. The syntax supports daily, hourly, weekly, and interval-based schedules with optional time constraints and timezone conversions. The specification includes a deterministic scattering algorithm that uses hash functions to assign consistent execution times to workflows based on their identifiers, ensuring predictable behavior across multiple compilations while distributing load across an organization’s infrastructure.
## Status of This Document
[Section titled “Status of This Document”](#status-of-this-document)
This section describes the status of this document at the time of publication. This is a draft specification and may be updated, replaced, or made obsolete by other documents at any time.
This document is governed by the GitHub Agentic Workflows project specifications process.
## Table of Contents
[Section titled “Table of Contents”](#table-of-contents)
1. [Introduction](#1-introduction)
2. [Conformance](#2-conformance)
3. [Core Syntax](#3-core-syntax)
4. [Time Specifications](#4-time-specifications)
5. [Timezone Support](#5-timezone-support)
6. [Scattering Algorithm](#6-scattering-algorithm)
7. [Cron Expression Generation](#7-cron-expression-generation)
8. [Error Handling](#8-error-handling)
9. [Compliance Testing](#9-compliance-testing)
***
## 1. Introduction
[Section titled “1. Introduction”](#1-introduction)
### 1.1 Purpose
[Section titled “1.1 Purpose”](#11-purpose)
The Fuzzy Schedule Time Syntax addresses the problem of server load spikes that occur when multiple workflows execute simultaneously using fixed-time schedules. Traditional cron expressions require explicit time specifications, leading developers to commonly use convenient times (e.g., midnight, on-the-hour) that create load concentration. This specification defines a natural language syntax that automatically distributes execution times while preserving schedule semantics.
### 1.2 Scope
[Section titled “1.2 Scope”](#12-scope)
This specification covers:
* Natural language schedule expressions for daily, hourly, weekly, and interval-based schedules
* Time constraint syntax using `around` and `between` modifiers
* Timezone conversion syntax for local-to-UTC time translation
* Deterministic scattering algorithm for execution time distribution
* Cron expression generation from fuzzy syntax
* Validation requirements and error handling
This specification does NOT cover:
* Standard cron expression syntax (handled by GitHub Actions)
* Monthly or yearly schedule patterns
* Dynamic schedule adjustment based on load metrics
* Schedule conflict resolution between workflows
### 1.3 Design Goals
[Section titled “1.3 Design Goals”](#13-design-goals)
This specification prioritizes:
1. **Human readability**: Natural language expressions that clearly communicate intent
2. **Load distribution**: Automatic scattering prevents simultaneous workflow execution
3. **Determinism**: Same workflow identifier always produces same execution time
4. **Predictability**: Execution times remain consistent across recompilations
5. **Timezone awareness**: Support for local time specifications with UTC conversion
***
## 2. Conformance
[Section titled “2. Conformance”](#2-conformance)
### 2.1 Conformance Classes
[Section titled “2.1 Conformance Classes”](#21-conformance-classes)
A **conforming implementation** is a parser that satisfies all MUST, MUST NOT, REQUIRED, SHALL, and SHALL NOT requirements in this specification.
A **conforming fuzzy schedule expression** is a schedule string that conforms to the syntax grammar defined in Section 3 and produces a valid fuzzy cron placeholder.
A **conforming scattering implementation** is an implementation that satisfies all scattering algorithm requirements in Section 6.
### 2.2 Requirements Notation
[Section titled “2.2 Requirements Notation”](#22-requirements-notation)
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
### 2.3 Compliance Levels
[Section titled “2.3 Compliance Levels”](#23-compliance-levels)
**Level 1 (Basic)**: Supports daily and weekly schedules without time constraints
**Level 2 (Standard)**: Adds support for time constraints (`around`, `between`) and hourly schedules
**Level 3 (Complete)**: Includes timezone conversion, interval schedules, and bi-weekly/tri-weekly patterns
***
## 3. Core Syntax
[Section titled “3. Core Syntax”](#3-core-syntax)
### 3.1 Grammar Definition
[Section titled “3.1 Grammar Definition”](#31-grammar-definition)
A fuzzy schedule expression MUST conform to the following ABNF grammar:
```text
fuzzy-schedule = daily-schedule / hourly-schedule / weekly-schedule / interval-schedule
daily-schedule = "daily" [time-constraint]
weekly-schedule = "weekly" ["on" weekday] [time-constraint]
hourly-schedule = "hourly" / ("every" hour-interval)
interval-schedule = "every" (minute-interval / hour-interval / day-interval / week-interval)
time-constraint = around-constraint / between-constraint
around-constraint = "around" time-spec
between-constraint = "between" time-spec "and" time-spec
time-spec = (hour-24 ":" minute) [utc-offset]
/ (hour-12 am-pm) [utc-offset]
/ time-keyword [utc-offset]
time-keyword = "midnight" / "noon"
am-pm = "am" / "pm"
utc-offset = "utc" ("+" / "-") (hours / hours ":" minutes)
weekday = "sunday" / "monday" / "tuesday" / "wednesday"
/ "thursday" / "friday" / "saturday"
hour-24 = 1*2DIGIT ; 0-23
hour-12 = 1*2DIGIT ; 1-12
minute = 2DIGIT ; 00-59
hours = 1*2DIGIT
minutes = 2DIGIT
minute-interval = 1*DIGIT ("m" / "minutes" / "minute")
hour-interval = 1*DIGIT ("h" / "hours" / "hour")
day-interval = 1*DIGIT ("d" / "days" / "day")
week-interval = 1*DIGIT ("w" / "weeks" / "week")
```
### 3.2 Daily Schedules
[Section titled “3.2 Daily Schedules”](#32-daily-schedules)
#### 3.2.1 Basic Daily Schedule
[Section titled “3.2.1 Basic Daily Schedule”](#321-basic-daily-schedule)
A basic daily schedule expression SHALL take the form:
```yaml
daily
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:DAILY * * *`
The execution time SHALL be deterministically scattered across all 24 hours and 60 minutes of the day.
#### 3.2.2 Daily Around Time
[Section titled “3.2.2 Daily Around Time”](#322-daily-around-time)
A daily around schedule expression SHALL take the form:
```yaml
daily around
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:DAILY_AROUND:HH:MM * * *`
The execution time SHALL be scattered within a ±60 minute window around the specified time.
**Example**:
```yaml
daily around 14:00
# Generates: FUZZY:DAILY_AROUND:14:0 * * *
# Scatters within window: 13:00 to 15:00
```
#### 3.2.3 Daily Between Times
[Section titled “3.2.3 Daily Between Times”](#323-daily-between-times)
A daily between schedule expression SHALL take the form:
```yaml
daily between and
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:DAILY_BETWEEN:START_H:START_M:END_H:END_M * * *`
The execution time SHALL be scattered uniformly within the specified time range, including handling of midnight-crossing ranges.
**Example**:
```yaml
daily between 9:00 and 17:00
# Generates: FUZZY:DAILY_BETWEEN:9:0:17:0 * * *
# Scatters within window: 09:00 to 17:00
daily between 22:00 and 02:00
# Generates: FUZZY:DAILY_BETWEEN:22:0:2:0 * * *
# Scatters within window: 22:00 to 02:00 (crossing midnight)
```
### 3.3 Weekly Schedules
[Section titled “3.3 Weekly Schedules”](#33-weekly-schedules)
#### 3.3.1 Basic Weekly Schedule
[Section titled “3.3.1 Basic Weekly Schedule”](#331-basic-weekly-schedule)
A basic weekly schedule expression SHALL take the form:
```yaml
weekly
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:WEEKLY * * *`
The execution SHALL be scattered across all seven days of the week and all hours/minutes of each day.
#### 3.3.2 Weekly with Day Specification
[Section titled “3.3.2 Weekly with Day Specification”](#332-weekly-with-day-specification)
A weekly day schedule expression SHALL take the form:
```yaml
weekly on
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:WEEKLY:DOW * * DOW`
**Example**:
```yaml
weekly on monday
# Generates: FUZZY:WEEKLY:1 * * 1
# Scatters across all hours on Monday
```
#### 3.3.3 Weekly with Time Constraints
[Section titled “3.3.3 Weekly with Time Constraints”](#333-weekly-with-time-constraints)
A weekly schedule MAY include time constraints using `around` or `between`:
```yaml
weekly on around
weekly on between and
```
**Example**:
```yaml
weekly on friday around 17:00
# Generates: FUZZY:WEEKLY:5:AROUND:17:0 * * 5
# Scatters Friday 16:00-18:00
```
### 3.4 Hourly Schedules
[Section titled “3.4 Hourly Schedules”](#34-hourly-schedules)
#### 3.4.1 Basic Hourly Schedule
[Section titled “3.4.1 Basic Hourly Schedule”](#341-basic-hourly-schedule)
A basic hourly schedule expression SHALL take the form:
```yaml
hourly
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:HOURLY * * *`
The minute offset SHALL be scattered across 0-59 minutes but remain consistent for each hour.
**Example**:
```yaml
hourly
# Generates: FUZZY:HOURLY * * *
# Might scatter to: 43 * * * * (runs at minute 43 every hour)
```
#### 3.4.2 Hour Interval Schedules
[Section titled “3.4.2 Hour Interval Schedules”](#342-hour-interval-schedules)
An hour interval schedule expression SHALL take the form:
```yaml
every h
every hours
every hour
```
Where `` MUST be a positive integer.
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:HOURLY: * * *`
Valid hour intervals SHOULD be: 1, 2, 3, 4, 6, 8, 12 (factors of 24 for even distribution).
**Example**:
```yaml
every 2h
# Generates: FUZZY:HOURLY:2 * * *
# Might scatter to: 53 */2 * * * (runs at minute 53 every 2 hours)
```
### 3.5 Special Period Schedules
[Section titled “3.5 Special Period Schedules”](#35-special-period-schedules)
#### 3.5.1 Bi-weekly Schedule
[Section titled “3.5.1 Bi-weekly Schedule”](#351-bi-weekly-schedule)
A bi-weekly schedule expression SHALL take the form:
```yaml
bi-weekly
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:BI-WEEKLY * * *`
The schedule SHALL execute once every 14 days with scattered time.
#### 3.5.2 Tri-weekly Schedule
[Section titled “3.5.2 Tri-weekly Schedule”](#352-tri-weekly-schedule)
A tri-weekly schedule expression SHALL take the form:
```yaml
tri-weekly
```
An implementation MUST generate a fuzzy cron placeholder: `FUZZY:TRI-WEEKLY * * *`
The schedule SHALL execute once every 21 days with scattered time.
### 3.6 Interval Schedules
[Section titled “3.6 Interval Schedules”](#36-interval-schedules)
An interval schedule expression SHALL take the form:
```yaml
every
```
Where:
* `` MUST be a positive integer
* `` MUST be one of: `minutes`, `minute`, `m`, `hours`, `hour`, `h`, `days`, `day`, `d`, `weeks`, `week`, `w`
An implementation MUST generate appropriate cron expressions based on the unit:
* Minutes: `*/N * * * *` (minimum N=5 per GitHub Actions constraint)
* Hours: `FUZZY:HOURLY:N * * *` (scattered minute)
* Days: `0 0 */N * *` (fixed midnight)
* Weeks: `0 0 */N*7 * *` (fixed Sunday midnight)
**Example**:
```yaml
every 5 minutes
# Generates: */5 * * * *
every 6h
# Generates: FUZZY:HOURLY:6 * * *
every 2 days
# Generates: 0 0 */2 * *
```
***
## 4. Time Specifications
[Section titled “4. Time Specifications”](#4-time-specifications)
### 4.1 Time Format Requirements
[Section titled “4.1 Time Format Requirements”](#41-time-format-requirements)
An implementation MUST support the following time formats:
#### 4.1.1 24-Hour Format
[Section titled “4.1.1 24-Hour Format”](#411-24-hour-format)
The 24-hour format SHALL use the pattern `HH:MM`:
* Hours MUST be in range 0-23
* Minutes MUST be in range 0-59
* Leading zeros MAY be omitted for hours
* Minutes MUST use two digits with leading zero if necessary
**Valid examples**: `00:00`, `9:30`, `14:00`, `23:59`
#### 4.1.2 12-Hour Format
[Section titled “4.1.2 12-Hour Format”](#412-12-hour-format)
The 12-hour format SHALL use the pattern `H[H]am` or `H[H]pm`:
* Hours MUST be in range 1-12
* AM/PM indicator MUST be lowercase `am` or `pm`
* Minutes MAY be omitted (defaults to :00)
* Colon and minutes MAY be included (e.g., `3:30pm`)
**Valid examples**: `1am`, `12pm`, `11pm`, `9am`, `3:30pm`
**Conversion rules**:
* `12am` converts to 00:00 (midnight)
* `12pm` converts to 12:00 (noon)
* `1am-11am` converts to 01:00-11:00
* `1pm-11pm` converts to 13:00-23:00
#### 4.1.3 Time Keywords
[Section titled “4.1.3 Time Keywords”](#413-time-keywords)
An implementation MUST support the following time keywords:
* `midnight`: Represents 00:00 (start of day)
* `noon`: Represents 12:00 (middle of day)
Keywords MUST be case-insensitive.
### 4.2 Time Range Requirements
[Section titled “4.2 Time Range Requirements”](#42-time-range-requirements)
#### 4.2.1 Window Specification
[Section titled “4.2.1 Window Specification”](#421-window-specification)
When using `around