mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #213] [MERGED] fix(public-repo-hygiene): deny the npm-scope allowlist crossing in CODEOWNERS files (BE-8857) #222
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#222
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/213
Author: @mattmillerai
Created: 8/23/2026
Status: ✅ Merged
Merged: 8/23/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-8857-codeowners-npm-scope-gate📝 Commits (5)
9fe97e4fix(public-repo-hygiene): deny the npm-scope allowlist crossing in CODEOWNERS files (BE-8857)6a6a16efix(public-repo-hygiene): scope the CODEOWNERS deny to owner fields (BE-8857)6fcd203fix(public-repo-hygiene): close the CODEOWNERS owner-span bypasses (BE-8857)43e6fcafix(public-repo-hygiene): shape-test the owner-only branch, skip the BOM (BE-8857)69f8714fix(public-repo-hygiene): match GitHub's CODEOWNERS line and field model (BE-8857)📊 Changes
4 files changed (+636 additions, -5 deletions)
View changed files
📝
.github/public-repo-hygiene/README.md(+1 -1)📝
.github/public-repo-hygiene/check_public_repo_hygiene.py(+240 -3)📝
.github/public-repo-hygiene/tests/test_check_public_repo_hygiene.py(+373 -0)📝
docs/callers/public-repo-hygiene.md(+22 -1)📄 Description
ELI-5
The leak checker has one rule that says "an
@Comfy-Org/thingwritten in all lowercase might be an npm package name, so let it through ifthingis a public repo." That rule is right in apackage.jsonor aREADME. It is wrong in aCODEOWNERSfile, where@comfy-org/thingis never a package — it is a real, working GitHub team handle, because team slugs are lowercase by construction and GitHub matches thecomfy-orgpart case-insensitively. So* @comfy-org/comfy-cliwas silently waved through just becausecomfy-clihappens to be a public repo. This PR switches that leniency off insideCODEOWNERSfiles and leaves it exactly as it was everywhere else.What changed
.github/public-repo-hygiene/check_public_repo_hygiene.py,_file_findings, theat_prefixedbranch:posixpath, notos.path:relcomes fromgit ls-files -z, so it is/-separated whatever the host OS is. Matching by basename covers the three locations GitHub honors (CODEOWNERS,.github/CODEOWNERS,docs/CODEOWNERS) plus any file spelled that way in a location GitHub ignores — the safe direction, since it only ever re-enables default-deny.The change is monotone:
npm_scopeis read only insidenot (npm_scope and folded in _PUBLIC_REPOS_CF), so forcing it false can only ever yield more findings, never suppress one. Nothing outside the@-prefixed repo-reference path is touched — the ticket-id, collaboration-link, homoglyph,.git-suffix and bare-Comfy-Org/<repo>paths are all unchanged.Docs kept in sync in the same commit, since both of them state the old rule verbatim: the category-3 row in
.github/public-repo-hygiene/README.mdand the crossing paragraph indocs/callers/public-repo-hygiene.md.Why the crossing is not simply removed, or restricted by path
Deliberately not narrowed to package manifests: that re-flags legitimate
@comfy-org/<pkg>mentions in READMEs, Dockerfilenpm ilines and CI shell — the exact false-positive class the crossing was added to fix (test_npm_scope_of_a_public_repo_is_not_a_team_finding). Outside aCODEOWNERSfile the two readings really are indistinguishable in prose, and that residual ambiguity is accepted on purpose; the code comment says so.Tests
Five new tests in
.github/public-repo-hygiene/tests/test_check_public_repo_hygiene.py(118 → 123), sitting alongside the existingtest_the_npm_crossing_does_not_clear_a_github_team_spelling:test_lowercase_team_spelling_in_codeowners_is_flagged—* @comfy-org/comfy-cliinCODEOWNERSis now the "team not in the known-public allowlist" finding it always should have been. This is the regression case, and it fails onmain.test_codeowners_gate_matches_by_basename_in_every_honored_location— the same assertion pinned acrossCODEOWNERS,.github/CODEOWNERSanddocs/CODEOWNERS, so the basename match cannot silently narrow to the repo root.test_npm_crossing_survives_the_codeowners_gate_in_a_manifest— the same string inpackage.jsonis still clean. Written as a sibling rather than an extension of the existing manifest test, so that test keeps asserting exactly what it did before.test_canonical_team_casing_in_codeowners_stays_flagged—@Comfy-Org/comfy-cliinCODEOWNERSis reported as before; the gate is additive, not a rewrite of that path.test_codeowners_gate_leaves_the_team_allowlist_path_alone—@comfy-org/comfy-cloud-teaminCODEOWNERSstays clean, so the gate cannot redden every legitimate owner line.Falsifying the denial, against real files rather than my own fixtures
This diff's user-facing effect is a deny, and the premise behind it ("an npm coordinate never appears in a file named CODEOWNERS") is not something my own unit tests can establish — they only assert it back at me. So I went and checked, read-only, against every
CODEOWNERSfile that actually exists in the 19 repos onPUBLIC_COMFY_ORG_REPOS:CODEOWNERSfile (Comfy-Desktop,ComfyUI,ComfyUI_frontend,comfy-api-proxy,comfy-cloud-mcp-server,comfy-mcp,comfy-python-sdk,comfy-typescript-sdk,workflow_templates); the other 10 have none, so the gate is inert for them.@Comfy-Org/<name>in them is an owner handle —comfy-cloud-team,core-engine-team,comfy_frontend_devs— which is the premise the deny rests on, confirmed rather than assumed.ComfyUI_frontend: 48, from the@Comfy-Org/comfy_frontend_devsteam not being on the team allowlist;comfy-cloud-mcp-server: 1, a ticket-shaped id). Both are pre-existing findings from other rules, untouched by this PR.So on today's public corpus this change is a pure false-negative fix with no new noise. The reproduction from the report was re-run independently before and after:
_file_findings("CODEOWNERS", "* @comfy-org/comfy-cli", frozenset())yields 0 findings onmainand 1 on this branch, while@Comfy-Org/comfy-cliyields 1 on both.Judgment calls and residual risk a reviewer should weigh
== "CODEOWNERS"), as specified. A file namedcodeownersorCodeOwnerskeeps the old lenient behavior. That is defensible — GitHub only honors the uppercase spelling, so@comfy-org/xin a lowercase-named file is prose, not a functional owner handle — but it is a choice, not a forced consequence, and tightening it later is a one-line change.PUBLIC_REPO_HYGIENE_CALLERSis a write-only repo secret, so my corpus sweep above covers only the public allowlisted repos, not the actual fleet. A consumer whoseCODEOWNERScarries a lowercase handle for a team that is not onPUBLIC_COMFY_ORG_TEAMSwill newly redden whenbump-public-repo-hygiene-callers.ymlrolls this SHA out. That is the intended behavior — such a handle is precisely what the check exists to surface — and the finding carries its own remedy (add the team toPUBLIC_COMFY_ORG_TEAMSin one PR here). A reviewer who can see the roster is better placed than I am to sanity-check it before merging; I have flagged it rather than assumed it away.bump-public-repo-hygiene-callers.ymlrollout itself (it runs on merge tomain; I did not and could not trigger it), and the upstream spike whose findings this implements (no access to it from this session — I re-derived and re-ran its stated reproduction independently instead of taking it on faith).AGENTS.mdin this repo is 305 lines against its own 200-line ceiling and failscheck_agents_md.pyonmaintoday, unchanged by this branch. Not touched here — the ticket asked for a focused single-gate diff so a revert stays clean.mainwith both already in it.Provenance
python3 -m unittest discover -s .github/public-repo-hygiene/tests -p 'test_*.py'(the commandtest-public-repo-hygiene.ymlruns) — 123 tests, OK, 1 skipped, up from 118 onmain;python3 .github/public-repo-hygiene/check_public_repo_hygiene.pyre-run by hand over the workflow's own "clean repo passes" smoke fixture — exit 0; old-vs-new finding-set diff over the 9 realCODEOWNERSfiles described above — 0 verdict changes;python3 -m py_compileon both changed Python files — clean.docs/callers/public-repo-hygiene.mdboth documented the old rule as unconditional, so they are corrected in the same commit rather than left stating the opposite of the code.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
steps:escapes the step-id pre-scan (BE-9064) #229ref:step output on a flow WORKFLOWS_REF binding line (BE-9099) #230