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
36 changes: 36 additions & 0 deletions docs/src/content/docs/reference/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,42 @@ This prevents conclusion jobs from colliding when multiple agents run the same w

This concurrency group is set automatically during compilation and requires no manual configuration.

## 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.
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 description of the fan-out failure mode is slightly inaccurate: GitHub Actions concurrency allows 1 running + 1 pending per group; additional queued runs are canceled (unless cancel-in-progress is set, which affects running jobs). So in a fan-out of N runs you typically end up with 2 survivors (running + latest pending), not “all but the latest dispatched run”. Please adjust the wording to match actual concurrency behavior to avoid misleading users about what will happen.

Suggested change
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.
When multiple workflow instances are dispatched concurrently with different inputs (fan-out pattern), compiler-generated job-level concurrency groups are static across all runs — so each group allows only one running job and one pending job at a time, with any additional queued runs in that group being cancelled.

Copilot uses AI. Check for mistakes.

Use `concurrency.job-discriminator` to append a unique expression to compiler-generated job-level concurrency groups (`agent` and `output` jobs), making each dispatched run's group distinct:

```yaml wrap
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 wrap
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

- [AI Engines](/gh-aw/reference/engines/) - Engine configuration and capabilities
Expand Down
9 changes: 9 additions & 0 deletions docs/src/content/docs/reference/frontmatter-full.md
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,15 @@ concurrency:
# (optional)
cancel-in-progress: true

# Additional discriminator expression appended to compiler-generated job-level
# concurrency groups (agent, output jobs). Use this in fan-out patterns where
# multiple workflow instances are dispatched concurrently with different inputs,
# to prevent job-level concurrency groups from colliding and causing cancellations.
# Supports GitHub Actions expressions. Stripped from the compiled lock file
# (gh-aw extension, not a GitHub Actions field).
# (optional)
job-discriminator: "${{ inputs.finding_id }}"

# Environment variables for the workflow
# (optional)
# This field supports multiple formats (oneOf):
Expand Down