Skip to content

Name Each Job That Posts the Required Check Off a Pull Request Run - #3799

Merged
ptr727 merged 8 commits into
developfrom
feature/burn-3797-fix1
Nov 2, 2026
Merged

ptr727 merged 8 commits into
developfrom
feature/burn-3797-fix1

Conversation

@ptr727

@ptr727 ptr727 commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

In spec/audit.py, check_interface skipped the D1.5 every-event finding for the whole workflow once any one job used the pull_request-only name expression. A second job could still post the required check on a non-PR run, and nothing flagged it.

The check now reads each job's name: together with its job key. A job's name off a pull_request run is its literal name, or the || fallback string when the name uses the pull_request-only expression. Some workflows are triggered by events other than pull_request. In those, every job whose off-PR name equals the required check gets its own DRIFT, and the finding names that job. The other jobs no longer affect it.

The existing missing-name DRIFT keeps its develop behaviour. It covers names that are neither a literal nor the pull_request-only expression, and it still flags an expression whose two branches are both the required name on a pull_request-only workflow. It now runs alongside the per-job check rather than ahead of it.

  • A job falling back to the required name, with no gated job. It reports both findings, and both are true. The PR run never posts the check, and a non-PR run does.
  • An expression whose two branches are both the required name, on a dispatch-triggered workflow. It reports only its per-job finding. That job does post the check on the PR run, so the missing-name finding would be false there.

Repro on a constructed stub triggered by pull_request and workflow_dispatch:

  • A literal sibling. One job is named by the D1.5 expression, and a second carries the literal Check pull request workflow status job. This returned [] before the change. It now returns one DRIFT naming the second job.
  • A fallback sibling. The second job is named ${{ github.event_name == 'pull_request' && 'Other job' || 'Check pull request workflow status job' }}. This also returned [] before the change. It now returns one DRIFT naming that job.

Unchanged: a gated job alone raises no finding. A literal name on a pull_request-only workflow raises no finding either.

Tests

New INTERFACE_CASES rows in tests/test_audit_helpers.py:

  • A literal sibling beside a gated job.
  • A fallback sibling beside a gated job.
  • Two literal jobs, one finding each.
  • A fallback-only job, both findings.
  • An every-event expression on a dispatch-triggered workflow, one finding.
  • A fallback job beside an every-event expression naming another check, both findings.

Two new tests assert which job each finding names, and that the dispatch every-event case reports its per-job finding rather than the generic one. Run against develop's spec/audit.py, every new row fails except the dispatch every-event row. That row keeps develop's count, so its message test is what pins it. The last row also fails if the suppression stops checking for the required name.

spec/audit.py --selftest and the full OPERATIONS.md "Local Verification" block pass.

Closes on promotion: #3334

🤖 Generated with Claude Code

ptr727 and others added 3 commits November 1, 2026 18:34
check_interface skipped the every-event DRIFT for the whole workflow
once any job used the pull_request-only name expression. A second job
carrying the literal required name, or an expression falling back to
it, still posted the required check on a non-PR run.

The check now collects every name a job can post off a pull_request
run and raises the DRIFT whenever the required name is among them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read each job's name with its job key, so the finding names the job
that can post the required check off a pull_request run. Word it as a
run other than pull_request, which also covers a job whose expression
falls back to the required name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a case with two literal check-name jobs on a workflow a dispatch
also triggers, so collapsing the per-job findings to one fails a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings November 2, 2026 02:47
@ptr727 ptr727 added the comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses label Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@ptr727

ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 01118f071fe01924646618888ba51f8b48e5a780, the content this pull request carries at that commit against develop, and it recorded 0 findings.

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

A moderate finding in spec/audit.py shows fallback-only job names bypass the per-job classification and omit the offending job key, leaving the new behavior incomplete.

1 open issue
What changed in this PR

This pull request updates the D1.5 workflow interface audit to evaluate each job’s effective name on runs other than pull_request, preventing one correctly gated job from masking another offending job.

Changes:

  • Tracks job names alongside their job keys.
  • Reports each offending job with a separate drift finding.
  • Adds coverage for literal siblings, fallback expressions, and multiple offending jobs.
  • Updates the finding wording to describe non-pull_request runs.
File Summary Findings
tests/​test_audit_helpers.py Adds regression coverage for sibling, fallback, duplicate-name, and job-specific finding scenarios. Nit: Rename the test at line 663 so its name reflects the non-pull_request behavior rather than “every event.” (1 vote)
spec/​audit.py Implements per-job required-check name analysis and reporting. Moderate/P2: Fallback-only names bypass the per-job path, so findings do not identify the offending job. (2 votes)

Nit: Remove the standalone comment near line 994 because it adds a comment-gate obligation without documenting non-obvious rationale. (1 vote)

Review effort: Lite

Comment thread spec/audit.py Resolved
The per-job finding sat behind the missing-name branch, so a workflow
whose only matching job falls back to the required name off a
pull_request run got the generic finding and never the one naming the
job. Run the per-job check on its own, beside the missing-name one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.72%. Comparing base (ac508e1) to head (9549ecb).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3799      +/-   ##
===========================================
+ Coverage    82.71%   82.72%   +0.01%     
===========================================
  Files           29       29              
  Lines         9626     9629       +3     
