[PR #180] [MERGED] feat(area-label): reusable agentic PR area-label classifier #187

Closed
opened 2026-10-26 22:37:09 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Comfy-Org/github-workflows/pull/180
Author: @luke-mino-altherr
Created: 8/18/2026
Status: ✅ Merged
Merged: 8/19/2026
Merged by: @luke-mino-altherr

Base: main ← Head: luke/area-label-reusable


📝 Commits (4)

  • d862079 feat(area-label): reusable agentic PR area-label classifier
  • a7d032d ci(area-label): fix shellcheck source dirs and adopt the recognized ref guard
  • 31a61a3 ci(area-label): address CodeRabbit review — ancestry guard, fail-soft, validation
  • d3204cd docs(area-label): list AREA_LABEL_CALLERS in the README roster enumeration

📊 Changes

11 files changed (+1074 additions, -2 deletions)

View changed files

➕ .github/workflows/bump-area-label-callers.yml (+105 -0)
➕ .github/workflows/pr-area-label.yml (+298 -0)
➕ .github/workflows/test-area-label.yml (+48 -0)
📝 README.md (+4 -2)
📝 docs/callers/README.md (+2 -0)
➕ docs/callers/pr-area-label.md (+127 -0)
➕ scripts/area-label/README.md (+48 -0)
➕ scripts/area-label/classify-and-apply.sh (+154 -0)
➕ scripts/area-label/lib.sh (+135 -0)
➕ scripts/area-label/sync-labels.sh (+51 -0)
➕ scripts/area-label/tests/test_lib.sh (+102 -0)

📄 Description

Ports the agentic area-label classifier from Comfy-Org/comfy-infra (#815) into a shared reusable workflow, so cloud, comfy-infra, and any other repo share one hardened implementation and keep only a thin caller + their own taxonomy. This is the risk-grader pattern Matt asked for on comfy-infra#815 (move the logic here; each repo defines its own area labels).

What this adds

  • .github/workflows/pr-area-label.yml — reusable (workflow_call), two jobs under one taxonomy:
    • sync-labels — gh label create --force reconcile of the consumer's area:* labels to its YAML. No secret.
    • label-pr — classifies each PR into exactly one area:* label.
  • scripts/area-label/ — the logic, loaded from the pinned workflows_ref:
    • lib.sh — pure, network-free core (taxonomy parse, the two validation gates, request build, reply parse).
    • sync-labels.sh / classify-and-apply.sh — the two jobs' bodies.
    • tests/test_lib.sh — hermetic suite, 25 cases, no network.
  • .github/workflows/test-area-label.yml — shellcheck + suite on change.
  • .github/workflows/bump-area-label-callers.yml — pin-bump fleet (AREA_LABEL_CALLERS roster).
  • docs/callers/pr-area-label.md + rows in README.md and docs/callers/README.md.

Reusability

Nothing repo-specific is baked in. Per-repo framing (the domain-vs-path judgement calls) lives in the consumer taxonomy's optional top-level repo_context: key, injected into the system prompt; the invariant scaffolding (classify-by-purpose, trust the conventional-commit scope, treat <pr_data> as untrusted) is fixed in build_system. Consumers keep .github/area-labels.yml; there is no generic default taxonomy (area labels are inherently per-repo — a missing taxonomy skips cleanly with a warning).

Security model (preserved from the comfy-infra port, CodeRabbit-hardened)

  • Model gets no tools and no token; PR title/body/paths/labels passed as data in <pr_data> tags, diff excluded.
  • Reply enum-constrained by JSON schema to the taxonomy's own area:* names.
  • Taxonomy read from the PR's base ref, never its head, and validated (unique area:[a-z0-9-]+ names; every label resolves to a non-blank routing guide) before it drives a write.
  • Label applied with targeted area:* add/remove ops, never a full-set PUT — concurrent non-area edits survive; add-before-cleanup; delete tolerates only HTTP 404.
  • Fork/Dependabot PRs skipped by construction; everything fails soft rather than reding the check.
  • workflows_ref validated to a full 40-hex lowercase SHA before any checkout.

Testing

  • bash scripts/area-label/tests/test_lib.sh → 25 passed, 0 failed (local).
  • shellcheck -x clean across all four scripts.
  • All three workflow YAMLs parse.

Rollout

Two-step per the caller contract: land this, then a maintainer adds each repo to AREA_LABEL_CALLERS and workflow_dispatches the bump fleet once. The comfy-infra caller (replacing the repo-local workflow in #815) is the first consumer and will be opened against the merged SHA.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Comfy-Org/github-workflows/pull/180 **Author:** [@luke-mino-altherr](https://github.com/luke-mino-altherr) **Created:** 8/18/2026 **Status:** ✅ Merged **Merged:** 8/19/2026 **Merged by:** [@luke-mino-altherr](https://github.com/luke-mino-altherr) **Base:** `main` ← **Head:** `luke/area-label-reusable` --- ### 📝 Commits (4) - [`d862079`](https://github.com/Comfy-Org/github-workflows/commit/d8620795729a1a893f4e4352dd9490cbefd613b5) feat(area-label): reusable agentic PR area-label classifier - [`a7d032d`](https://github.com/Comfy-Org/github-workflows/commit/a7d032d28fbea55f17b51dac1d3a5508bc75a634) ci(area-label): fix shellcheck source dirs and adopt the recognized ref guard - [`31a61a3`](https://github.com/Comfy-Org/github-workflows/commit/31a61a3268913d62547540b24d7179f637bac203) ci(area-label): address CodeRabbit review — ancestry guard, fail-soft, validation - [`d3204cd`](https://github.com/Comfy-Org/github-workflows/commit/d3204cd346e5a100f3053c00067fa6528b38f879) docs(area-label): list AREA_LABEL_CALLERS in the README roster enumeration ### 📊 Changes **11 files changed** (+1074 additions, -2 deletions) <details> <summary>View changed files</summary> ➕ `.github/workflows/bump-area-label-callers.yml` (+105 -0) ➕ `.github/workflows/pr-area-label.yml` (+298 -0) ➕ `.github/workflows/test-area-label.yml` (+48 -0) 📝 `README.md` (+4 -2) 📝 `docs/callers/README.md` (+2 -0) ➕ `docs/callers/pr-area-label.md` (+127 -0) ➕ `scripts/area-label/README.md` (+48 -0) ➕ `scripts/area-label/classify-and-apply.sh` (+154 -0) ➕ `scripts/area-label/lib.sh` (+135 -0) ➕ `scripts/area-label/sync-labels.sh` (+51 -0) ➕ `scripts/area-label/tests/test_lib.sh` (+102 -0) </details> ### 📄 Description Ports the agentic area-label classifier from `Comfy-Org/comfy-infra` (#815) into a **shared reusable workflow**, so cloud, comfy-infra, and any other repo share one hardened implementation and keep only a thin caller + their own taxonomy. This is the risk-grader pattern Matt asked for on comfy-infra#815 (move the logic here; each repo defines its own area labels). ## What this adds - **`.github/workflows/pr-area-label.yml`** — reusable (`workflow_call`), two jobs under one taxonomy: - `sync-labels` — `gh label create --force` reconcile of the consumer's `area:*` labels to its YAML. No secret. - `label-pr` — classifies each PR into exactly one `area:*` label. - **`scripts/area-label/`** — the logic, loaded from the pinned `workflows_ref`: - `lib.sh` — pure, network-free core (taxonomy parse, the two validation gates, request build, reply parse). - `sync-labels.sh` / `classify-and-apply.sh` — the two jobs' bodies. - `tests/test_lib.sh` — hermetic suite, **25 cases, no network**. - **`.github/workflows/test-area-label.yml`** — shellcheck + suite on change. - **`.github/workflows/bump-area-label-callers.yml`** — pin-bump fleet (`AREA_LABEL_CALLERS` roster). - **`docs/callers/pr-area-label.md`** + rows in `README.md` and `docs/callers/README.md`. ## Reusability Nothing repo-specific is baked in. Per-repo framing (the domain-vs-path judgement calls) lives in the consumer taxonomy's optional top-level **`repo_context:`** key, injected into the system prompt; the invariant scaffolding (classify-by-purpose, trust the conventional-commit scope, treat `<pr_data>` as untrusted) is fixed in `build_system`. Consumers keep `.github/area-labels.yml`; there is **no generic default taxonomy** (area labels are inherently per-repo — a missing taxonomy skips cleanly with a warning). ## Security model (preserved from the comfy-infra port, CodeRabbit-hardened) - Model gets **no tools and no token**; PR title/body/paths/labels passed as data in `<pr_data>` tags, diff excluded. - Reply **enum-constrained by JSON schema** to the taxonomy's own `area:*` names. - Taxonomy read from the PR's **base ref**, never its head, and **validated** (unique `area:[a-z0-9-]+` names; every label resolves to a non-blank routing guide) before it drives a write. - Label applied with **targeted `area:*` add/remove ops**, never a full-set PUT — concurrent non-area edits survive; add-before-cleanup; delete tolerates only HTTP 404. - Fork/Dependabot PRs skipped by construction; everything **fails soft** rather than reding the check. - `workflows_ref` validated to a full 40-hex lowercase SHA before any checkout. ## Testing - `bash scripts/area-label/tests/test_lib.sh` → 25 passed, 0 failed (local). - `shellcheck -x` clean across all four scripts. - All three workflow YAMLs parse. ## Rollout Two-step per the caller contract: land this, then a maintainer adds each repo to `AREA_LABEL_CALLERS` and `workflow_dispatch`es the bump fleet once. The comfy-infra caller (replacing the repo-local workflow in #815) is the first consumer and will be opened against the merged SHA. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-26 22:37:09 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Comfy-Org/github-workflows#187
No description provided.