Repository navigation
Enforce detection gates for custom workflow jobs - #70997
Conversation
Lint transitive custom-job ordering in AW and Actions graphs and enforce successful clean detection before downstream custom jobs run. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Update compiler threat specification to 1.0.66, document the ordering and clean-detection contract, and synchronize lint threat metadata and conformance mappings. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft. Commit pushed:
|
|
✅ Ponytail Reviewer completed successfully! Ponytail ReviewerOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
✅ PR Code Quality Reviewer completed the code quality review.
|
|
✅ Test Quality Sentinel completed test quality analysis. Test Quality SentinelOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅
|
There was a problem hiding this comment.
Verdict
No actionable correctness, security, or performance defects were identified in the changed lines. The review was static; repository tests were not run per the review constraints. The advisory first-pass reviewer did not produce parseable findings, so this assessment is based on the independent diff analysis.
🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt50 · 2.16 AIC · ⌖ 0.54 AIC · ⊞ 1.6K
Comment /review to run again
🏗️ Design Decision Gate — ADR RequiredThis PR adds 458 new lines of core business logic under 📄 Draft ADR committed:
The draft records one decision. After dependency lowering, the compiler enforces detection gates on the compiled job graph in 📋 What to do next
Once an ADR is linked in the PR body, this gate will re-run and check that the implementation matches the decision. ❓ Why ADRs Matter
ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you. 📋 Michael Nygard ADR Format ReferenceAn ADR must contain these four sections to be considered complete:
All ADRs are stored in
|
There was a problem hiding this comment.
🟡 Changes recommended
An authored reusable job can still bypass detection by using an inactive built-in name.
4 open issues
What changed in this PR
This PR strengthens gh-aw’s compiler and lint checks so custom jobs run before the agent or wait for successful, clean threat detection.
Changes:
- Adds transitive dependency checks and compiler-enforced detection guards, including for reusable workflow calls.
- Adds regression tests and documents the CTR-005 contract in specification version 1.0.66.
- Regenerates workflow locks with clean-detection guards and updated release dependencies.
| File | Description |
|---|---|
specs/compiler-threat-detection-spec.md |
Defines custom-job ordering and gating requirements. |
specs/compiler-threat-detection-changelog.md |
Records specification version 1.0.66. |
pkg/workflow/lint/rule_contract_test.go |
Updates rule metadata and Actions contracts. |
pkg/workflow/lint/custom_job_detection.go |
Extends detection linting across dependency graphs. |
pkg/workflow/lint/custom_job_detection_test.go |
Adds transitive and Actions lint cases. |
pkg/workflow/compiler_yaml.go |
Invokes detection enforcement after dependency lowering. |
pkg/workflow/compiler_main_job_helpers.go |
Uses transitive dependencies for agent scheduling. |
pkg/workflow/compiler_main_job_helpers_test.go |
Covers combined activation dependencies. |
pkg/workflow/compiler_custom_job_detection.go |
Adds final-graph validation and detection guards. |
pkg/workflow/compiler_custom_job_detection_test.go |
Covers compiler ordering, guards, and exemptions. |
pkg/workflow/aw/job_dependencies.go |
Introduces shared dependency-graph traversal. |
pkg/workflow/aw/job_dependencies_test.go |
Tests transitive and cycle-safe traversal. |
docs/src/content/docs/reference/workflow-linters.md |
Explains expanded lint and compiler enforcement. |
docs/src/content/docs/reference/steps-jobs.md |
Documents downstream custom-job requirements. |
.github/workflows/smoke-work-queue.lock.yml |
Gates result verification on clean detection. |
.github/workflows/smoke-test-tools.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-temporary-id.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-service-ports.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-project.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-opencode.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-kiro.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-goose.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-gemini.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-deepseek-harness.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-cursor.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-crush.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-copilot.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-copilot-arm.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-copilot-aoai-entra.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-copilot-aoai-apikey.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/smoke-codex.lock.yml |
Gates telemetry, secret scanning, and reporting. |
.github/workflows/smoke-claude.lock.yml |
Adds clean-detection telemetry gating. |
.github/workflows/release.lock.yml |
Expands agent prerequisites and success checks. |
.github/workflows/github-remote-mcp-auth-test.lock.yml |
Gates the MCP canary on clean detection. |
.github/workflows/firewall-escape.lock.yml |
Gates failure reporting on clean detection. |
.github/workflows/daily-max-ai-credits-test.lock.yml |
Gates credit verification on clean detection. |
Review effort: Max
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /codebase-design and /improve-codebase-architecture (per pr-triage: architecture_change). The new transitive JobDependencyGraph abstraction and guardCustomJobDetection consistently mirror the existing guardGatewayProvenanceJobs pattern (inject needs + wrap if with a non-overridable guard + actionsCondition = true), and test coverage in compiler_custom_job_detection_test.go / lint/custom_job_detection_test.go is thorough (ordering, transitive paths, bypass conditions, malformed if, disabled detection). No blocking issues found — posting a few targeted improvement suggestions.
📋 Key Themes & Highlights
Key Themes
- Minor consistency nit:
AuthoredJobDependencies's built-in exclusion switch uses raw string literals instead of the already-importedconstants.*JobNametyped constants, risking silent drift fromKnownBuiltInJobNames. - Duplicated validation logic: the actionlint lexer/parser expression-validation in
addCustomJobDetectionGuard(compiler) closely duplicatescustomJobDetectionCondition(lint). Worth extracting into one shared helper (e.g. inpkg/workflow/aw) so the "one valid Actions expression" contract is defined once. - Error message drift: the compiler and lint diagnostics for the same "must run before agent or after detection" violation use slightly different wording, which could read as two different rules to a user hitting both.
Positive Highlights
- ✅ Dependency-graph abstraction (
JobDependencyGraph.DependsOn) is cycle-safe and cleanly separates graph construction from traversal. - ✅ Strong parity between compiler enforcement and lint detection (dual-AST support, transitive checks, ordering diagnostics) — docs in
workflow-linters.mdandsteps-jobs.mdare updated to match the new semantics. - ✅ Test coverage exercises the tricky cases: jobs sitting between agent/detection, pre-agent jobs, warn-mode bypass via
always()/||, and malformedifexpressions.
@copilot please address the review comments above.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 171.3 AIC · ⌖ 16.3 AIC · ⊞ 10.2K
Comment /matt to run again
|
@copilot address the following outstanding work in one pass:
Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI. Sous-chef head: 2955ffe
|
Preserve transitive detection gating while adopting upstream prompt-output dependency checks and regenerate compiled workflows from merged sources. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject inactive reserved-name jobs, distinguish generated maintenance jobs in standalone linting, skip non-agent Actions graphs, share expression parsing, fix CLI fixtures, and finalize ADR-70997. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
In response to #70997 (comment): Accepted the ADR follow-up. The generated draft is now finalized and linked from the PR body. |
|
In response to #70997 (comment): No change is needed for this completion notice because it contains no actionable finding. Focused regressions and the full AST suites were run independently for the review fixes. |
|
In response to #70997 (comment): No additional change is needed for the no-findings review summary. The separate correctness findings were fixed and covered by compiler, lint, and CLI regressions. |
|
In response to #70997 (comment): No change is needed for the no-action test-quality notice. Added and ran regressions for reserved-name calls, generated maintenance jobs, non-agent workflows, shared expression parsing, and CLI input modes. |
|
In response to #70997 (comment): Accepted the associated skills-review suggestions. Typed job-name constants, shared expression parsing, and aligned diagnostics are implemented, and each inline thread has been answered. |
|
In response to #70997 (comment): Accepted. ADR-70997 is finalized with context, rationale, alternatives, and negative consequences, committed in 22b06ce, and linked from the PR body. |
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
|
Thanks @pelikhan! This PR touches 244 files (5,470 lines), mostly lock regenerations. Consider splitting core detection-gate logic and tests from spec updates and lock-file regeneration for easier review.
|
Integrate model-routing and detection alias updates, regenerate workflows, and remove an undefined redundant postAgentJobs check introduced by a recent branch commit. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
🎉 This pull request is included in a new release. Release: |


Why
Custom jobs could consume tainted agent results before threat detection completed, or bypass failed detection with status-override conditions. These jobs must run before the agent or wait for successful, clean detection.
Changes
custom-job-detectionlinting across Actions and AW ASTs, including transitive dependencies, unordered jobs, and jobs placed between agent and detection. Ordinary CI graphs without an agent are excluded; standalone locks recognize generated maintenance jobs.detection_success == 'true'. Authored conditions cannot bypass it; explicitly disabled detection remains exempt. Inactive reserved built-in names cannot be used to create custom jobs that evade the guard.The clean-output check is intentional: warn-mode findings can leave the detection job successful while its output reports unsafe results.
ADR: ADR-70997: Enforce Detection Gates for Custom Workflow Jobs in the Compiled Job Graph
Verification
origin/main, preserving upstream prompt-output dependency checks alongside transitive detection gating.