mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #382] [MERGED] feat(cursor-review): optional direct-OpenAI review cell via a pinned Codex CLI (BE-19639) #383
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#383
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/382
Author: @mattmillerai
Created: 10/8/2026
Status: ✅ Merged
Merged: 10/8/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-19639-openai-direct-cell📝 Commits (6)
6e7bfdffeat(cursor-review): optional direct-OpenAI review cell via a pinned Codex CLI (BE-19639)ce1e2fdfix(cursor-review): keep the direct-OpenAI cell on hosted runners with the canonical ref guard83123bdfeat(cursor-review): the direct cell replaces the Cursor OpenAI cell by default (BE-19639)1a237befix(cursor-review): make the direct-OpenAI cell genuinely advisory and keep its key off disk (BE-19639)c55df99fix(cursor-review): splice the prior-review ledger into the direct cell's prompt; keep CODEX_HOME under RUNNER_TEMP (BE-19639)b37c098test(groom): bind the dependabot npm-entry check to the groom directory, and assert the cursor-review one too (BE-19639)📊 Changes
8 files changed (+547 additions, -11 deletions)
View changed files
📝
.github/cursor-review/README.md(+3 -0)➕
.github/cursor-review/package.json(+8 -0)📝
.github/cursor-review/tests/test_workflow_ref_guard_parity.py(+1 -1)📝
.github/dependabot.yml(+15 -0)📝
.github/groom/tests/test_claude_code_pin.py(+14 -3)📝
.github/workflow-pins/tests/test_check_workflow_pins.py(+6 -2)📝
.github/workflows/cursor-review.yml(+497 -5)📝
docs/callers/cursor-review.md(+3 -0)📄 Description
ELI5
The review panel can only use models Cursor offers. This adds an optional extra
reviewer that talks to OpenAI directly, so the panel can include a model Cursor
does not carry. It is off unless a repo turns it on, and when it is off nothing
about today's reviews changes.
What this adds
openai_direct_model(default'') — an OpenAI model id reviewed as oneadversarial cell through the OpenAI API directly.
openai_direct_replaces_cursor_openai(defaulttrue) — when the directcell is in effect, preflight drops the Cursor
gpt-*cell(s) so the OpenAI laneis reviewed once;
falseruns both for a side-by-side comparison. Preflightfails rather than leave the Cursor panel empty.
OPENAI_API_KEY..github/cursor-review/package.json— pins@openai/codexto an exact version.review-openai-direct./.github/cursor-review, so the pin is actually watched.openai_direct_model/openai_direct_replaces_cursor_openai/OPENAI_API_KEYrows in the cursor-review README anddocs/callers/cursor-review.md.Design notes
Separate job, not another
reviewmatrix entry. The matrix's model list isvalidated against the live Cursor catalog in
preflight, and a delisted id therefails the run loud by design (BE-2627). A direct-API id is not in that catalog at
all, so adding it to
panel_modelswould fail preflight for the right reason andthe wrong cause. Separation also means a failure here can neither cancel nor skip
a Cursor matrix leg.
Turned on only when it can run. The hosted
gatejob resolves whetherOPENAI_API_KEYreached the workflow, as a boolean.preflightfollowsruns_onand must not reference the secret.
preflightturns the cell on only for a plain[A-Za-z0-9._-]id with the key present. Otherwise it warns, leaves the cell offand leaves the Cursor panel unchanged, so a misconfigured opt-in never drops the
OpenAI lane.
Judge integration. The artifact is
findings-direct-adversarial-<model>. Itstill matches
consolidate'sfindings-*download and can never collide with aCursor cell's name.
consolidatelists the job inneeds:(for ordering only; its!cancelled()gate does not read the result).Aggregate panel findingssends thecell's findings to the judge but keeps it out of the Cursor
expected/presentsets,
ok_count/totaland thepanelmetadata auto-approve counts failures from.Identical prompt path. Same
prompt-adversarial.mdwith the same prior-reviewledger splice and new-hunks block, same marker stripped and
re-emitted by
fence-diff.py, a fresh per-prompt nonce minted into a shellvariable rather than a step
env:, and the samereview-output-mcp.pysubmissiontool the Cursor cells use. So one implementation produces the findings schema for
both backends, and a finding difference is attributable to the model or the
backend rather than to prompt drift.
Advisory on purpose.
continue-on-error: trueat the job level, so no step inthe cell can turn the caller's run red while the backend is still being
characterised. Its record is not counted by
Panel integrityor the auto-approvegate.
CLI pinning follows the groom precedent. The pin lives in a real npm manifest
so Dependabot's npm ecosystem can see it and open a bump PR — an inline
npm install -g pkg@1.2.3in arun:step is invisible to every ecosystem, whichis how the groom pin silently rotted. The manifest arrives with the assets
checkout, so it resolves at the same SHA as the prompts and scripts, and the job
rejects a non-exact pin at run time.
Credential posture unchanged.
contents: readonly, no PR checkout, nowrite-scoped token (SECURITY.md). The job runs on GitHub-hosted
ubuntu-latest,never the caller's
runs_onpool: it holdsOPENAI_API_KEY, and onlyCURSOR_API_KEY-only read-only jobs may follow
runs_on. Itsworkflows_refguard is a byte-identical copy of the shared one (incl. the
job.workflow_shacross-check). The only PR-authored content the agent sees is
the same nonce-fenced diff text the Cursor cells read. The key reaches
codex execonly asCODEX_API_KEYin that one step's env, with a freshCODEX_HOMEunderRUNNER_TEMP. It never goes in argv and never on disk: there isno
codex login, whoseauth.jsonthe read-only sandbox could still read. Theagent's shell gets
shell_environment_policy.inherit=core, so it never sees thekey. The public log shows the cell's status and finding count, not the findings
verbatim. Fork PRs get no secret, as before.
Verification
actionlintbash -non every new run blockThe cell contract was exercised end to end against real PRs locally before this
was wired, using the same prompt, fencing and MCP tool: cells reached
status: ok, submitted findings in the judge's schema, and stayed well inside theagent step's cap. That included a control case — a documentation-only diff
correctly produced no findings, which the adversarial prompt explicitly excludes.
Scope / follow-ups
edge-case), one model, one round.max; worth an input once there is a reason to vary it.stop-on-submit.py— the CLI exits on submissionin practice, so this is unneeded today rather than deferred.
point of enabling it on one repo first.
Provenance
workflow-pins,cursor-reviewandgroomunittest suites pass locally at the current head (incl. job-isolation, panel-integrity, guard-parity and inputs-docs-drift)check_workflow_pins.py,check_agents_md.py --root .andcheck-org-repo-literals.shpass;actionlintreports no new message classes vsmainAggregate panel findingssnippet exercised locally: afindings-direct-*cell stays out ofok_count/total/present, and a forgeddirect_apimarker on a Cursor record is strippedCODEX_API_KEYenv auth reaches the API and writes noauth.json;model_reasoning_effort=maxis in its enum/.github/groomentry and asserts the same for/.github/cursor-review. It still fails if the groom block moves; that was checked by mutating the file.cursor-approve'stest_cli_pin_matches_cursor_reviewfails here, as it does onmain:cursor-axis-base.ymlwas not moved with #335's Cursor CLI bump. That is a base defect outside this PR.🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.