[PR #34] [MERGED] feat: reusable AGENTS.md integrity CI workflow (SHA-pinnable) #45

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

📋 Pull Request Information

Original PR: https://github.com/Comfy-Org/github-workflows/pull/34
Author: @mattmillerai
Created: 7/18/2026
Status: ✅ Merged
Merged: 7/19/2026
Merged by: @mattmillerai

Base: main ← Head: matt/be-3368-agents-md-integrity


📝 Commits (2)

  • 9b12546 feat(agents-md-integrity): reusable CI workflow enforcing the AGENTS.md standard
  • c3aa656 feat(agents-md-integrity): fail on a missing root CLAUDE.md shim (require_shim, default true)

📊 Changes

6 files changed (+778 additions, -0 deletions)

View changed files

➕ .github/agents-md-integrity/README.md (+25 -0)
➕ .github/agents-md-integrity/check_agents_md.py (+318 -0)
➕ .github/agents-md-integrity/tests/test_check_agents_md.py (+219 -0)
➕ .github/workflows/agents-md-integrity.yml (+154 -0)
➕ .github/workflows/test-agents-md-integrity.yml (+61 -0)
📝 README.md (+1 -0)

📄 Description

ELI-5

We're standardizing on one thin AGENTS.md per repo as the single source of truth for agent instructions, with CLAUDE.md reduced to a one-line @AGENTS.md shim, no stray .cursorrules, and a hard under-200-line ceiling (per Anthropic guidance). Nothing enforces that today, so files quietly drift back over the limit and shims diverge. This adds a reusable CI workflow any Comfy repo can pin (by commit SHA) to fail its build when its AGENTS.md drifts out of spec.

What this adds

  • .github/workflows/agents-md-integrity.yml — a workflow_call reusable workflow. It runs in the caller's context, so actions/checkout checks out the calling repo and the checks operate on that repo's files. The checker itself is loaded from a pinned ref of this repo (workflows_ref), never the caller's checkout, so a PR can't rewrite the check.
  • .github/agents-md-integrity/check_agents_md.py — the checker (stdlib-only Python), the single source of truth so consumers carry only a thin caller. Emits FAIL:/WARN: lines plus GitHub ::error::/::warning:: annotations and exits non-zero on any hard failure, so it wires in as a required status check.
  • .github/agents-md-integrity/tests/ + .github/workflows/test-agents-md-integrity.yml — a unittest suite (16 cases) plus a self-test workflow (mirroring test-cursor-review-scripts.yml) that also runs a passing-repo and a failing-repo CLI smoke test.
  • A README row following the SHA-pin + v1 conventions.

Checks enforced (all acceptance criteria)

Check Behavior Input (default)
Exists Top-level AGENTS.md present agents_file (AGENTS.md)
Line ceiling > max_lines fails; > warn_lines (but ≤ max_lines) warns max_lines (200), warn_lines (150)
CLAUDE.md shim If CLAUDE.md exists, it must contain @AGENTS.md; a divergent copy fails —
No .cursorrules Legacy root .cursorrules fails forbid_cursorrules (true)
Nested (monorepo) Every nested AGENTS.md needs a sibling @AGENTS.md shim and ≤ max_lines check_nested (true)
CODEOWNERS / DRI AGENTS.md matched by a CODEOWNERS rule; warn-only unless escalated require_codeowners (false → warn)

All inputs are documented in the workflow's header comment.

Usage

name: AGENTS.md Integrity
on:
  pull_request:
  push:
    branches: [main, master]
jobs:
  agents-md:
    permissions:
      contents: read
    uses: Comfy-Org/github-workflows/.github/workflows/agents-md-integrity.yml@<sha>  # v1
    with:
      workflows_ref: <same-sha>   # pin the checker to the same ref as `uses:`

Testing

  • python3 -m unittest discover -s .github/agents-md-integrity/tests → 16 passing.
  • CLI smoke-tested end-to-end: a compliant repo exits 0; a drifted repo (over-ceiling AGENTS.md, divergent CLAUDE.md, .cursorrules) exits 1 with clear per-check output.

Judgment calls / notes

  • require_codeowners is a boolean (default false = warn-only, true = fail), which reads as the ticket's "input-gated, default: warn only".
  • CODEOWNERS matching is a best-effort gitignore-style matcher (leading-/ anchoring, basename-at-any-depth, */**, last-match-wins incl. owner-less unassign). It's a warn-only check by default, so approximate matching is acceptable; exotic patterns may under-match.
  • workflows_ref defaults to main and must be pinned by the caller to match the uses: SHA for full reproducibility — same limitation/pattern as cursor-review.yml. Documented in the header + README.
  • Line counting uses splitlines() (number of text lines), which is wc -l-equivalent for newline-terminated files and one more (correctly) for a file with no trailing newline.
  • Out of scope per the ticket: wiring the thin caller into each consumer repo (a separate per-repo rollout once a v1 tag is cut), semantic/drift checks, and content-quality checks.

Scoped to Comfy-Org/github-workflows; no consumer repos are modified.


🔄 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/34 **Author:** [@mattmillerai](https://github.com/mattmillerai) **Created:** 7/18/2026 **Status:** ✅ Merged **Merged:** 7/19/2026 **Merged by:** [@mattmillerai](https://github.com/mattmillerai) **Base:** `main` ← **Head:** `matt/be-3368-agents-md-integrity` --- ### 📝 Commits (2) - [`9b12546`](https://github.com/Comfy-Org/github-workflows/commit/9b12546a554860b35f44d346aa0634c038c60cd2) feat(agents-md-integrity): reusable CI workflow enforcing the AGENTS.md standard - [`c3aa656`](https://github.com/Comfy-Org/github-workflows/commit/c3aa656edc219336a3dee24f7b0ebb458ea8fb33) feat(agents-md-integrity): fail on a missing root CLAUDE.md shim (require_shim, default true) ### 📊 Changes **6 files changed** (+778 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `.github/agents-md-integrity/README.md` (+25 -0) ➕ `.github/agents-md-integrity/check_agents_md.py` (+318 -0) ➕ `.github/agents-md-integrity/tests/test_check_agents_md.py` (+219 -0) ➕ `.github/workflows/agents-md-integrity.yml` (+154 -0) ➕ `.github/workflows/test-agents-md-integrity.yml` (+61 -0) 📝 `README.md` (+1 -0) </details> ### 📄 Description ## ELI-5 We're standardizing on one thin `AGENTS.md` per repo as the single source of truth for agent instructions, with `CLAUDE.md` reduced to a one-line `@AGENTS.md` shim, no stray `.cursorrules`, and a hard under-200-line ceiling (per Anthropic guidance). Nothing enforces that today, so files quietly drift back over the limit and shims diverge. This adds a **reusable CI workflow** any Comfy repo can pin (by commit SHA) to fail its build when its `AGENTS.md` drifts out of spec. ## What this adds - **`.github/workflows/agents-md-integrity.yml`** — a `workflow_call` reusable workflow. It runs in the **caller's** context, so `actions/checkout` checks out the calling repo and the checks operate on that repo's files. The checker itself is loaded from a pinned ref of *this* repo (`workflows_ref`), never the caller's checkout, so a PR can't rewrite the check. - **`.github/agents-md-integrity/check_agents_md.py`** — the checker (stdlib-only Python), the single source of truth so consumers carry only a thin caller. Emits `FAIL:`/`WARN:` lines plus GitHub `::error::`/`::warning::` annotations and exits non-zero on any hard failure, so it wires in as a required status check. - **`.github/agents-md-integrity/tests/`** + **`.github/workflows/test-agents-md-integrity.yml`** — a `unittest` suite (16 cases) plus a self-test workflow (mirroring `test-cursor-review-scripts.yml`) that also runs a passing-repo and a failing-repo CLI smoke test. - A **README row** following the SHA-pin + `v1` conventions. ## Checks enforced (all acceptance criteria) | Check | Behavior | Input (default) | |---|---|---| | **Exists** | Top-level `AGENTS.md` present | `agents_file` (`AGENTS.md`) | | **Line ceiling** | `> max_lines` fails; `> warn_lines` (but `≤ max_lines`) warns | `max_lines` (200), `warn_lines` (150) | | **CLAUDE.md shim** | If `CLAUDE.md` exists, it must contain `@AGENTS.md`; a divergent copy fails | — | | **No `.cursorrules`** | Legacy root `.cursorrules` fails | `forbid_cursorrules` (true) | | **Nested (monorepo)** | Every nested `AGENTS.md` needs a sibling `@AGENTS.md` shim and `≤ max_lines` | `check_nested` (true) | | **CODEOWNERS / DRI** | `AGENTS.md` matched by a CODEOWNERS rule; warn-only unless escalated | `require_codeowners` (false → warn) | All inputs are documented in the workflow's header comment. ## Usage ```yaml name: AGENTS.md Integrity on: pull_request: push: branches: [main, master] jobs: agents-md: permissions: contents: read uses: Comfy-Org/github-workflows/.github/workflows/agents-md-integrity.yml@<sha> # v1 with: workflows_ref: <same-sha> # pin the checker to the same ref as `uses:` ``` ## Testing - `python3 -m unittest discover -s .github/agents-md-integrity/tests` → 16 passing. - CLI smoke-tested end-to-end: a compliant repo exits 0; a drifted repo (over-ceiling `AGENTS.md`, divergent `CLAUDE.md`, `.cursorrules`) exits 1 with clear per-check output. ## Judgment calls / notes - **`require_codeowners` is a boolean** (default `false` = warn-only, `true` = fail), which reads as the ticket's "input-gated, default: warn only". - **CODEOWNERS matching** is a best-effort gitignore-style matcher (leading-`/` anchoring, basename-at-any-depth, `*`/`**`, last-match-wins incl. owner-less unassign). It's a warn-only check by default, so approximate matching is acceptable; exotic patterns may under-match. - **`workflows_ref` defaults to `main`** and must be pinned by the caller to match the `uses:` SHA for full reproducibility — same limitation/pattern as `cursor-review.yml`. Documented in the header + README. - **Line counting** uses `splitlines()` (number of text lines), which is `wc -l`-equivalent for newline-terminated files and one more (correctly) for a file with no trailing newline. - Out of scope per the ticket: wiring the thin caller into each consumer repo (a separate per-repo rollout once a `v1` tag is cut), semantic/drift checks, and content-quality checks. Scoped to `Comfy-Org/github-workflows`; no consumer repos are modified. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-26 22:35:41 +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#45
No description provided.