mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #49] [MERGED] feat(groom): reusable groom.yml — two-phase finder→verifier, GitHub-issue sink (BE-3872) #59
Labels
No labels
cursor-review-catalog-drift
groom
groom
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/github-workflows#59
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/github-workflows/pull/49
Author: @mattmillerai
Created: 7/21/2026
Status: ✅ Merged
Merged: 7/21/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-3872-groom-reusable-workflow📝 Commits (2)
f0444f5feat(groom): reusable groom.yml — two-phase finder→verifier, GitHub-issue sink (BE-3872)447941dfix(groom): address cursor-review panel — isolate verifier job, harden allowlist + filing (BE-3872)📊 Changes
3 files changed (+686 additions, -5 deletions)
View changed files
➕
.github/workflows/groom.yml(+675 -0)📝
AGENTS.md(+10 -5)📝
README.md(+1 -0)📄 Description
ELI-5
We already have a robot that reviews pull requests (
cursor-review.yml). This adds a second robot, groom, that goes the other way: on a schedule it reads a whole repo (not a diff) and looks for cleanups worth doing — duplicated code, dead code, inconsistent patterns. One agent proposes candidates, a second, independent agent plays skeptic and confirms/rejects each, and the survivors are filed as GitHub issues (labeledgroom) for humans to pick up. It never writes code, opens a PR, or merges anything — it only files issues. A durable ledger (built in Phase 1) remembers what it already filed or what a human rejected, so it never nags you twice.What this does
Adds
.github/workflows/groom.ymlas aworkflow_callreusable, cloning the cursor-review topology and reusing the Phase-1 briefs + ledger under.github/groom/as the single source of truth:gatejob — validatessinkand applies the volume gate (skip a repo with no merges incadencedays; fail-open).auditjob (contents: readonly) — checks out a clean default-branch copy, substitutes the{{…}}placeholders infinder.md/verifier.md, runs the finder then a fresh independent verifier viaanthropics/claude-code-action, and uploads the verified findings. This job holds no write credentials — it is structurally incapable of writing to GitHub.filejob — dedups survivors (CONFIRM/DOWNGRADE only) against the durable ledger and opensgroom-labeled GitHub issues as the configured bot (Comfy: cloud-code-bot viabot_app_id+BOT_APP_PRIVATE_KEY), embedding the ledger's signature marker so the next run won't re-file. Security-adjacent findings getgroom-security(investigate, don't auto-implement).Triggers (
schedule+workflow_dispatch, never on-PR) and the requiredconcurrency:group live in the caller (documented in the header + README), matching how cursor-review's triggers live in its caller. A workflow-levelconcurrencygroup also serializes runs per target repo as a backstop against the ledger's TOCTOU race.Inputs
themes,cadence,volume_gate,sink(defaultgithub),max_findings,scope_label/scope_desc,model,workflows_ref,bot_app_id,dry_run. Secrets:ANTHROPIC_API_KEY(required),BOT_APP_PRIVATE_KEY(whenbot_app_idset).Acceptance criteria
groom.ymlreusable exists; files verified findings as GitHub issues, acted as cloud-code-bot, no credentials in the agent step (theauditjob iscontents: read-only and the agent gets onlyANTHROPIC_API_KEY)..github/groom/ledger.py) before filing, reusing its exact signature marker.supervisor-groom.shbriefs verbatim (same.github/groom/*.md), anddry_runprints exactly what it would file for a spot-check. Live parity against a studio run on a test repo is the remaining manual verification step — see below.agent-oksink is deferred (needs orgLINEAR_API_KEY), per the ticket —sink: linearfails the run loudly rather than silently filing nothing.Verification done
actionlintclean ongroom.yml..github/groomledger tests: 37 passing (dep unchanged).agents-md-integritychecker passes (1 pre-existing CODEOWNERS warning, unrelated).signature_markerreuse round-trips; the filing logic verified for dry-run, live-command shape,max_findingscapping (with deferral warning), invalid-signature skip, andgroom-securityrouting.workflow_dispatchon a test repo requires the orgANTHROPIC_API_KEY+ cloud-code-bot install on that repo — that end-to-end run (and the studio-parity spot-check) is the reviewer/operator step before moving thev1tag.Judgment calls (flagged)
themesdefault: I could not read epic BE-3870, so I set the default to the finder brief's own five dimensions verbatim — a no-op that preserves studio parity by default while letting a caller narrow it. If the epic's "safe starter set" is a specific narrower list, adjust the default.bot_app_id/BOT_APP_PRIVATE_KEY(consumer supplies its own App). Comfy uses cloud-code-bot.sink != github) path: this is a not-yet-built feature with a clear error, not a regression removing an existing capability — there is no existing linear-sink path in this new workflow to redirect to, and the ticket explicitly defers Linear. So it ships as a loud guard.schedule); aworkflow_dispatchfrom a non-main branch would groom that branch. Acceptable and arguably desirable; noted for awareness.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.