Skip to content

Add needs consistency linting and fix activation output references - #70546

Merged
pelikhan merged 2 commits into
mainfrom
pelikhan-verbose-guide
Oct 20, 2026
Merged

pelikhan merged 2 commits into
mainfrom
pelikhan-verbose-guide

Conversation

@pelikhan

Copy link
Copy Markdown
Collaborator

Summary

Disconnected needs expressions can silently evaluate to empty values, even when the referenced producer exists elsewhere in the workflow. Add the built-in needs-consistency Actions/AW rule to detect unknown dependencies, self-dependencies, cycles, missing direct dependency edges, invalid job properties, and undeclared outputs.

The rule parses dot and literal bracket accesses, including implicit job/step conditions. Compiled Actions graphs take precedence over authored AW configuration; unresolved imports, generated defaults, computed indexes, and external reusable-workflow outputs are handled conservatively. Ordering-only dependencies remain valid. Findings are warnings.

Fix the findings discovered in this repository:

  • Resolve activation prompt self-output references through their actual local step bindings, preserving expression precedence, quoted literals, empty string bindings, and hyphenated output names.
  • Remove ACE's condition on the undeclared activation.outputs.activated output. Its direct activation dependency retains Actions' default successful-dependency gate.
  • Regenerate affected workflow locks and require repository workflows to remain free of needs-consistency findings.

Validation

  • Workflow linter suite, focused compiler regressions, CLI integration, and impacted tests passed.
  • All 345 workflows compiled; workflow drift check passed.
  • gh aw lint --rules needs-consistency --json returned zero findings.
  • Go lint passed with the supported --allow-parallel-runners option; custom scoped lint passed. The aggregate gate encountered shared golangci-lint lock contention without that option.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review October 20, 2026 16:04
Copilot AI max review requested due to automatic review settings October 20, 2026 16:04
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

Commit pushed: 833a28e

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel

Outcome: reported_no_action

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.

Generated from Test Quality Sentinel · sonnet50 · 14.1 AIC · ⌖ 15.1 AIC · ◇ 6.65 AIC · ⊞ 12.6K · ◷

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Ponytail Reviewer

Outcome: reported_no_action

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.

Generated from Ponytail Reviewer · gpt56 · 10.5 AIC · ⌖ 5.39 AIC · ⊞ 14.7K · ◷

Generated by Ponytail Reviewer for #70546

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR adds a lot of new code to core business logic (704 new lines under pkg/), but it does not link an Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/70546-needs-consistency-lint-rule-and-local-activation-output-bindings.md. Please review and complete it before merging.

Decision captured in the draft:

  • A new default needs-consistency lint rule (Warning severity, AW and Actions ASTs) checks the needs graph and needs.* expressions. When a compiled Actions graph is available, it takes precedence over authored source.
  • The compiler now rewrites the activation prompt's own needs.activation.outputs.* references to local step bindings.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch. It was generated from the PR diff.
  2. Complete the missing sections. Check the alternatives, especially why findings are Warnings and not Errors, and why the fix rewrites references in place instead of adding a downstream job. Also confirm the list of cases the rule deliberately skips.
  3. Commit the finalized ADR to docs/adr/ on your branch.
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-70546: Add a needs-consistency Lint Rule and Bind Activation Prompt Outputs to Local Steps

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

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context: What is the problem? What forces are at play?
  • Decision: What did you decide? Why?
  • Alternatives Considered: What else could have been done?
  • Consequences: What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · opus55 · 39 AIC · ⌖ 40.7 AIC · ⊞ 1.9K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: Comment

No actionable blocking issues found in the changed lines. The needs-consistency implementation is covered by targeted regression cases, and the activation-output rewrite preserves literal and expression forms.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt50 · 3.21 AIC · ⌖ 0.532 AIC · ⊞ 1.6K
Comment /review to run again

@pelikhan
pelikhan merged commit 862ff31 into main Oct 20, 2026
2 checks passed
@pelikhan
pelikhan deleted the pelikhan-verbose-guide branch October 20, 2026 16:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved correctness issues affect linting valid workflows and executing activation and ACE jobs.

7 open issues
What changed in this PR

Adds dependency-consistency warnings to gh-aw’s workflow linter and corrects activation prompt output bindings.

Changes:

  • Check dependency graphs, direct needs references, and declared outputs.
  • Rewrite activation self-output references and regenerate affected locks.
  • Remove ACE’s undeclared-output gate; add tests and documentation.
File Description
pkg/​workflow/​lint/​rule_contract_test.go Add rule contract fixtures.
pkg/​workflow/​lint/​repository_workflows_test.go Require clean dependency linting.
pkg/​workflow/​lint/​performance_benchmark_test.go Preserve benchmark producer jobs.
pkg/​workflow/​lint/​needs_expression.go Analyze dependency expressions.
pkg/​workflow/​lint/​needs_consistency.go Validate dependency graphs and outputs.
pkg/​workflow/​lint/​needs_consistency_test.go Cover dependency rule behavior.
pkg/​workflow/​lint/​lint.go Register the new rule.
pkg/​workflow/​lint/​lint_test.go Update registration expectations.
pkg/​workflow/​compiler_steering_issue_test.go Verify local steering bindings.
pkg/​workflow/​compiler_experiments.go Share expression-rewriting logic.
pkg/​workflow/​compiler_activation_prompt_outputs.go Rewrite activation output references.
pkg/​workflow/​compiler_activation_prompt_outputs_test.go Cover output-binding rewrites.
pkg/​workflow/​compiler_activation_job.go Apply rewrites during prompt generation.
pkg/​cli/​lint_workflow_test.go Test CLI rule integration.
docs/​src/​content/​docs/​reference/​workflow-linters.md Document rule behavior and limits.
.github/​workflows/​weekly-safe-outputs-spec-review.lock.yml Use local steering output.
.github/​workflows/​weekly-editors-health-check.lock.yml Use local steering output.
.github/​workflows/​weekly-blog-post-writer.lock.yml Use local steering output.
.github/​workflows/​update-astro.lock.yml Use local steering output.
.github/​workflows/​unbloat-docs.lock.yml Use local steering output.
.github/​workflows/​ubuntu-image-analyzer.lock.yml Use local steering output.
.github/​workflows/​tidy.lock.yml Use local steering output.
.github/​workflows/​technical-doc-writer.lock.yml Use local steering output.
.github/​workflows/​spec-extractor.lock.yml Use local steering output.
.github/​workflows/​spec-enforcer.lock.yml Use local steering output.
.github/​workflows/​smoke-project.lock.yml Use local steering output.
.github/​workflows/​slide-deck-maintainer.lock.yml Use local steering output.
.github/​workflows/​refiner.lock.yml Use local steering output.
.github/​workflows/​q.lock.yml Use local steering output.
.github/​workflows/​purelock.lock.yml Use local steering output.
.github/​workflows/​linter-miner.lock.yml Use local steering output.
.github/​workflows/​layout-spec-maintainer.lock.yml Use local steering output.
.github/​workflows/​instructions-janitor.lock.yml Use local steering output.
.github/​workflows/​hourly-ci-cleaner.lock.yml Use local steering output.
.github/​workflows/​go-logger.lock.yml Use local steering output.
.github/​workflows/​glossary-maintainer.lock.yml Use local steering output.
.github/​workflows/​github-mcp-tools-report.lock.yml Use local steering output.
.github/​workflows/​functional-pragmatist.lock.yml Use local steering output.
.github/​workflows/​evoskill-evolver.lock.yml Use local steering output.
.github/​workflows/​eslint-miner.lock.yml Use local steering output.
.github/​workflows/​dictation-prompt.lock.yml Use local steering output.
.github/​workflows/​developer-docs-consolidator.lock.yml Use local steering output.
.github/​workflows/​dependabot-burner.lock.yml Use local steering output.
.github/​workflows/​dead-code-remover.lock.yml Use local steering output.
.github/​workflows/​daily-yamllint-fixer.lock.yml Use local steering output.
.github/​workflows/​daily-workflow-updater.lock.yml Use local steering output.
.github/​workflows/​daily-trajectory-grader-implementer.lock.yml Use local steering output.
.github/​workflows/​daily-safeoutputs-git-simulator.lock.yml Use local steering output.
.github/​workflows/​daily-safe-output-integrator.lock.yml Use local steering output.
.github/​workflows/​daily-rendering-scripts-verifier.lock.yml Use local steering output.
.github/​workflows/​daily-go-test-stubs-aider.lock.yml Use local steering output.
.github/​workflows/​daily-go-test-parallelizer.lock.yml Use local steering output.
.github/​workflows/​daily-elixir-credo-snippet-audit.lock.yml Use local steering output.
.github/​workflows/​daily-documentation-diagram.lock.yml Use local steering output.
.github/​workflows/​daily-doc-updater.lock.yml Use local steering output.
.github/​workflows/​daily-doc-healer.lock.yml Use local steering output.
.github/​workflows/​daily-compiler-threat-spec-optimizer.lock.yml Use local steering output.
.github/​workflows/​daily-community-attribution.lock.yml Use local steering output.
.github/​workflows/​daily-code-debt-aider.lock.yml Use local steering output.
.github/​workflows/​daily-caveman-optimizer.lock.yml Use local steering output.
.github/​workflows/​daily-astrostylelite-markdown-spellcheck.lock.yml Use local steering output.
.github/​workflows/​daily-architecture-diagram.lock.yml Use local steering output.
.github/​workflows/​daily-agent-of-the-day-blog-writer.lock.yml Use local steering output.
.github/​workflows/​code-simplifier.lock.yml Use local steering output.
.github/​workflows/​code-scanning-fixer.lock.yml Use local steering output.
.github/​workflows/​cloclo.lock.yml Use local steering output.
.github/​workflows/​ci-coach.lock.yml Use local steering output.
.github/​workflows/​avenger.lock.yml Use local steering output.
.github/​workflows/​archivx-agentic-workflows-analyzer.lock.yml Use local steering output.
.github/​workflows/​approach-validator.lock.yml Use local trigger-label output.
.github/​workflows/​ace-editor.md Remove undeclared-output condition.
.github/​workflows/​ace-editor.lock.yml Regenerate metadata and remove condition.

Review effort: Max

@@ -22,7 +22,6 @@ jobs:
post_ace_link:
runs-on: ubuntu-latest
needs: [activation]
"github.com/goccy/go-yaml"
)

var activationPromptOutputReferenceRegex = regexp.MustCompile(`\bneeds\.activation\.outputs\.([a-zA-Z_][a-zA-Z0-9_-]*)\b`)
bindings := make(map[string]string, len(outputs))
for name, value := range outputs {
if strings.HasPrefix(strings.TrimSpace(value), "${{") {
bindings[name] = "(" + stripExpressionWrapper(value) + ")"
Comment on lines +146 to +148
if !valid {
return fmt.Errorf("needs-consistency requires literal job IDs at %s.needs; use needs: [build]", path)
}
Comment on lines +175 to +176
_, builtin := constants.KnownBuiltInJobNames[id]
return builtin || c.imports
if path == jobPath+".if" {
return true
}
for _, field := range []string{"steps", "post-steps"} {
Comment on lines +101 to +104
if checkEdge && !connected {
c.report(path, "Needs expression references a job outside direct needs; add the producer to this job's needs list, even if it is a transitive dependency")
return
}
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.93.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants