* Require environment input to pat_pool shared workflow.
- Updates the PAT pool shared workflow to latest version
- Updates the validate-pat-pool workflow to match other repos
- Updates all agentic workflows to use the updated PAT pool import
with the standard secret names used across other repos
- The new version of the import does not require the 'needs' workaround
but the issue-triage workflow's 'roles: all' configuration requires
a different workaround to ensure the pre_activation job exists for
the pat_pool job to be able to depend on it (necessary for ordering).
* Update markdown bullet style
* Apply Copilot PR feedback
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Bump versions to match gh-aw
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Adopt the shared workflow import pattern from dotnet/runtime PR #127946,
replacing the per-workflow select-copilot-pat action + custom job (shipped in
#736) with a reusable shared/pat_pool.md import.
What changed:
- Add .github/workflows/shared/pat_pool.md: an import that defines a `pat_pool`
job (inline bash, no separate action) exposing a `pat_number` output, plus an
import-schema mapping COPILOT_PAT_0..7 to this repo's pool secrets
(COPILOT_GITHUB_TOKEN, COPILOT_GITHUB_TOKEN_2..8).
- Add .github/workflows/shared/pat_pool.README.md documenting the pattern.
- Convert all 8 agentic workflows to `imports: - shared/pat_pool.md` +
`engine.env` `case(needs.pat_pool.outputs.pat_number ...)`.
- Delete the now-unused .github/actions/select-copilot-pat action.
- Add .github/workflows/validate-pat-pool.yml: a daily standalone workflow that
validates each pool PAT with a Copilot CLI request and summarizes pool health.
Wiring note (adaptation from runtime): consuming workflows declare
`on.needs: [pat_pool]` instead of runtime's `needs: [pre_activation]` +
`on.permissions: {}`. This wires pat_pool ahead of the pre_activation and
activation jobs so the selected PAT is validated by the activation job and used
by the agent, and it works for `roles: all` workflows (issue-triage), which do
not produce a pre_activation job for the runtime workaround to attach to.
Compiled with gh-aw v0.77.5. Verified end-to-end with a temporary
test-pat-rotation workflow (since removed): a run selected token #2 of the
3-token pool and the agent job observed pat_number='2', confirming the rotated
PAT reaches the agent.
* Fix Copilot PAT rotation for gh-aw v0.77.5 runtime
The PAT-rotation stop-gap wired the rotated token into engine.env via needs.pre_activation.outputs.copilot_pat_number. Because the compiled agent job depends only on 'activation' (not the built-in 'pre_activation'), that needs reference evaluated to an empty string in the agent job, so the case() fell through to the default COPILOT_GITHUB_TOKEN and rotation never reached the agent. gh-aw v0.77.5 surfaces this as a compiler warning.
Replace the pre_activation step-injection with a 'select_copilot_pat' custom job wired via on.needs. As a user-defined job referenced in engine.env, the compiler makes it a direct dependency of the agent job, so needs.select_copilot_pat.outputs.copilot_pat_number resolves correctly in both the activation and agent jobs. Same action, same secret pool, same case() expression. Recompiled all workflows with gh-aw v0.77.5.
* Add temporary test-pat-rotation workflow to validate rotation
Non-destructive pull_request-triggered workflow that selects a pool token and asserts, in the agent job, that needs.select_copilot_pat.outputs.copilot_pat_number is non-empty (the exact value that was silently empty with the old pre_activation wiring). To be removed after validation.
* Work around gh-aw v0.77.5 invalid-YAML rendering of top-level if
gh-aw v0.77.5 emits the top-level frontmatter `if:` on the built-in
pre_activation job WITHOUT a ${{ }} wrapper. When the condition starts with
`!` (the fork guards), the emitted `if: !(...)` is invalid YAML (a leading `!`
starts a YAML tag), which GitHub rejects as a workflow-file startup failure.
v0.68.3 wrapped it (valid); v0.77.5 does not. Confirmed independent of the
PAT-rotation change via a minimal probe.
Wrap the fork-guard conditions in parentheses so the emitted scalar starts
with `(` instead of `!` (semantically identical). Affects close-stale-prs,
devops-health-check, devops-health-groom, markdown-linter, pr-malicious-scan.
* Update select-copilot-pat README for the custom-job + on.needs pattern
* Remove temporary test-pat-rotation workflow (rotation validated)
* Fix malicious-scan repeat-spam + integrity-filter blocks
Root causes (observed on PR #237):
1. Agent's emitted add_comment body did not include the HTML marker line
(<!-- pr-malicious-scan:fingerprint=... -->), so both the orchestrator's
pre-dispatch check and the agent's own Step 1 idempotency lookup failed
to find a prior scan for the same head SHA. Result: hourly re-dispatch.
2. The github MCP tools (pull_request_read, list_pull_requests,
search_pull_requests) are blocked by the gh-aw integrity filter on PRs
from non-approved authors -- exactly the population this scanner targets.
Result: 'Integrity filter blocked N items' notes in every comment.
Fixes:
- pr-malicious-scan.agent.md: drop the github MCP toolset, add 'gh' to the
bash allowlist, and instruct the agent to use 'gh api' for all PR data
reads (PAT-authenticated, not subject to the integrity filter).
- Strengthen Step 5: the HTML marker MUST be the first line of the comment
body. Add a defense-in-depth note that the orchestrator also accepts the
visible-body sentinel.
- pr-triage-batch.yml + pr-triage-act.sh: match prior scans by EITHER the
HTML marker OR the visible-body sentinel ('Automated diff scan' + backticked
sha7), so a missing marker on a previously-emitted comment no longer
triggers re-dispatch.
Workflow disabled remotely while this lands.
* Orchestrator-only dispatch + integrity-filter opt-out
Replace the per-push pull_request_target trigger and the gh-api workaround
with the documented gh-aw pattern:
- pr-malicious-scan.agent.md: drop pull_request_target; trigger only via
workflow_dispatch from the orchestrator. Restore the github MCP toolset
with min-integrity: none (the documented level for spam-detection /
analytics workflows; safe-outputs still gates every mutation). Drop the
'gh' bash hack and visible-body sentinel requirements.
- pr-triage-batch.yml: orchestrator now posts a deterministic
'<!-- pr-malicious-scan:dispatched=SHORT --> ' comment BEFORE calling
gh workflow run. That comment is the source of truth for 'a scan has
been initiated for this head SHA' and survives every agent-side failure
mode (PAT outage, integrity block, dropped HTML marker). Dedup matches
either that orchestrator marker OR the agent's own fingerprint marker.
- pr-triage-act.sh: drop the visible-body-sentinel fallback; match the
orchestrator dispatched marker plus the agent fingerprint marker.
Validated: gh aw compile clean; bash -n clean for both worker script and
orchestrator embedded script; markdownlint clean; dedup query and POST
api tested live against PR #713.
* PR triage workflows: orchestrator, worker, and evaluate-now label
Implements docs/design/pr-triage-workflows.md:
- pr-triage-batch.yml: hourly orchestrator that classifies open PRs
- pr-triage.yml + pr-triage-act.sh: per-PR worker (state recompute,
label reconciliation, eval-trigger, ping comments with cool-down)
- evaluation.yml: gate job now also handles pull_request_target [labeled]
with the evaluate-now label as a second entry point alongside /evaluate
* Add temporary push triggers for testing pr-triage workflows
* test: live-run pr-triage worker once
* test: re-run worker for cool-down check
* fix: age gate uses created_at and applies only before first ping
* Remove temporary test triggers and inline test marker
* Add pr-malicious-scan agent workflow; replace design doc with brief overview
- New: .github/workflows/pr-malicious-scan.agent.md + compiled .lock.yml.
Static diff scanner for external (non-trusted) PR contributors. Triggers
on pull_request_target [opened/synchronize/reopened] and workflow_dispatch.
Surfaces findings as code-scanning alerts plus a single maintainer-ping
comment per head SHA when high-severity / workflow-tamper / supply-chain
hits. Never executes PR head code.
- docs/design/pr-triage-workflows.md replaced with a brief overview + diagram.
The full implementation plan is kept locally as
docs/design/pr-triage-workflows-plan.md (gitignored).
- pr-triage-batch.yml's existing dispatch-scanner branch now resolves to
the new scanner; orchestrator unchanged.
* Fix markdownlint MD038 (pipe inside code span) in malicious-scan agent