mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #87] [MERGED] feat(cursor-review): weekly catalog-drift check for the panel pins (BE-4819) #97
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#97
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/87
Author: @mattmillerai
Created: 7/28/2026
Status: ✅ Merged
Merged: 8/4/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-4819-cursor-review-catalog-drift📝 Commits (4)
40d5f0afeat(cursor-review): weekly catalog-drift check for the panel pins (BE-4819)c36a347fix(cursor-review): least-privilege the drift check + paginate the sticky lookup (BE-4819)1c47f59fix(cursor-review): close the drift check's silent-miss paths from the review panel (BE-4819)4d7efb9fix(cursor-review): survive a rebranded model family in the drift check (BE-4852) (#88)📊 Changes
7 files changed (+1838 additions, -1 deletions)
View changed files
📝
.github/cursor-review/README.md(+1 -0)➕
.github/cursor-review/catalog-drift.py(+849 -0)➕
.github/cursor-review/tests/test_catalog_drift.py(+736 -0)➕
.github/workflows/cursor-review-catalog-drift.yml(+238 -0)📝
.github/workflows/test-cursor-review-scripts.yml(+9 -0)📝
AGENTS.md(+4 -1)📝
README.md(+1 -0)📄 Description
ELI-5
The review panel pins four model ids (plus a judge). Cursor keeps swapping models under us: a pinned id gets delisted (every consumer PR then fails the review preflight), or a newer/better model ships and we never notice. The only thing watching for the second case was a hand-written
last checked <date>comment — which went stale in 13 days, and both swaps the BE-4817 audit found (Opus 5 on 07-24, Kimi K3 on ~07-26) landed inside that window and were caught by a human, not by CI.This adds a robot that checks every Monday. It reads the pins out of
cursor-review.ymlitself, asks Cursor what models actually exist, and writes what it finds into one sticky GitHub issue — which it updates in place each week and closes automatically once the drift is gone.What this changes
New
.github/workflows/cursor-review-catalog-drift.yml—schedule(17 6 * * 1) +workflow_dispatch,contents: read+issues: write:cursor-agent models(hard fail on failure — preflight's "better red than silent" stance)..github/workflows/cursor-review.yml— theDefine panel modelsheredoc plus thejudge_modelinput default. Nothing is duplicated, so the checker stays zero-maintenance when the pins are bumped (e.g. by #86).(?<![\w.-])<id>(?![\w.-])):(NO ZDR)) reproduced verbatim and a caution that an unmarked id is not thereby confirmed ZDR-eligible;last checked YYYY-MM-DDolder than 30 days (or missing).[cursor-review catalog drift] …, found by exact title prefix. Raw catalog folded into a<details>block. No findings → the sticky issue is closed and the run is a green no-op.Comparison + rendering live in
.github/cursor-review/catalog-drift.pywith 30 unit tests;cursor-review.ymland the new workflow jointest-cursor-review-scripts.yml's path filter. Docs: a row in the root README table, a paragraph in the cursor-review README's panel section (thelast checkedcomment stays the human-audit record), and anAGENTS.mdlayout line.Verification
python3 -m unittest discover -s .github/cursor-review/tests -p 'test_*.py'→ 78 passed (75 pre-existing + the new suite).actionlint(which runs shellcheck over therun:blocks) clean on every workflow;check_agents_md.pypasses.cursor-review.ymlwith synthesized catalogs: a clean catalog reportsno drift; a catalog withkimi-k3-codereplacingkimi-k2.7-codeplus a newclaude-opus-5-thinking-maxreproduces exactly the BE-4817 scenario — 1 delisted pin (withkimi-k3-codenamed as the same-lab alternative), 3 unpinned same-lab ids, stale audit date.cursor-review.yml, so a refactor of the pins block fails a cheap unit run instead of silently making the weekly check report "no drift" forever. Verified against #86's diff: it changes the pin values and the audit date but keeps every anchor, so extraction still works after that lands.cursor-agent modelswithout credentials → exit 1, empty stdout (ran it locally). So the workflow'sif ! cursor-agent modelsguard genuinely catches the auth case rather than proceeding with garbage. A second guard rejects a non-empty but unparseable catalog rather than reporting "all four pins delisted".ci-cursor-review.ymlruns (which need the key for preflight) are succeeding as recently as 2026-07-28, so the org secret does reach this repo and the missing-secret branch is a real-failure path, not the expected one. (Repo-level secret list shows onlyCLOUD_CODE_BOT_PRIVATE_KEY; the org secret list needsadmin:org, which I don't have — the succeeding runs are the evidence.)Not verified, and it cannot be until this merges: the ticket's
workflow_dispatchchecks (dispatch once, dispatch again to confirm the sticky issue updates in place; a fake-id branch run for the delisted path). GitHub only exposesworkflow_dispatchfor workflows present on the default branch, so neither can run from this branch. The dry runs above cover the same logic offline; the first scheduled/dispatched run is the live confirmation.Judgment calls
sed/yqin the workflow. The ticket sketched inline extraction; this repo's convention (AGENTS.md) is that cursor-review logic lives in.github/cursor-review/with unit tests, and inline heredocs in a scheduled-only workflow are otherwise untestable before merge. Behavior is the ticket's; only the location changed.gpt-/claude-/gemini-/kimi-. Today that resolves to exactly that list (it reuses preflight'sre.split(r"[-.]", id, 1)[0]lab derivation), and it keeps working if a pin moves to a differently-branded lab. Consequence, stated deliberately: ids from labs the panel does not pin (e.g.fable-*) are not in the review-me list — they are in the raw-catalog fold, which is where an excluded-by-policy lab belongs.--search. Search is fuzzy and eventually consistent, so a second dispatch minutes after the first could miss its own issue and file a duplicate — precisely the ticket's verification scenario.test-cursor-review-scripts.yml's path filter. Small scope add: the anchor test only protects the extraction if it runs when the file it parses changes.cursor-review.yml, which is the single source of truth for every consumer's pins, so the README row marks it internal.Notes
runs_onandmodelsinputs forcursor-review.ymlthat the workflow does not currently declare.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.