Read the shared caller contract first.
Checks that your repo follows the org's agent-instructions standard:
- a top-level
AGENTS.mdexists and stays under a hard line ceiling (max_lines, default 200; warns overwarn_lines, default 150) - every agents file, root and nested, stays within character limits — a
paragraph is one line, so a 111-line file can still carry 200k chars. A file
over
warn_chars(default 25000) or with any line overmax_line_chars(default 3000) warns;max_chars(default off) turns total size into a failure. Each finding names the file, its size and its longest lines. - a root
CLAUDE.mdexists and is a thin@AGENTS.mdshim rather than a divergent copy. With the defaultrequire_shim: true, a repo that hasAGENTS.mdand noCLAUDE.mdfails — Claude Code reads onlyCLAUDE.mdand does not fall back, so a missing shim means invisible instructions. Setrequire_shim: falseto only validate aCLAUDE.mdthat is already there. - no legacy
.cursorrules(gated byforbid_cursorrules) - every nested monorepo
AGENTS.mdhas a sibling@AGENTS.mdshim and is under the ceiling (gated bycheck_nested) AGENTS.mdhas a CODEOWNERS DRI (require_codeowners, warn-only by default)
Fails with a non-zero exit and GitHub annotations, so it wires in cleanly as a
required status check. The checker lives in
.github/agents-md-integrity/.
None. No secrets.
.github/workflows/agents-md-integrity.yml:
name: AGENTS.md Integrity
on:
pull_request:
push:
branches: [main] # or [master] — your default branch
jobs:
check:
permissions:
contents: read
uses: Comfy-Org/github-workflows/.github/workflows/agents-md-integrity.yml@<full-commit-sha>
with:
workflows_ref: <same-full-commit-sha>Then ask a maintainer to add your repo to the AGENTS_MD_CALLERS roster secret.
contents: read| Input | Default | Notes |
|---|---|---|
max_lines |
200 |
Hard ceiling. Over this fails. |
warn_lines |
150 |
Warns without failing. |
max_chars |
0 |
Hard ceiling on each agents file's total characters (root and nested). Over this fails. 0 = off, so a pin bump never turns you red; 40000 matches Claude Code's oversized-memory-file floor. |
warn_chars |
25000 |
Total-character target per agents file. Warns without failing. 0 = off. |
max_line_chars |
3000 |
Per-line character ceiling. A longer line (a paragraph kept on one line) warns without failing. 0 = off. |
forbid_cursorrules |
true |
Fail on a legacy .cursorrules. |
check_nested |
true |
Also check nested monorepo AGENTS.md files. |
exclude_paths |
'' |
Newline- or comma-separated path globs carved out of the nested scan (e.g. plugins/**, for a repo that ships agent instructions as distributable payload). Excluded subtrees are never scanned, and every exclusion is reported in the run log. A glob that would match the root agents file or CLAUDE.md, or whose every segment is exactly * or **, is rejected — the root pair is never excludable. That second check is literal, not semantic: a wildcard-equivalent spelling like ?*/?* is not caught by it, and would silently exclude every nested path while leaving check_nested: true green. Name the subtree (plugins/**); do not get clever. |
require_shim |
true |
A root CLAUDE.md shim must exist (and import @AGENTS.md). false still rejects a divergent CLAUDE.md, but tolerates its absence. |
require_codeowners |
false |
Require a CODEOWNERS DRI for AGENTS.md. |
agents_file |
AGENTS.md |
Override the filename. |
workflows_ref |
— (required) | Pin to the SAME full commit SHA as uses:. No default on purpose; the run fails fast (Require a pinned workflows_ref step) if omitted or empty. The checker script loads from this ref. |
Claude Code reads only CLAUDE.md, so the standard keeps content in AGENTS.md
and makes CLAUDE.md a two-line pointer. This repo's own is the reference:
<!-- Agent instructions live in AGENTS.md (the cross-agent standard). This is a Claude Code shim: Claude reads only CLAUDE.md, so the import below pulls AGENTS.md in. Don't add content here — edit AGENTS.md. -->
@AGENTS.mdAdopt on pull_request before adding it as a required check. An existing repo
with a 400-line AGENTS.md fails immediately; you want that visible on a PR, not
blocking the queue.
Character limits are warn-first. Read the warnings after a pin bump; once
every agents file is under warn_chars, set max_chars: 40000 to make the
ceiling stick. The fix for an oversized file is the same whether it is long or
wide: move rationale into docs/agents/ and leave a one-line pointer (a
plain link — an @ import is still expanded at session start). A limit that
is not a whole number fails the run with exit 2 rather than switching off.
check_nested: true on a large monorepo can surface a lot at once. Land the
top-level fix first, then switch it on.