Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ export default defineConfig({
{ label: 'Safe Outputs', link: '/reference/safe-outputs/' },
{ label: 'Safe Outputs (Pull Requests)', link: '/reference/safe-outputs-pull-requests/' },
{ label: 'Safe Outputs (Spec)', link: '/reference/safe-outputs-specification/' },
{ label: 'Safe Outputs (Staged Mode)', link: '/reference/staged-mode/' },
{ label: 'Sandbox', link: '/reference/sandbox/' },
{ label: 'Schedule Syntax', link: '/reference/schedule-syntax/' },
{ label: 'Templating', link: '/reference/templating/' },
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/reference/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ An optional field on safe output tool calls indicating the confidentiality level

### Staged Mode

A preview mode where workflows simulate actions without making changes. The AI generates output showing what would happen, but no GitHub API write operations are performed. Use for testing before production runs.
A preview mode where workflows simulate actions without making changes. The AI generates output showing what would happen, but no GitHub API write operations are performed. Use for testing before production runs. See [Staged Mode](/gh-aw/reference/staged-mode/) for details.

### Integrity

Expand Down
28 changes: 28 additions & 0 deletions docs/src/content/docs/reference/safe-outputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -1349,8 +1349,36 @@ safe-outputs:

**Variables**: `{workflow_name}`, `{run_url}`, `{triggering_number}`, `{workflow_source}`, `{workflow_source_url}`, `{event_type}`, `{status}`, `{operation}`

## Staged Mode

Staged mode lets you preview what safe outputs a workflow would create without actually creating anything. Every write operation is skipped; instead, a 🎭-labelled preview appears in the GitHub Actions step summary.
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text uses UK spelling "🎭-labelled"; elsewhere in these docs the standard spelling is "labeled" (e.g., GitHub event types like labeled). Consider changing this to "🎭-labeled" for consistency.

Suggested change
Staged mode lets you preview what safe outputs a workflow would create without actually creating anything. Every write operation is skipped; instead, a 🎭-labelled preview appears in the GitHub Actions step summary.
Staged mode lets you preview what safe outputs a workflow would create without actually creating anything. Every write operation is skipped; instead, a 🎭-labeled preview appears in the GitHub Actions step summary.

Copilot uses AI. Check for mistakes.

Enable it globally by adding `staged: true` to the `safe-outputs:` block:

```yaml wrap
safe-outputs:
staged: true
create-issue:
title-prefix: "[ai] "
labels: [automation]
```

You can also scope staged mode to a specific output type by adding `staged: true` directly to that type while leaving the global setting at `false`:

```yaml wrap
safe-outputs:
create-pull-request:
staged: true # preview only
add-comment: # executes normally
Comment on lines +1370 to +1372
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example is introduced as leaving the global safe-outputs.staged setting at false, but the snippet doesn’t show staged: false at the top level. Either include staged: false in the example for clarity, or adjust the wording to reflect that staged defaults to false when omitted.

Suggested change
create-pull-request:
staged: true # preview only
add-comment: # executes normally
staged: false # global default
create-pull-request:
staged: true # preview only
add-comment: # executes normally

Copilot uses AI. Check for mistakes.
```

To disable staged mode and start creating real resources, remove the `staged: true` setting or set it to `false`.

See [Staged Mode](/gh-aw/reference/staged-mode/) for the full guide, including the preview message format, per-type support table, custom message templates, and how to implement staged mode in [custom safe output jobs](/gh-aw/reference/custom-safe-outputs/#staged-mode-support).

## Related Documentation

- [Staged Mode](/gh-aw/reference/staged-mode/) - Preview safe output operations without making changes
- [Threat Detection Guide](/gh-aw/reference/threat-detection/) - Complete threat detection documentation and examples
- [Frontmatter](/gh-aw/reference/frontmatter/) - All configuration options for workflows
- [Workflow Structure](/gh-aw/reference/workflow-structure/) - Directory layout and organization
Expand Down
166 changes: 166 additions & 0 deletions docs/src/content/docs/reference/staged-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
---
title: Staged Mode
description: Preview safe output operations without making any changes, so you can see exactly what a workflow would do before it acts.
sidebar:
order: 820
---

Staged mode lets you run a workflow and see what [safe outputs](/gh-aw/reference/safe-outputs/) it would create — issues, comments, pull requests, and more — without actually creating anything. Every write operation is skipped; instead, a detailed preview appears in the GitHub Actions step summary with a 🎭 indicator.

This is useful when you're adopting a new workflow and want to verify its behavior before it has any real effect, or when you want to share what a workflow *would* do with colleagues before enabling it in production.

## Enabling Staged Mode

Add `staged: true` to the `safe-outputs:` block in your workflow frontmatter:

```aw wrap
---
on: issues
safe-outputs:
staged: true
create-issue:
title-prefix: "[ai] "
labels: [automation]
---

# Issue Analyzer

Analyze the issue and suggest follow-up tasks.
```

With this configuration the workflow runs fully — the AI completes its analysis — but no issues are created. Instead, the Actions run summary shows a preview of what would have been created.

## Scoping Staged Mode per Output Type

Use `staged: true` on a specific type to preview only that output type while letting others execute normally:

```aw wrap
---
safe-outputs:
staged: false # default: execute normally
create-pull-request:
staged: true # PRs: preview only
add-comment: # comments: execute normally
---
```

A type-level `staged` setting overrides the global one, so you can pilot one risky output type while keeping other outputs fully active.

## What the Preview Looks Like

When staged mode is active the step summary contains a structured preview for each output type. The 🎭 emoji appears in every heading to make previews easy to spot:

```markdown
## 🎭 Staged Mode: Issue Creation Preview

The following 2 issue(s) would be performed if staged mode was disabled:

### Operation 1: Add caching layer to database queries

**Type**: create-issue
**Title**: Add caching layer to database queries
**Body**:
Performance profiling shows repeated queries to the users table …

**Additional Fields**:
- Labels: performance, database
- Assignees: octocat

### Operation 2: Update connection pool settings


---
**Preview Summary**: 2 operations previewed. No GitHub resources were created.
```

The preview includes every field the AI populated — title, body, labels, assignees — so you can evaluate the full output before enabling.

## Supported Output Types

Staged mode is supported by all built-in safe output types:

| Output type | What the preview shows |
|---|---|
| [`create-issue`](/gh-aw/reference/safe-outputs/#issue-creation-create-issue) | Title, body, labels, assignees |
| [`update-issue`](/gh-aw/reference/safe-outputs/#issue-updates-update-issue) | Target issue, updated fields |
| [`close-issue`](/gh-aw/reference/safe-outputs/#close-issue-close-issue) | Target issue, closing comment |
| [`add-comment`](/gh-aw/reference/safe-outputs/#comment-creation-add-comment) | Target issue/PR/discussion, comment body |
| [`add-labels`](/gh-aw/reference/safe-outputs/#add-labels-add-labels) | Target item, labels to add |
| [`remove-labels`](/gh-aw/reference/safe-outputs/#remove-labels-remove-labels) | Target item, labels to remove |
| [`create-discussion`](/gh-aw/reference/safe-outputs/#discussion-creation-create-discussion) | Title, body, category |
| [`update-discussion`](/gh-aw/reference/safe-outputs/#discussion-updates-update-discussion) | Target discussion, updated fields |
| [`close-discussion`](/gh-aw/reference/safe-outputs/#close-discussion-close-discussion) | Target discussion, closing comment |
| [`create-pull-request`](/gh-aw/reference/safe-outputs-pull-requests/#pull-request-creation-create-pull-request) | Title, body, branch, diff |
| [`update-pull-request`](/gh-aw/reference/safe-outputs/#pull-request-updates-update-pull-request) | Target PR, updated fields |
| [`close-pull-request`](/gh-aw/reference/safe-outputs/#close-pull-request-close-pull-request) | Target PR |
| [`create-pull-request-review-comment`](/gh-aw/reference/safe-outputs/#pr-review-comments-create-pull-request-review-comment) | File, line, comment body |
| [`push-to-pull-request-branch`](/gh-aw/reference/safe-outputs-pull-requests/#push-to-pr-branch-push-to-pull-request-branch) | Branch, patch summary |
| [`create-project`](/gh-aw/reference/safe-outputs/#project-creation-create-project) | Project title, description |
| [`update-project`](/gh-aw/reference/safe-outputs/#project-board-updates-update-project) | Target project, project items and fields to update |
| [`create-project-status-update`](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update) | Status, body |
| [`update-release`](/gh-aw/reference/safe-outputs/#release-updates-update-release) | Target release, updated body |
| [`upload-asset`](/gh-aw/reference/safe-outputs/#asset-uploads-upload-asset) | File names and sizes |
| [`dispatch-workflow`](/gh-aw/reference/safe-outputs/#workflow-dispatch-dispatch-workflow) | Target workflow, inputs |
| [`assign-to-agent`](/gh-aw/reference/safe-outputs/#assign-to-agent-assign-to-agent) | Target issue/PR |
| [`assign-to-user`](/gh-aw/reference/safe-outputs/#assign-to-user-assign-to-user) | Target item, user |
| [`create-agent-session`](/gh-aw/reference/safe-outputs/#agent-session-creation-create-agent-session) | Session details |

[Custom safe output jobs](/gh-aw/reference/custom-safe-outputs/) receive the `GH_AW_SAFE_OUTPUTS_STAGED` environment variable set to `"true"` when staged mode is active, allowing you to implement your own preview behavior.

## Staged Mode for Custom Safe Output Jobs

Custom jobs check `GH_AW_SAFE_OUTPUTS_STAGED` to skip the real operation and display a preview instead:

```javascript
if (process.env.GH_AW_SAFE_OUTPUTS_STAGED === 'true') {
core.info('🎭 Staged mode: would send Slack notification');
await core.summary
.addHeading('🎭 Staged Mode: Slack Notification Preview', 2)
.addRaw(`**Would send**: ${process.env.MESSAGE}`)
.write();
return;
}

// Production path — actually send the notification
await sendSlackMessage(process.env.MESSAGE);
```

See [Custom Safe Outputs — Staged Mode Support](/gh-aw/reference/custom-safe-outputs/#staged-mode-support) for a complete example.

## Customizing Preview Messages

Override the default preview heading and description using the `messages:` block:

```aw wrap
---
safe-outputs:
staged: true
messages:
staged-title: "🎭 Preview: {operation}"
staged-description: "The following {operation} would occur if staged mode was disabled:"
create-issue:
---
```

The `{operation}` placeholder is replaced with the safe output operation name (for example, `issue creation`).

## Recommended Workflow

A common adoption pattern is to start with staged mode and disable it once you're satisfied with the output:

1. Enable `staged: true` and trigger the workflow on a real event.
2. Open the Actions run and review the 🎭 preview in the step summary.
3. Adjust the workflow prompt or configuration based on the preview.
4. Repeat until the output looks correct.
5. Remove `staged: true` (or set it to `false`) to start creating real GitHub resources.

> [!TIP]
> Keep staged mode enabled when iterating on prompt changes, and only remove it when the workflow is stable. You can always re-enable it for a single type if you add a new safe output.

## Related Documentation

- [Safe Outputs](/gh-aw/reference/safe-outputs/) — All built-in safe output types and their configuration
- [Custom Safe Outputs](/gh-aw/reference/custom-safe-outputs/) — Adding custom jobs with staged mode support
- [Frontmatter (Full)](/gh-aw/reference/frontmatter-full/) — Complete configuration reference
- [Threat Detection](/gh-aw/reference/threat-detection/) — Security scanning for safe output content