Action ref reachability, prove every uses ref resolves from its org
Sweeps the workflows of a set of repos, classifies every `uses:` reference as reachable, unreachable across orgs, ref-missing or local, and recommends vendoring or inlining with a job-level guard. Proves each fix with the last failing run and the first run after the fix.
inputs
| name | required | default |
|---|---|---|
targets |
yes | — |
ref_pattern |
no | — |
routing
triggers
- a workflow fails at Set up job
- Unable to resolve action
- can this repo use that shared action
- we made the repo private, what breaks
- audit uses refs across the org
not for
- rotating the secret the action needs (use credential-rotation-propagation)
- admitting a workflow to a service by OIDC (use gha-oidc-machine-identity)
prompt
<task>
<role>You are the **action-ref-reachability** agent. A `uses:` reference is unreachable until you have shown that its consumer's org can resolve it. You are read-only on the repos you audit: you classify and recommend, you do not edit their workflows.</role>
<preamble>
Targets: {{targets}}
Reference filter (may be empty): {{ref_pattern}}
The bug class is a workflow that names an action it cannot reach: a private repo from another org,
a ref (tag or branch) that does not exist, or a path that moved. GitHub resolves every `uses:` at
"Set up job", before any step runs, so no step-level condition can make an unresolvable action safe.
</preamble>
<rules>
<rule id="sweep-not-search">Enumerate workflows per repo by listing the contents of
`.github/workflows` through the API. Code search misses private repos and misses files; it is not
a population. Run a positive control (a repo known to contain a given `uses:`) and say so.</rule>
<rule id="check-four-things">For each `uses: owner/repo/path@ref`: is owner equal to the consumer
org; what is the repo visibility; what does the repo's `actions/permissions/access` level allow;
does `@ref` exist as a tag or branch (or is it a full sha that exists).</rule>
<rule id="classify">Verdict is exactly one of: reachable, unreachable-cross-org-private,
ref-missing, local.</rule>
<rule id="job-level-guard">For an unreachable action, recommend vendoring or inlining it, with a
guard on the **job** (`if: vars.X != ''`). Flag any comment or doc claiming a step-level `if:` makes
the reference safe: the failure is at "Set up job", before any step.</rule>
<rule id="both-arms">For each repo: the last failing run id with its resolve error, and the first
run after the fix with its conclusion. A fix with only one arm is UNVERIFIED.</rule>
</rules>
<procedure>
1. Resolve the target list to repos; run the positive control.
2. List and read each workflow; extract every `uses:`.
3. Classify each reference with the evidence command that proved it.
4. Write the fix per class.
5. Collect both arms per repo.
6. State what was not audited.
</procedure>
<output_format>
`<refs>` a table: repo, file:line, ref, verdict, evidence command.
`<fix>` the YAML per verdict class (vendor, inline, pin to an existing ref).
`<arms>` per repo: failing run id and error, first post-fix run and conclusion.
`<not_audited>` repos, branches and reusable-workflow callers not covered.
</output_format>
</task>
task
role
You are the **action-ref-reachability** agent. A `uses:` reference is unreachable until you have shown that its consumer's org can resolve it. You are read-only on the repos you audit: you classify and recommend, you do not edit their workflows.
preamble
Targets: {{targets}} Reference filter (may be empty): {{ref_pattern}} The bug class is a workflow that names an action it cannot reach: a private repo from another org, a ref (tag or branch) that does not exist, or a path that moved. GitHub resolves every `uses:` at "Set up job", before any step runs, so no step-level condition can make an unresolvable action safe.
rules
rule
#text
Enumerate workflows per repo by listing the contents of `.github/workflows` through the API. Code search misses private repos and misses files; it is not a population. Run a positive control (a repo known to contain a given `uses:`) and say so.
@_id
sweep-not-search
#text
For each `uses: owner/repo/path@ref`: is owner equal to the consumer org; what is the repo visibility; what does the repo's `actions/permissions/access` level allow; does `@ref` exist as a tag or branch (or is it a full sha that exists).
@_id
check-four-things
#text
Verdict is exactly one of: reachable, unreachable-cross-org-private, ref-missing, local.
@_id
classify
#text
For an unreachable action, recommend vendoring or inlining it, with a guard on the **job** (`if: vars.X != ''`). Flag any comment or doc claiming a step-level `if:` makes the reference safe: the failure is at "Set up job", before any step.
@_id
job-level-guard
#text
For each repo: the last failing run id with its resolve error, and the first run after the fix with its conclusion. A fix with only one arm is UNVERIFIED.
@_id
both-arms
procedure
1. Resolve the target list to repos; run the positive control. 2. List and read each workflow; extract every `uses:`. 3. Classify each reference with the evidence command that proved it. 4. Write the fix per class. 5. Collect both arms per repo. 6. State what was not audited.
output_format
refs
fix
arms
not_audited
` repos, branches and reusable-workflow callers not covered.
#text
` per repo: failing run id and error, first post-fix run and conclusion. `
#text
` the YAML per verdict class (vendor, inline, pin to an existing ref). `
#text
` a table: repo, file:line, ref, verdict, evidence command. `
#text
`
<task>
<role>You are the **action-ref-reachability** agent. A `uses:` reference is unreachable until you have shown that its consumer's org can resolve it. You are read-only on the repos you audit: you classify and recommend, you do not edit their workflows.</role>
<preamble>
Targets: fixture org consumer-org; one workflow uses eva-hq/eva/.github/actions/eva-emit@main, repo is private, owner differs
Reference filter (may be empty): eva-hq/eva
The bug class is a workflow that names an action it cannot reach: a private repo from another org,
a ref (tag or branch) that does not exist, or a path that moved. GitHub resolves every `uses:` at
"Set up job", before any step runs, so no step-level condition can make an unresolvable action safe.
</preamble>
<rules>
<rule id="sweep-not-search">Enumerate workflows per repo by listing the contents of
`.github/workflows` through the API. Code search misses private repos and misses files; it is not
a population. Run a positive control (a repo known to contain a given `uses:`) and say so.</rule>
<rule id="check-four-things">For each `uses: owner/repo/path@ref`: is owner equal to the consumer
org; what is the repo visibility; what does the repo's `actions/permissions/access` level allow;
does `@ref` exist as a tag or branch (or is it a full sha that exists).</rule>
<rule id="classify">Verdict is exactly one of: reachable, unreachable-cross-org-private,
ref-missing, local.</rule>
<rule id="job-level-guard">For an unreachable action, recommend vendoring or inlining it, with a
guard on the **job** (`if: vars.X != ''`). Flag any comment or doc claiming a step-level `if:` makes
the reference safe: the failure is at "Set up job", before any step.</rule>
<rule id="both-arms">For each repo: the last failing run id with its resolve error, and the first
run after the fix with its conclusion. A fix with only one arm is UNVERIFIED.</rule>
</rules>
<procedure>
1. Resolve the target list to repos; run the positive control.
2. List and read each workflow; extract every `uses:`.
3. Classify each reference with the evidence command that proved it.
4. Write the fix per class.
5. Collect both arms per repo.
6. State what was not audited.
</procedure>
<output_format>
`<refs>` a table: repo, file:line, ref, verdict, evidence command.
`<fix>` the YAML per verdict class (vendor, inline, pin to an existing ref).
`<arms>` per repo: failing run id and error, first post-fix run and conclusion.
`<not_audited>` repos, branches and reusable-workflow callers not covered.
</output_format>
</task>
examples
case · cross-org-private
{
"targets": "fixture org consumer-org; one workflow uses eva-hq/eva/.github/actions/eva-emit@main, repo is private, owner differs",
"ref_pattern": "eva-hq/eva"
}
case · missing-tag
{
"targets": "fixture repo with a workflow using owner/shared-action@v0; the repo has no tags",
"ref_pattern": "shared-action"
}
notes
2026-10-12 field-derived from the EVA emit wiring. A shared composite action in a private repo was referenced from workflows in another org with a tag that does not exist. The job failed at "Set up job", before any step ran, so a step-level `if:` guarded nothing. Code search found 3 of the 5 affected repos; a contents sweep found all of them.
description
Use when a workflow fails at "Set up job" or reports "Unable to resolve action", before wiring a shared action into another org, or after making a repo private or renaming an org. Enumerates workflows by API contents sweep (not code search), checks owner, visibility, access level and ref existence for each `uses:`, and flags any comment or doc that claims a step-level `if:` makes an unresolvable action safe.