Repository navigation
feat: close the AGENTS.md and CI hardening gaps #125
Description
Motivation
The maintainer keeps a canonical AGENTS.md specification in this gist. A review of this repository against that specification found nine gaps.
This issue keeps the four gaps that carry a real failure mode. It moves two gaps to optional work. It drops three gaps and gives the reason for each.
Verified state
Checked on 2026-09-02 against the live repository.
| Fact | Command | Result |
|---|---|---|
CLAUDE.md is untracked |
git ls-files CLAUDE.md |
prints nothing |
staging has no protection |
gh api repos/textrefs/textrefs.org/branches/staging/protection |
404 |
staging has no ruleset |
gh api repos/textrefs/textrefs.org/rules/branches/staging |
[] |
main carries a legacy layer and a ruleset |
gh api repos/textrefs/textrefs.org/branches/main/protection |
both exist, and they disagree |
| The ruleset requires two checks | gh api repos/textrefs/textrefs.org/rulesets/17092029 |
data and linkcheck |
| Every action floats on a tag | grep -rn "uses:" .github/workflows/ |
13 lines, no commit SHA |
check:links is undocumented |
grep -n "check:links" AGENTS.md |
prints nothing |
Required work
Track A: agent instruction files (target staging)
A1. Track CLAUDE.md. The file holds the single line @AGENTS.md. .gitignore does not list it. Claude Code reads CLAUDE.md and ignores AGENTS.md. A fresh clone therefore loads no agent instructions. Commit the file.
A2. Add the same bridge to textrefs/registry. That repository holds data/AGENTS.md and no CLAUDE.md. Open a matching issue there.
A3. Add a GitHub-workflow section to AGENTS.md. An agent reads AGENTS.md first, and AGENTS.md never names staging, the fork, the squash merge, or the signed commit. Keep the new section to five rules:
- Sign every commit. Ruleset 17092029 sets
required_signatures. - Branch from
stagingfor content, documentation, and copy. - Branch from
mainfor CI, build tooling, and release work. - Open every pull request from the
maehrfork. - Merge with a squash merge only.
Then link CONTRIBUTING.md from the Pointers list. Also add npm run check:links to the Commands list.
Track B: repository settings (target main)
B1. Add a ruleset for staging. Require the data check and the linkcheck check. Add a deletion rule and a non_fast_forward rule.
Both workflows already run on a pull request into staging, so this change adds enforcement only. Dependabot version updates target staging. An unreviewed workflow bump can therefore land on staging today.
B2. Repair ruleset 17092029, then delete the legacy protection on main.
Caution: repair the ruleset before you delete the legacy layer. The legacy layer sets dismiss_stale_reviews: true. The ruleset sets dismiss_stale_reviews_on_push: false. The other order lets a stale approval survive a new push.
- Set
dismiss_stale_reviews_on_push: trueon ruleset 17092029. - Add the CodeQL check to the required checks of the ruleset.
- Delete the legacy protection on
main.
The ruleset covers every other rule that the legacy layer holds. The legacy layer reports a false policy, because it sets required_signatures: false, enforce_admins: false, and required_approving_review_count: 0. GitHub applies the union of both layers, so the ruleset governs today. The legacy layer is dead weight, and it misleads anyone who reads it.
Optional work
C1. Pin the three third-party actions to a commit SHA. The actions are lycheeverse/lychee-action, peter-evans/create-issue-from-file, and softprops/action-gh-release.
Keep the five actions/* entries on a major tag. GitHub owns them, so a commit SHA adds weekly Dependabot noise for a small gain.
C2. Add a dependency-review-action workflow. The action blocks a pull request that adds a vulnerable dependency. Add the check to ruleset 17092029 after the workflow runs one time.
Dropped work, with reasons
Do not enable delete_branch_on_merge.
Caution: keep the flag false while staging has no deletion rule. GitHub deletes the head branch of a merged pull request, and it exempts a protected branch only. The publish pull request uses staging as the head branch. The flag therefore deletes staging at the next release. Revisit the flag after B1 lands.
Do not copy section 1 of the specification into AGENTS.md. The model tier, the parallel limits, and the context ladder describe an agent harness, not this repository. That content belongs in the private global instructions. AGENTS.md holds what only this repository knows.
Do not add the toolchain departure table. The Commands section already names npm, Prettier, Husky, and commitlint. A table that compares this repository to a private specification helps no contributor. npm run check:links is the one real omission, and A3 adds it.
Do not change the permissions in links.yml, and do not change CODEOWNERS. links.yml has one job, so a top-level issues: write scope has the same effect as a job-level scope. Code-owner review stays advisory on a repository with one owner, and that owner holds a pull_request bypass.
Acceptance criteria
-
git ls-files CLAUDE.mdprintsCLAUDE.md. - An issue for the
data/CLAUDE.mdbridge exists ontextrefs/registry. -
AGENTS.mdstates the five workflow rules and documentsnpm run check:links. -
gh api repos/textrefs/textrefs.org/rules/branches/stagingreturns thedatacheck and thelinkcheckcheck. - Ruleset 17092029 sets
dismiss_stale_reviews_on_push: trueand requires the CodeQL check. -
gh api repos/textrefs/textrefs.org/branches/main/protectionreturns 404, and ruleset 17092029 stays active. -
delete_branch_on_mergestays false untilstaginghas adeletionrule.
Optional:
- The three third-party actions name a 40-character commit SHA.
- A
dependency-review-actionworkflow runs on a pull request.
Activity
maehr commentedon Sep 2, 2026
Both tracks are implemented. Track B is live, because a repository setting needs no pull request. Track A waits for review in #141.
Track A
CLAUDE.md, adds the GitHub workflow section, documentsnpm run check:links, and linksCONTRIBUTING.mdfrom Pointers. Thedatacheck and thelinkcheckcheck pass.data/CLAUDE.mdbridge.Track B
B2, step 1. Ruleset 17092029 now sets
dismiss_stale_reviews_on_push: true. Every other rule, the conditions, and the bypass actor are unchanged.B2, step 2. The ruleset now requires the
CodeQLcheck. The name isCodeQL, which is the aggregate check that the default setup posts. Do not requireAnalyze (javascript-typescript), because that name changes with the analysed language.B2, step 3. The legacy protection on
mainis deleted.gh api repos/textrefs/textrefs.org/branches/main/protectionreturns 404, and ruleset 17092029 stays active.B1. Ruleset 22142888 protects
staging. It holds adeletionrule, anon_fast_forwardrule, and thedataandlinkcheckrequired checks.Two choices in B1 depart from the
mainruleset. Both are recorded here for review.always, notpull_request. A required check blocks a direct push to a branch, and no workflow runs on a push tostaging. Thealwaysmode therefore keeps the direct push open for the maintainer. Change the mode topull_requestto close it.strict_required_status_checks_policyisfalse. Atruevalue forces a rebase of every grouped Dependabot pull request wheneverstagingmoves.Finding: CodeQL does not analyse a pull request into
stagingThe default setup analyses a pull request that targets the default branch only. Every analysis on a pull request reference belongs to #4, which is the standing
stagingtomainpull request.A CodeQL alert therefore reaches a human at the release pull request, not at the content pull request. The
mainruleset now blocks that release until the check passes, so nothing ships unanalysed. Adding the check to thestagingruleset would block every merge, because the check never reports there.State of the acceptance criteria
git ls-files CLAUDE.mdprintsCLAUDE.md. (chore(agents): track CLAUDE.md and document the GitHub workflow #141, pending merge)data/CLAUDE.mdbridge exists ontextrefs/registry. (chore: add a CLAUDE.md bridge to AGENTS.md registry#41)AGENTS.mdstates the five workflow rules and documentsnpm run check:links. (chore(agents): track CLAUDE.md and document the GitHub workflow #141, pending merge)gh api repos/textrefs/textrefs.org/rules/branches/stagingreturns thedatacheck and thelinkcheckcheck.dismiss_stale_reviews_on_push: trueand requires the CodeQL check.gh api repos/textrefs/textrefs.org/branches/main/protectionreturns 404, and ruleset 17092029 stays active.delete_branch_on_mergestays false untilstaginghas adeletionrule.Optional work stays open: C1 pins the three third-party actions, and C2 adds the
dependency-review-actionworkflow.Caution:
stagingnow has adeletionrule, sodelete_branch_on_mergeis safe to enable. Enable the flag only after you confirm that the rule protectsstaging.🤖 Generated with Claude Code
https://claude.ai/code/session_01NtQMT2WCNxEAEbEbdhVmuX
chore(agents): track CLAUDE.md and document the GitHub workflow
chore(agents): track CLAUDE.md and document the GitHub workflow (#141)