mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #295] [MERGED] fix(groom): validate extra_denied_paths in the gate before agent spend #300
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#300
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/295
Author: @mattmillerai
Created: 9/16/2026
Status: ✅ Merged
Merged: 9/16/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-14745-groom-gate-validate-extra-denied-paths📝 Commits (2)
3c327e6fix(groom): validate extra_denied_paths in the gate before agent spend321afdffix(groom): gate extra_denied_paths validation on should_run; honest fail-closed scope📊 Changes
3 files changed (+84 additions, -6 deletions)
View changed files
📝
.github/groom/tests/test_patch_policy.py(+32 -0)📝
.github/workflows/groom.yml(+50 -4)📝
docs/callers/groom.md(+2 -2)📄 Description
ELI-5
If a caller mistypes one of its
extra_denied_pathspatterns, groom used toonly notice the typo at the very end — after the finder, verifier, and builder
agents had already been paid for. This moves that one check to the front door,
so a broken pattern fails the run instantly and costs $0 in agent spend. Nothing
about what fails changes: same error message, same fail-closed behaviour, just
~10 minutes and a full agent budget earlier.
What changed
extra_denied_paths(a caller's additive builder patch deny-list) was firstcompiled in the
buildjob'sCapture patchstep — the pipe intopatch_policy.pyunderset -euo pipefail— which runs after the finder,verifier, and per-finding builder agents have billed. An uncompilable pattern
therefore burned the full agent budget for every selected finding, every
scheduled run, before aborting.
This adds one step to the cheap, pre-agent
gatejob (afterResolve operational knobs, so$GROOM_ASSETSis populated) that validates the patternsbefore any model work:
main()compilesEXTRA_DENIED_PATHSbefore reading stdin, so feeding it anempty diff exercises only the pattern compile — exit 0 on a good/empty value,
exit 2 with the identical
::error::on a bad one. The gate already checks outthe assets (
Load groom assets), so no second checkout is added, and thecompile logic stays solely in
patch_policy.py— nopython3 -cloop, noduplication (per AGENTS.md single-source-of-truth). A gate failure fails every
downstream job (they all
needs: gate), so no agent job runs.Builder-gated:
extra_denied_pathsis ignored unlessbuilderis true, so anon-builder caller's typo stays harmless exactly as it is today.
The operator-facing message and fail-closed shape are byte-identical to the
build-job failure seen today — just earlier and free.
Testing
python3 -m unittest discover -s .github/groom/tests -p 'test_*.py' -v— 396 pass.GatePreAgentValidationTestpinning the gate's exact empty-stdininvocation: rc 2 on a bad pattern (with
::error::naming it), rc 0 on agood pattern and on an empty/unset value. (The pre-existing
main()tests allfed a non-empty diff; these cover the
printf ''path directly.)patch_policy.py:bad pattern → rc 2 +
::error::on stderr; good / empty / unset → rc 0 withno output. Confirms both that a typo fails closed and that a valid caller is
not spuriously blocked.
check_workflow_pins.py(OK — gate still declaresworkflows_ref, guarded)and
check_agents_md.py(passed; the two warnings are pre-existing andunrelated to this diff).
groom.ymlparses as YAML.Residual
groom.yml. The workflow itself cannot be executedfrom this environment; the substance — the exact
run:command against thereal
patch_policy.py— was verified locally as above, but the step's behaviourinside a real
gatejob (step ordering,$GROOM_ASSETSpopulation by thecheckout) was reasoned from the file, not observed in CI. First real invocation
is the definitive check.
with a sibling "residual" ticket from the same feature PR (#291) and asked that
it be checked for an already-stated gate-validation task before implementing.
That ticket's body was not readable from this environment (no issue-tracker
access here), so the overlap could not be confirmed either way. Open-PR search
found no in-flight PR touching
extra_denied_pathsgate validation (checkedthe
extra_denied_pathsandgroom gatePR queues), so this does not duplicateany open PR; a duplicate ticket remains possible and should be de-duped by a
human with tracker access.
Provenance
python3 -m unittest discover -s .github/groom/tests -p 'test_*.py' -v(396 pass); local run of the gate'srun:command againstpatch_policy.py(rc 2 bad / rc 0 good/empty);check_workflow_pins.py,check_agents_md.py, YAML parse — all green.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.