===========================================
+ Hits          7962     7966       +4     
+ Misses        1664     1663       -1     
Flag Coverage Δ
python-3.13 82.72% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

ptr727 and others added 2 commits November 1, 2026 18:55
An expression yielding the required name on both branches posts it on
the pull_request run, so where another event triggers the workflow its
job's off-PR finding covers it. Skip the missing-name finding there,
which claimed the pull_request run never posts the check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Literal names cannot reach the suppression, since the missing-name
branch already requires the required name not be a literal one. Read
the expressions' pull_request strings alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ptr727

ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 5cee26196d4f1baccee148f2ad3a22832ba240ec, the content this pull request carries at that commit against develop, and it recorded 2 findings.

ptr727 and others added 2 commits November 1, 2026 19:06
Read the suppression from an expression whose two strings are both the
required name, as its comment says, and assert that such a job on a
dispatch workflow reports its own off-PR finding, not the generic one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a case where one job names another check on every event beside a
job falling back to the required name, so a suppression reading any
every-event expression rather than the required name's fails a test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ptr727

ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 9549ecba4dfa70060530bf3f7fc0a7623551e03c, the content this pull request carries at that commit against develop, and it recorded 0 findings.

@ptr727

ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

Answers to the Copilot round on 01118f0. Its FINDINGS WITH NO THREAD block counted (1), and its overview table names two findings that sit on no thread, so each is answered below.

  • tests/test_audit_helpers.py:663, "Rename the test at line 663 so its name reflects the non-pull_request behavior rather than 'every event.'" Fixed in 43c5b1a. It is now test_the_off_pull_request_finding_names_the_job_beside_a_gated_one.
  • spec/audit.py:994, "Remove the standalone comment near line 994 because it adds a comment-gate obligation without documenting non-obvious rationale." No change needed. The comment gives the reason findings are counted per job: neither a gated job nor a missing one excuses another job that yields the name off a pull_request run. The pooled read it replaces is the defect this pull request fixes, so the reason is the non-obvious part. The PR carries the comments label for it.

@ptr727
ptr727 merged commit 23c7d78 into develop Nov 2, 2026
13 checks passed
@ptr727
ptr727 deleted the feature/burn-3797-fix1 branch November 2, 2026 03:27
ptr727 added a commit that referenced this pull request Nov 2, 2026
…ings With an Acknowledgment Record, and Mark Direct-Push Closures (#3797)

Promotes the changes merged into `develop` since promotion #3778 to
`main`, the second round of a backlog burndown.

- [#3784](#3784) has the
write guard read a push option attached to `-o` as that option's value,
as git does, rather than as more short flags. It also walks a
short-option cluster carrying a digit, such as `-4f`.
- [#3796](#3796) fixes
five pull-request-gate and release-task defects:
- Each aggregator's `name:` gives the ruleset-bound required check name
only on a `pull_request` run, so a dispatch run cannot mask it.
`spec/audit.py` `check_interface` reads that expression.
- The stubs drop the `pull_request` base-branch filter, and "Adopting
the Gates" states the task's preconditions.
- A re-run release takes the Latest flag only where its version sorts at
or above the current Latest release.
- The `lint` job runs its Python steps under the first `python-versions`
entry.
- `dotnet format` and `dotnet test` run per tracked workspace where the
root holds no solution or project.
- [#3793](#3793) has
`pr_review.py merge` read an acknowledgment record, posted with `comment
--ack KEY=OUTCOME`, for findings no thread carries and for a verdict
naming no counted finding. Every `merge` run ends on one `next=` line
the skills follow, and the digest reads the excluded-files refusal as
`refusal=EXCLUDED`.
- [#3792](#3792) has a
direct push to `develop` on an operational-model repository name the
issues it fixes in its commit message's on-promotion line.
`backlog-burndown` assembles the promotion body from the pull request
that merged each commit, falling back to a direct push's own message.
Its claim lookup matches only claim comments, and
`git-commit-conventions` names the abandon-discard exception.
- [#3798](#3798) has
`has_prose` read an inline token's text children outside code, so an
inline-code span alone no longer counts as prose. It answers this
promotion's first review round.
- [#3799](#3799) has
`check_interface` read each job by its key on a workflow a non-PR event
triggers. A job whose off-PR name is the required check gets its own
DRIFT. It answers this promotion's first review round.

## Downstream effect

From #3796: once this reaches `main`, every downstream
`test-pull-request.yml` whose aggregator carries a literal `name:` shows
`check_interface` DRIFT. It shows that until its next resync. A resync
clears it by replacing the aggregator's `name:` line with the
expression. No ruleset changes, since the `context:` a pull request run
posts is unchanged.

Fixes #3720
Fixes #3334
Fixes #1516
Fixes #3487
Fixes #1485
Fixes #1938
Fixes #3718
Fixes #3724
Fixes #3777
Fixes #3773
Fixes #1276
Fixes #1307
Fixes #3780

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants