# GitHub Agentic Workflows: how gh aw compiles to Actions

> GitHub Agentic Workflows compile Markdown into Actions YAML with gh aw. The file format, the jobs it generates, safe outputs and how its PRs get CI.

Source: https://latchkey.dev/learn/agent-ci/github-agentic-workflows  
Updated: 2026-11-12

GitHub Agentic Workflows let you write a repository automation as a Markdown file with YAML frontmatter and compile it with `gh aw compile` into a standard `.lock.yml` Actions workflow that runs a coding agent. GitHub made it generally available on October 28, 2026; the agent job is read-only by default, and every write goes through a separate safe-output job with its own scoped permissions.

The pitch is that some repository chores need judgment rather than a script: triaging an issue, investigating a red build, keeping docs in step. `gh aw` keeps those in Actions, with Actions' triggers, runners and logs, and adds the parts an agent needs: an engine, a firewall, and a way to write to GitHub without handing the model a write token.

GitHub's own framing is that it complements CI rather than replacing it: builds, tests and deployments stay deterministic. What follows is the file format, what compilation produces, the safe-output model, and the CI gap on pull requests it opens.

## Status, engines and what you pay for

It went from technical preview in February 2026 to general availability in October, and the CLI is a GitHub CLI extension, `github/gh-aw`, whose latest release on 2026-11-12 was v1.2.2. The default engine is GitHub Copilot, which requires a Copilot license; the others bring their own key. Two costs land on separate lines of the bill: Actions minutes for every generated job, and inference from the model provider.

| Engine | `engine:` | Authenticates with |
| --- | --- | --- |
| GitHub Copilot (default) | `copilot` | `copilot-requests: write` or `COPILOT_GITHUB_TOKEN` |
| Claude Code | `claude` | `ANTHROPIC_API_KEY` or Anthropic workload identity federation |
| OpenAI Codex | `codex` | `CODEX_API_KEY` or `OPENAI_API_KEY` |
| Google Gemini | `gemini` | `GEMINI_API_KEY` or Google workload identity federation |
| Pi | `pi` | Copilot, Anthropic or OpenAI auth, chosen by the `model:` prefix |

> Milestones from GitHub's changelog: technical preview 2026-02-13, public preview 2026-06-11, general availability 2026-10-28 on github.com for Free, Team and Enterprise.

## The file format

A workflow is one Markdown file in `.github/workflows/`. The frontmatter between the `---` markers holds what Actions needs and what the compiler enforces: triggers, permissions, engine, tools and safe outputs. The body is the instruction, in prose. Permissions are read scopes; writes are declared under `safe-outputs` instead.

The example below investigates failed CI runs on `main` and opens at most one issue. Two compiler rules shaped it: a `workflow_run` trigger must name at least one workflow, and strict mode, which is on by default, errors when `branches` is missing.

```.github/workflows/ci-failure-triage.md
---
on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]
    branches: [main]
    conclusion: failure
  workflow_dispatch:
permissions:
  contents: read
  actions: read
  issues: read
engine: claude
tools:
  github:
    toolsets: [default, actions]
safe-outputs:
  create-issue:
    title-prefix: "[ci] "
    labels: [ci-failure]
    max: 1
---
# Investigate the failed CI run

Read the failed jobs of the run that triggered this workflow. Decide whether
the failure is in the code or in the environment, quote the failing step's
error, and open one issue with the cause and the smallest fix you can name.
If an open issue already covers this failure, do nothing.
```

## What gh aw compile produces

`gh aw compile` validates the frontmatter against the schema, resolves imports, builds the jobs, pins every action to a commit SHA with the version in a comment, and writes `ci-failure-triage.lock.yml` beside the source. Commit both files together. The lock file is what Actions runs; the activation job checks that it is fresh.

The body is loaded at run time, so editing the instructions takes effect on the next run without recompiling. Anything between the `---` markers, from triggers to safe outputs to the engine, needs `gh aw compile` again. A workflow compiled with `strict: false` refuses to run on a public repository.

```Terminal
gh extension install github/gh-aw
gh aw compile ci-failure-triage
gh aw run ci-failure-triage
gh aw logs ci-failure-triage
```

## Safe outputs: the agent asks, another job writes

The agent job never holds a write token for GitHub. When it wants to open an issue or a pull request, it records a structured request; after it finishes, a separate job downloads that output and performs the permitted operation with the permissions that one operation needs, within the limits you set, such as `max: 1`. A detection job, when threat detection is configured, scans the output before any of that happens.

The agent's network is closed by default too: with no `network:` setting it reaches only certificate validation, JSON schema and Ubuntu archive hosts, plus GitHub's own domains. If you declare no safe outputs at all, `create-issue` is enabled with conservative defaults, so a workflow can always report what it found.

| Job | Runs when | What it does |
| --- | --- | --- |
| `pre_activation` | Role checks, deadlines or command triggers are set | Validates permissions and conditions before any AI runs |
| `activation` | Always | Sanitizes event text, checks the lock file is fresh |
| `agent` | Always | Runs the engine with read scopes, in a sandbox behind the firewall |
| `detection` | Threat detection configured | Scans the agent output before anything is applied |
| Safe-output jobs | One per configured output type | Performs one GitHub operation with the write scope it needs |

## Pull requests it opens, and CI

According to gh-aw's reference on triggering CI, pull requests created with the default `GITHUB_TOKEN` do not trigger CI runs by default, and that applies to both `create-pull-request` and `push-to-pull-request-branch`. On github.com, GitHub's 2026-06-11 change means a `GITHUB_TOKEN` pull request now gets its `pull_request` runs in an approval-required state, so a person still has to click before any check reports.

The fix gh-aw ships is an extra empty commit pushed with a different identity, which produces normal `push` and `pull_request` events. Point `github-token-for-extra-empty-commit` at a fine-grained PAT with Contents read and write, or at `app` for the workflow's GitHub App, or set the secret `GH_AW_CI_TRIGGER_TOKEN`, which the compiler picks up without being referenced. If CI still does not start, check that the empty commit's run actor is that identity rather than `github-actions[bot]`.

```.github/workflows/<name>.md frontmatter
safe-outputs:
  create-pull-request:
    github-token-for-extra-empty-commit: ${{ secrets.MY_CI_TRIGGER_PAT }}
  push-to-pull-request-branch:
    github-token-for-extra-empty-commit: app
```

## Runners and timeouts

`runs-on` in the frontmatter applies to the agent job only and defaults to `ubuntu-latest`; `runs-on-slim` covers the generated framework jobs and defaults to `ubuntu-slim`, which allows timeouts of at most 15 minutes. Safe-output jobs that create or push pull requests use `ubuntu-latest`, because they check out and publish code.

`timeout-minutes` bounds the agent step and falls back to 20 minutes; the agent job as a whole defaults to 60 and the detection job to 10. Self-hosted runners must be Linux with Docker; macOS and Windows are not supported, and GA added Actions Runner Controller with Docker-in-Docker.

## Sources, and the missing run

Everything here comes from the github/gh-aw repository on its main branch, with v1.2.2 as the latest release, its published reference pages and GitHub's changelog, all read on 2026-11-12. No run of `gh aw` was recorded for this page, and the repository's evidence files have no entry for it. The default engine needs a Copilot license, and a lock file compiled here would describe one CLI version, while the job layout and defaults above are what the reference commits to.

## FAQ

### Are GitHub Agentic Workflows generally available?

Yes. GitHub announced general availability on October 28, 2026, for GitHub Free, Team and Enterprise on github.com, after a technical preview in February and a public preview in June. Using the default Copilot engine requires a Copilot license.

### Do I need to recompile after editing an agentic workflow?

Only if you changed the frontmatter. The Markdown body is loaded at run time, so instruction changes apply on the next run. Triggers, permissions, tools, network, safe outputs, engine and timeouts all live in the frontmatter and need `gh aw compile` before they take effect.

### Why does CI not run on pull requests created by an agentic workflow?

Because they are created with `GITHUB_TOKEN`, and GitHub does not start unattended runs from events that token causes. Set `github-token-for-extra-empty-commit` on the pull request safe output, or the `GH_AW_CI_TRIGGER_TOKEN` secret, so an extra empty commit is pushed by an identity whose events trigger workflows.

### Which AI engines does gh aw support?

GitHub Copilot (the default), Claude Code, OpenAI Codex, Google Gemini and Pi, selected with `engine:` in the frontmatter. Each authenticates with its own secret or permission, for example `ANTHROPIC_API_KEY` for Claude or `copilot-requests: write` for organization-billed Copilot.

## References

- [github/gh-aw repository (read 2026-11-12)](https://github.com/github/gh-aw)
- [gh-aw: how agentic workflows work](https://github.github.com/gh-aw/introduction/how-they-work/)
- [gh-aw: triggering CI on pull requests from agentic workflows](https://github.github.com/gh-aw/reference/triggering-ci/)
- [gh-aw: safe outputs](https://github.github.com/gh-aw/reference/safe-outputs/)
- [GitHub changelog: GitHub Agentic Workflows generally available](https://github.blog/changelog/2026-10-28-github-agentic-workflows-generally-available)

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
