Skip to content

chore(ci): emit claude:review:passed/failed label from automated PR review [PYSDK-105]#593

Closed
helmut-hoffer-von-ankershoffen wants to merge 1 commit into
mainfrom
chore/PYSDK-105-claude-review-verdict-labels
Closed

chore(ci): emit claude:review:passed/failed label from automated PR review [PYSDK-105]#593
helmut-hoffer-von-ankershoffen wants to merge 1 commit into
mainfrom
chore/PYSDK-105-claude-review-verdict-labels

Conversation

@helmut-hoffer-von-ankershoffen

@helmut-hoffer-von-ankershoffen helmut-hoffer-von-ankershoffen commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

🛡️ Implements PYSDK-105 — Governed by CC-SOP-01, part of our ISO 13485-certified QMS.

Summary

Adds a machine-readable verdict from the automated Claude PR review so branch-protection rules can gate auto-merge on the review outcome without human intervention.

  • Two new mutually-exclusive labels: claude:review:passed (green) and claude:review:failed (red).
  • Workflow prompt (claude-code-automation-pr-review.yml) extended with a mandatory "Machine-Readable Verdict" final step. Claude emits PASS or FAIL based on the existing CRITICAL CHECKS criteria (test markers, coverage ≥85%, lint clean, conventional commits, architecture/security) and applies the corresponding label via gh pr edit --add-label … --remove-label …. The opposite label is always removed, so the labels stay mutually exclusive.

Why

Today the automated review leaves a sticky comment but no structured verdict — a human still has to skim the comment to decide whether blocking findings remain. With the new labels, branch-protection can require both green CI and claude:review:passed before GitHub-native auto-merge fires. This unblocks fully unattended auto-merge for low-risk PRs (Renovate/Dependabot bumps, the upcoming daily audit-vulnerabilities routine remediation PRs, and other auto-merge-labelled changes).

Re-emission

Every push to a PR re-runs the review (existing synchronize trigger), so the verdict is always tied to the current head commit. A stale claude:review:passed cannot persist past a new commit — the workflow flips the label on the next push.

Risk

  • ⚠️ Auto-merge based on Claude review delegates merge authority. Mitigations: (a) labels gate auto-merge only via branch protection, which still requires green CI, (b) make lint/make test/make audit remain primary defences, (c) the verdict is re-emitted on every push.
  • ⚠️ False positives (Claude flags non-issue) → mitigated by re-review on push and human override (manually applying claude:review:passed).
  • ⚠️ False negatives (Claude misses an issue) → same risk profile as today's sticky-comment review; CI gates remain the primary defence.

Out of scope

  • Branch-protection rule changes — those live in repo settings (Settings → Branches), configured separately.
  • Other Claude workflows (interactive sessions, weekly automation) are untouched.
  • No new merge automation beyond labels — GitHub-native auto-merge is reused.

Test plan

  • make lint clean.
  • CI green.
  • After merge, gh label sync (via labels-sync.yml) creates the two new labels.
  • Open a trivial test PR; confirm Claude applies claude:review:passed.
  • Open a deliberately-broken PR (e.g. a test missing a category marker); confirm Claude applies claude:review:failed.
  • Push a fix to the broken PR; confirm the label flips to claude:review:passed on next push.

🤖 Generated with Claude Code

…eview [PYSDK-105]

Adds a machine-readable verdict from the automated Claude PR review so
branch-protection rules can gate `auto-merge` on the review outcome
without human intervention.

Changes:
* `.github/labels.yml`: two new mutually-exclusive labels
  - `claude:review:passed` (green) — no blocking findings on current head
  - `claude:review:failed` (red)   — blocking findings on current head
* `.github/workflows/claude-code-automation-pr-review.yml`: extend prompt
  with a mandatory "Machine-Readable Verdict" final step. Claude must
  emit PASS or FAIL based on the existing CRITICAL CHECKS criteria
  (test markers, coverage ≥85%, lint clean, conventional commits,
  architecture/security) and apply the corresponding label via
  `gh pr edit --add-label ... --remove-label ...`. The opposite label
  is always removed, so the labels stay mutually exclusive across
  re-reviews on subsequent pushes.

