Skip to content

fix(groom): pin ci-groom.yml by SHA and stop the bumper reporting unpinnable callers as converged (BE-6015) - #107

Open
mattmillerai wants to merge 6 commits into
mainfrom
matt/be-6015-groom-caller-registration
Open

fix(groom): pin ci-groom.yml by SHA and stop the bumper reporting unpinnable callers as converged (BE-6015)#107
mattmillerai wants to merge 6 commits into
mainfrom
matt/be-6015-groom-caller-registration

Conversation

@mattmillerai

Copy link
Copy Markdown
Contributor

ELI-5

The groom workflow lives here, and other repos "call" it by pointing at a specific commit of this repo. A robot keeps those pointers up to date, but it only knows about repos listed in a config list. Four repos were calling groom without being on that list, so their pointers had gone stale — and this repo's own caller had a leftover REPLACE_ME placeholder instead of a real pointer, so it had been crashing on startup every single day while the robot cheerfully logged it as "already up to date." This fixes our own pointer, and makes the robot say "I can't move this one" instead of pretending it's fine.

What this does

Two changes, both from the same root cause — a caller that is registered with the fleet but that the fleet cannot actually move.

1. ci-groom.yml is pinned by a real SHA. BE-4004 (#56) landed the interval gate behind a deliberate fail-loud REPLACE_AT_MERGE_WITH_THIS_PRS_SQUASH_SHA placeholder in both uses: and workflows_ref:, to be hand-bumped to that PR's squash SHA after merge. The hand-bump never happened. Every scheduled ci-groom run since has failed at startup on an unresolvable ref — six consecutive schedule failures, each with zero jobs. Both refs now pin bcde90f4, the same SHA the other groom callers carry, which puts this caller back under bump-groom-callers.yml so future bumps move it automatically.

2. bump-callers.sh no longer reports an unpinnable caller as converged. The skip branch treats a no-op rewrite as "already at NEW_SHA", but a no-op rewrite only means that when the file carries a 40-hex pin the pass could have moved. A caller that names the reusable and pins it with a placeholder, tag or branch produces a byte-identical no-op — so the log said already at <short> — skipping for a file that had been crashing for weeks. It now emits a ::warning:: naming the file instead. Control flow is unchanged: the entry is still skipped, still a warning rather than a failure, so one unpinnable caller cannot abort the fan-out. It stays silent when the reusable-name probe (GW_USES, the same probe the rewrite address uses) cannot identify a uses: spelling, so a converged caller never warns spuriously.

Out-of-repo work this PR completes (no commit — it is an Actions variable)

The bulk of BE-6015 is a GROOM_CALLERS edit, already applied and verified: four live callers that were never registered are now on the roster, and the stale pre-rename repo name was corrected in the same edit. Dispatching bump-groom-callers.yml then opened bump PRs against exactly those four, each moving uses: and workflows_ref: in lock-step and touching nothing else. An independent sweep of all 196 Comfy-Org repos confirms nine live groom callers exist and all nine are now registered — no tenth was missed. Consumer names are deliberately not listed here; this repo is public and most callers are private.

Merging this PR is what gets the ninth caller onto the same SHA as the other eight.

Verification

shellcheck -x clean; bash .github/bump-callers/tests/test_bump_callers.sh128 passed, 0 failed; the cursor-review (40), agents-md-integrity (18) and groom (170) unittest suites all pass; check_agents_md.py --root . passes (its one warning, no CODEOWNERS, is pre-existing on main). The new bump-callers test is a genuine red→green regression test: reverting only bump-callers.sh drops it to 126 passed / 2 failed.

Judgment calls and things a reviewer should weigh

  • Scope. The ticket's plan is entirely operational (edit the variable, dispatch the bumper). I added this in-repo change because acceptance criterion 3 — "after merge all nine pin the same SHA" — is unreachable without it, and because the ticket's own measured state records this repo's pin as a "local path," which is not what is on main. Flagging rather than assuming: if you would rather split the bump-callers.sh warning into its own PR, it is the second commit and drops cleanly.
  • This makes a dormant scheduled job actually run, for the first time since it was written. Checked before pinning: all six inputs it passes are declared in groom.yml at bcde90f4; both secrets it forwards resolve (ANTHROPIC_API_KEY from the org, CLOUD_CODE_BOT_PRIVATE_KEY from the repo); builder is unset so it defaults to false — issues only, no auto-PRs; and interval_days falls back to 7, so weekly. Reasonable to workflow_dispatch it once with dry_run: true after merge before letting the schedule take it.
  • A tag-pinned caller in any fleet will now emit the new warning. That is intended — this repo mandates full-SHA pins and a bare @v1 fails the consumer-side pin validation — but it is a behavior change visible in every fleet's run summary, not just groom's.
  • Not done, and it needs a human: the ticket asks for the before/after roster JSON in a Linear comment. It cannot go here — the roster names four private repos and this repo is public. The JSON is captured on the runner at .supervisor-state/BE-6015-groom-callers/{before,after}.json.
  • Adjacent, deliberately not fixed: CURSOR_REVIEW_CALLERS and AGENTS_MD_CALLERS still carry the same stale pre-rename repo name. BE-5921 owns that class across every *_CALLERS variable, and the ticket says to fix it in one place, not two.
  • The public-log gap the bump-callers README already documents (a step's env: block prints before masking) now exposes four more names. Pre-existing and fleet-wide, but this edit widened it.

… fleet can bump it (BE-6015)

BE-4004 (#56) landed the interval gate behind a fail-loud
REPLACE_AT_MERGE_WITH_THIS_PRS_SQUASH_SHA placeholder that was meant to be
hand-bumped to that PR's squash SHA. The hand-bump never happened, so every
scheduled ci-groom run since has failed at startup on an unresolvable ref (zero
jobs, six consecutive schedule failures). The placeholder is not 40-hex, so the
bumper's rewrite could not move it either and logged the file as already
converged.

Pin both refs (uses: and workflows_ref, in lock-step) to bcde90f — the SHA the
other eight groom callers already carry — which puts this caller back under
bump-groom-callers.yml, where future bumps move it automatically.
…nable caller (BE-6015)

A no-op rewrite only means "already at NEW_SHA" when the file carries a 40-hex
pin the pass could have moved. A caller that names the reusable but pins it with
a placeholder, tag or branch produces a byte-identical no-op, so the skip branch
reported it as converged — which is what let a caller that failed every run at
startup read as healthy in the bump log.

Control flow is unchanged (the entry is still skipped); only the report differs.
Silent when the reusable-name probe cannot identify a uses: spelling, so a
converged caller never warns spuriously.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fde2bd88-3774-430e-9cf4-a36e05a999b6

📥 Commits

Reviewing files that changed from the base of the PR and between 026e3a9 and e367d08.

📒 Files selected for processing (3)
  • .github/bump-callers/bump-callers.sh
  • .github/bump-callers/tests/test_bump_callers.sh
  • AGENTS.md
📝 Walkthrough

Walkthrough

The caller bumping flow now validates roster entries, repairs supported pin formats, records unpinnable files, and reports aggregate failures after processing the full fleet. Tests and guidance cover sibling-only, empty, dynamic, and missing references.

Changes

Caller roster validation

Layer / File(s) Summary
Roster entry validation
.github/bump-callers/bump-callers.sh, .github/bump-callers/tests/test_bump_callers.sh, .github/bump-callers/README.md
The script detects roster entries that reference only sibling workflows. It records roster errors, suppresses misleading “already pinned” output, and tests wrong-fleet and no-reusable cases. Supported pin shapes are rewritten.
Fleet failure reporting
.github/bump-callers/bump-callers.sh, .github/bump-callers/README.md, .github/bump-callers/tests/test_bump_callers.sh, AGENTS.md
The dispatcher aggregates unpinnable files and exits nonzero after fan-out completes. Documentation describes dynamic-reference, missing-file, and roster validation failures. Pin guidance stays in line.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matt/be-6015-groom-caller-registration
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch matt/be-6015-groom-caller-registration

Comment @coderabbitai help to get the list of available commands.

@mattmillerai mattmillerai added agent-coded Authored by the agent-work loop cursor-review Multi-model cursor review labels Aug 2, 2026
@mattmillerai
mattmillerai marked this pull request as ready for review August 2, 2026 07:39

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔍 Cursor Review — Consolidated panel

Triggered by @mattmillerai.

Found 10 finding(s).

Severity Count
🟠 High 2
🟡 Medium 3
🟢 Low 3
⚪ Nit 2

Panel: 8/8 reviewers contributed findings.

Comment thread .github/bump-callers/bump-callers.sh
Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread .github/workflows/ci-groom.yml Outdated
Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread .github/workflows/ci-groom.yml Outdated
Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread .github/bump-callers/bump-callers.sh Outdated
… the run (BE-6015)

Review follow-ups on the BE-6015 fix. The pin check now runs against the
ORIGINAL file content and independently of whether the rewrite changed
anything, so it also catches the case where an unmovable `uses:` sits beside a
stale-but-movable `workflows_ref:` — the rewrite changes bytes there, the file
is staged, and the bump PR would have shipped with the unresolvable ref still
in place and no warning at all.

- anchor both probes to `^[^#]*<key>:` so a commented-out old pin or a docs URL
  cannot vouch for a live pin that is still a placeholder
- require a whitespace/EOL boundary after the 40-hex run, so a mutable ref that
  merely STARTS with 40 hex (`<sha>-wip`) is not read as a commit pin
- validate the `workflows_ref:` half too — a `uses:` at NEW_SHA beside a
  `workflows_ref: main` is the split state a twice-pinning caller prevents
- distinguish a stale ROSTER entry (file calls only a sibling reusable) from an
  unpinned file, and blame the variable rather than telling a human to hand-pin
  a workflow the file does not use
- accumulate offenders and exit non-zero with an aggregate `::error::` after the
  whole fleet is processed: the fan-out still completes, but a run containing a
  caller the bumper cannot keep current no longer reports success

ci-groom.yml: correct the now-stale `permissions:` ordering note (the pin is at
main's tip, i.e. at/after the BE-4214 CLI migration, so the shorter grant
matches what that groom.yml declares; only a BACKWARDS move is unsafe).

Verified `Comfy-Org/github-workflows` IS present in `vars.GROOM_CALLERS`
(`.github/workflows/ci-groom.yml`), so the caller is genuinely back under the
fleet and the pin will move on the next bump.
@mattmillerai

Copy link
Copy Markdown
Contributor Author

Parked during the merge-backlog sweep — this needs a design decision, not a rebase.

Attempting to merge current main into this branch produces resolvable text conflicts but a semantic collision with #79 (BE-4662), which landed first. After resolving all three conflicted files, the suite runs 198 passed, 7 failed — and the 7 failures are the collision, in both directions.

BE-4662 rewrote the pin substitution to target the pin token rather than "a 40-hex on a line mentioning github-workflows", so any literal ref shape now moves — full SHA, short SHA, tag, or a REPLACE_AT_MERGE_… placeholder. Verified against the merged rewrite rules:

uses: …/groom.yml@REPLACE_AT_MERGE_WITH_THIS_PRS_SQUASH_SHA  ->  …/groom.yml@<NEW_SHA>
workflows_ref: REPLACE_AT_MERGE_WITH_THIS_PRS_SQUASH_SHA     ->  workflows_ref: <NEW_SHA>
workflows_ref: v1                                            ->  workflows_ref: <NEW_SHA>

That invalidates this PR's central premise. The pin-integrity check here warns "the bumper cannot move it; pin it by full SHA by hand" for precisely the three shapes the bumper now self-heals.

#79's tests that this PR breaks (all expected exit 0, now exit 1 — a caller this fleet can keep current is refused):

  • a TAG-pinned workflows_ref moves in lock-step with uses: (BE-4662)
  • a SHORT-SHA (and quoted) workflows_ref also moves in lock-step (BE-4662)
  • a lowercase owner/repo is still THIS repo — both halves move (BE-4662)

This PR's own tests that are now factually wrong:

  • a caller with NO movable pin FAILS the run… — asserts "committed nothing" / "opened no PR"; the rewrite moved both placeholder pins, so the file was staged and committed.
  • an unmovable 'uses:' is caught even when the rewrite DOES change bytes — asserts REPLACE_AT_MERGE survives into the PUT; it no longer does.
  • a pinned 'uses:' beside an UNPINNED workflows_ref is still un-bumpable — asserts "committed nothing"; workflows_ref: main is now movable.

Also worth noting: the two other things this PR does are already on main independently —

What still looks worth salvaging, and the reason this is parked rather than closed:

  1. The roster-entry check — a file that names only a sibling reusable and none of ours, where the vars.*_CALLERS entry is the bug, not the file. That test passes against merged main and BE-4662 does not cover it.
  2. The README / AGENTS.md prose on the two-step enrollment (merge the caller and add it to the roster).

Both are separable from the obsolete uses:/workflows_ref not-40-hex checks. Suggested path: drop those two branches of the check, keep the roster branch plus the docs, and delete the four superseded test cases.

No changes were pushed to this branch — it is exactly as it was.

@mattmillerai

Copy link
Copy Markdown
Contributor Author

Parked — needs re-authoring, not conflict resolution. Left untouched (head still 963557f).

I attempted this one properly and the test suite settled it. Three findings:

  1. Commit 1 is superseded. It re-pins ci-groom.yml to bcde90f; main is now at 176c0dd. Taking the branch's side rolls the pin backwards. Mechanical — resolved to main cleanly.
  2. Two of the three PIN_OK probes are obsolete, and one contradicts main. BE-4662 (since merged) anchored the rewrite to the pin token rather than to 40-hex-ness, so a tag- or short-SHA-pinned workflows_ref is movable now, and an unmovable uses: is already caught by the post-rewrite STALE_PINS assertion that fails the repo. Keeping PIN_OK as authored produces false "unpinnable" reports on callers the bumper can in fact bump: I tried it, and the unioned suite went 194 passed / 11 failed, the failures being exactly main's BE-4662 lock-step cases (reftag, refshort, lowercase) plus the no-false-positive case.
  3. The branch's own tests encode the behavior main deliberately changedtest_bump_callers.sh asserts pins groom.yml with something other than a 40-hex commit SHA in three places. Reconciling means rewriting those expectations, which is authoring your intent, not merging it.

What genuinely survives and is still worth landing: the one case BE-4662 cannot see — a roster entry pointing at a file that names no uses: for this fleet at all. The rewrite changes nothing, no pin is left stale, and the run reports already at <short> — skipping. The file is fine; the roster entry is the bug, and only a pre-rewrite look can tell those apart. I narrowed PIN_OK to just that case and the suite moved to 178/27 — worse, because the branch's own tests then fail — which is the clearest evidence that this needs your decision on the intended contract rather than my guess.

Suggested shape: drop commits 1–2, keep a single commit implementing only the no-uses:-for-this-fleet warning, and delete the three test assertions BE-4662 invalidated.

Nothing was pushed; branch is byte-identical to before I started.

Resolves a semantic conflict with #79 (BE-4662), which anchored the
bump-callers rewrite to the pin TOKEN rather than 40-hex-ness after this
branch was opened — so a placeholder/tag/short-SHA uses:/workflows_ref
pin is now self-healed on the next bump instead of needing a human. Drop
this branch's two now-redundant/contradicting pre-rewrite pin-shape
checks (uses: not-40-hex, workflows_ref not-40-hex) and keep only the
roster-entry check (a caller registered in vars.*_CALLERS whose file
names no uses: of this fleet's reusable at all), which BE-4662 does not
cover. ci-groom.yml's own pin is superseded by main (#102, then further
bumps) so that file now matches main byte-for-byte. Delete the five
BE-6015 tests whose expectations BE-4662 invalidated, keep the two
(roster-entry, no-github-workflows-uses) that still hold, and correct
the AGENTS.md/README prose that claimed a placeholder/tag/branch pin is
un-bumpable — it no longer is.
…eals pin shape (BE-6015)

The merge with main pulled in BE-4662, which anchors the caller rewrite to
the pin token rather than 40-hex-ness — a placeholder/tag/branch/short-SHA
pin now self-heals on the next bump instead of needing a human. Update the
AGENTS.md and bump-callers README prose that still claimed those shapes are
un-bumpable; the only case that remains genuinely un-bumpable is a roster
entry naming no uses: of this fleet's reusable at all.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/bump-callers/bump-callers.sh:
- Around line 419-437: After appending a failed entry to UNPINNABLE in the
caller-processing flow, immediately skip further handling of that roster entry
so it cannot be added to PEND_CONTENT or staged. Update the wrongfleet fixture
to include workflows_ref: and verify the scenario creates neither a commit nor a
PR, while preserving processing of other entries.

In `@AGENTS.md`:
- Around line 156-159: Update the roster-failure description in AGENTS.md to
state that the script fails only when it parses a github-workflows reusable call
whose sibling workflow differs from WORKFLOW_FILE. Remove the claim that a
roster entry with no fleet uses: causes the run to fail, while preserving the
distinction between an invalid roster entry and a movable pin.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6a9dabf3-bbd3-40db-8627-5976a7172128

📥 Commits

Reviewing files that changed from the base of the PR and between 7f7c9bf and 026e3a9.

📒 Files selected for processing (4)
  • .github/bump-callers/README.md
  • .github/bump-callers/bump-callers.sh
  • .github/bump-callers/tests/test_bump_callers.sh
  • AGENTS.md

Comment thread .github/bump-callers/bump-callers.sh Outdated
Comment thread AGENTS.md Outdated
…ws_ref (BE-6015)

CodeRabbit review: the roster-entry check flagged PIN_OK=0 for a file that
calls only a sibling fleet's reusable but did not stop processing, so rule
2's deliberately-unaddressed workflows_ref: rewrite (it can't distinguish
'ours' from a sibling job's with: input) still fired and staged the
sibling's asset ref at this fleet's SHA. continue immediately after
recording the failure so a bad roster entry can no longer corrupt a
sibling's config while it's being reported. Extends the wrongfleet fixture
with a workflows_ref: line so the suite proves it (red without the fix:
'committed nothing' / 'opened no PR' both fail).

Also tightens the AGENTS.md roster-failure description: the run fails only
when a github-workflows reusable IS parsed and it's a sibling's, not on
every file with no fleet uses: at all (that case stays a silent skip).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-coded Authored by the agent-work loop cursor-review Multi-model cursor review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants