Bug
The compiler (v0.81.6) generates the pre_activation job without pull-requests: read when using a decentralized label_command trigger with events: [pull_request]. The check_membership.cjs script (v0.81.6) in that job calls GET /repos/{owner}/{repo}/pulls/{number} to verify PR provenance, but receives HTTP 403 because the job inherits the workflow-level permissions: {}.
This causes all downstream jobs (activation, agent, detection, safe_outputs) to be skipped.
Steps to Reproduce
Frontmatter:
on:
label_command:
name: ci-doctor
events: [pull_request]
strategy: decentralized
permissions:
pull-requests: read
- Compile with
gh aw compile ci-doctor
- Observe the generated
pre_activation job has no permissions: block
- Add the label to a PR —
check_membership.cjs fails with 403 on the pulls API
Evidence
In the compiled .lock.yml (v0.81.6), the pre_activation job:
pre_activation:
if: >
fromJSON(github.event.inputs.aw_context || '{}').event_type == 'pull_request' && ...
runs-on: ubuntu-slim
# No permissions: block here!
env:
GH_AW_RUNTIME_FEATURES: ...
The workflow-level declaration is permissions: {}, so the GITHUB_TOKEN has zero scopes.
From the workflow run logs:
Validating centralized workflow_dispatch against originating actor
GET /repos/products/grc-poc/pulls/125 - 403
##[warning]Repository permission check failed: Unable to verify pull request provenance
The activation job (which the compiler DOES give permissions) has actions: read, contents: read, issues: write — but pre_activation gets nothing.
Expected Behavior
When the compiler generates pre_activation for a label_command with strategy: decentralized and events: [pull_request], it should automatically include pull-requests: read in the job's permissions: block — since check_membership.cjs requires it to verify PR provenance.
Workaround
Adding on.permissions to the frontmatter propagates the permission correctly:
on:
label_command:
name: ci-doctor
events: [pull_request]
strategy: decentralized
permissions:
pull-requests: read
This tells the compiler to grant pull-requests: read to the pre_activation job.
Implementation Plan
-
Identify the code that generates pre_activation job permissions (likely in pkg/workflow/ — the job compilation logic that builds the YAML for pre_activation)
-
Add automatic pull-requests: read when:
- Trigger strategy is
decentralized
- Events include
pull_request
- The
check_membership.cjs step is generated (PR provenance verification)
-
Add a test that compiles a workflow with label_command + strategy: decentralized + events: [pull_request] and asserts the generated pre_activation job includes permissions: { pull-requests: read }
-
Run make agent-finish to validate
Bug
The compiler (v0.81.6) generates the
pre_activationjob withoutpull-requests: readwhen using a decentralizedlabel_commandtrigger withevents: [pull_request]. Thecheck_membership.cjsscript (v0.81.6) in that job callsGET /repos/{owner}/{repo}/pulls/{number}to verify PR provenance, but receives HTTP 403 because the job inherits the workflow-levelpermissions: {}.This causes all downstream jobs (activation, agent, detection, safe_outputs) to be skipped.
Steps to Reproduce
Frontmatter:
gh aw compile ci-doctorpre_activationjob has nopermissions:blockcheck_membership.cjsfails with 403 on the pulls APIEvidence
In the compiled
.lock.yml(v0.81.6), thepre_activationjob:The workflow-level declaration is
permissions: {}, so the GITHUB_TOKEN has zero scopes.From the workflow run logs:
The
activationjob (which the compiler DOES give permissions) hasactions: read,contents: read,issues: write— butpre_activationgets nothing.Expected Behavior
When the compiler generates
pre_activationfor alabel_commandwithstrategy: decentralizedandevents: [pull_request], it should automatically includepull-requests: readin the job'spermissions:block — sincecheck_membership.cjsrequires it to verify PR provenance.Workaround
Adding
on.permissionsto the frontmatter propagates the permission correctly:This tells the compiler to grant
pull-requests: readto thepre_activationjob.Implementation Plan
Identify the code that generates
pre_activationjob permissions (likely inpkg/workflow/— the job compilation logic that builds the YAML forpre_activation)Add automatic
pull-requests: readwhen:decentralizedpull_requestcheck_membership.cjsstep is generated (PR provenance verification)Add a test that compiles a workflow with
label_command+strategy: decentralized+events: [pull_request]and asserts the generatedpre_activationjob includespermissions: { pull-requests: read }Run
make agent-finishto validate