Re-emission: every push to a PR re-runs the review (existing
`synchronize` trigger), so the verdict is always tied to the current
head commit — stale verdicts cannot persist.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 25, 2026 09:19
@helmut-hoffer-von-ankershoffen helmut-hoffer-von-ankershoffen requested a review from a team as a code owner April 25, 2026 09:19
@helmut-hoffer-von-ankershoffen helmut-hoffer-von-ankershoffen added sop:cc-sop-01 CC-SOP-01 Change Control (feature / planned change) type:ci CI/CD change type:chore Tooling, maintenance, routine task (conventional chore) scope:dev-only Affects only our dev/CI env; consumers unaffected auto-merge Eligible for auto-merge once CI is green skip:test:long_running Skip long-running tests (≥5min) labels Apr 25, 2026
@sonarqubecloud

Copy link
Copy Markdown

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.

Pull request overview

Adds a machine-readable outcome for the automated Claude PR review by introducing two mutually exclusive labels that can be used by branch protection / auto-merge gating.

Changes:

  • Extend the Claude PR review workflow prompt to require emitting a PASS/FAIL verdict and applying a corresponding claude:review:* label.
  • Add two new labels (claude:review:passed, claude:review:failed) to the repo’s label sync configuration.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
.github/workflows/claude-code-automation-pr-review.yml Updates the automation prompt to require applying a deterministic PASS/FAIL label verdict after the review.
.github/labels.yml Defines the new claude:review:passed/failed labels for label-sync creation.

Comment on lines +217 to +242
## Machine-Readable Verdict (MANDATORY)

After posting your review comment, you MUST emit a single-label verdict on the PR. This label is consumed by branch-protection rules to gate auto-merge — it is the only deterministic signal of your review outcome.

**Verdict criteria** (all must hold for PASS):

- No blocking findings under "CRITICAL CHECKS" — i.e. no missing test markers, no coverage drop below 85%, no `make lint` failures, no conventional-commit violations.
- No blocking architecture or security violations under "Repository-Specific Review Areas".
- Suggestions / nice-to-haves do NOT block the verdict.

If any blocking finding remains: verdict is **FAIL**.
Otherwise: verdict is **PASS**.

**Apply the label** (the two labels are mutually exclusive — always remove the opposite one):

```bash
# PASS:
gh pr edit ${{ github.event.pull_request.number }} \
--add-label "claude:review:passed" \
--remove-label "claude:review:failed"

# FAIL:
gh pr edit ${{ github.event.pull_request.number }} \
--add-label "claude:review:failed" \
--remove-label "claude:review:passed"
```

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

Applying claude:review:* labels from within this workflow can retrigger the workflow because it listens to pull_request labeled events and the job condition stays true as long as the PR has the claude trigger label. That can cause at least one redundant extra Claude run per review (and potentially a loop if GitHub emits labeled even when --add-label is a no-op). Consider gating the job so it only runs on labeled events when github.event.label.name == 'claude', or remove labeled from the triggers and switch to a different trigger for starting the review.

Copilot uses AI. Check for mistakes.
Comment on lines +232 to +241
```bash
# PASS:
gh pr edit ${{ github.event.pull_request.number }} \
--add-label "claude:review:passed" \
--remove-label "claude:review:failed"

# FAIL:
gh pr edit ${{ github.event.pull_request.number }} \
--add-label "claude:review:failed" \
--remove-label "claude:review:passed"

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

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

gh pr edit --add-label fails if the label does not already exist in the repo. Since labels-sync.yml only syncs labels on push to main, this PR’s own review run (and any runs before labels are created in repo settings) can error when trying to apply claude:review:passed/failed. To make the automation robust, add guidance/logic to ensure the labels exist first (e.g., create them if missing, or handle the “label not found” failure gracefully and still post the review).

Copilot uses AI. Check for mistakes.
@helmut-hoffer-von-ankershoffen

Copy link
Copy Markdown
Contributor Author

ok, stupid idea, obsolete

auto-merge was automatically disabled April 25, 2026 09:22

Pull request was closed

@codecov

codecov Bot commented Apr 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.
see 1 file with indirect coverage changes

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

Labels

auto-merge Eligible for auto-merge once CI is green scope:dev-only Affects only our dev/CI env; consumers unaffected skip:test:long_running Skip long-running tests (≥5min) sop:cc-sop-01 CC-SOP-01 Change Control (feature / planned change) type:chore Tooling, maintenance, routine task (conventional chore) type:ci CI/CD change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants