feat: add reusable workflow that keeps AGENTS.md accurate in the PR that changed it - #311
Open
FilipMasar wants to merge 8 commits into
Open
feat: add reusable workflow that keeps AGENTS.md accurate in the PR that changed it#311FilipMasar wants to merge 8 commits into
FilipMasar wants to merge 8 commits into
Conversation
Keeps CLAUDE.md up to date inside the PR that made it wrong, instead of opening a separate PR after merge that nobody merges. Refs apify/integrations-team#98 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AGENTS.md now holds the doc and CLAUDE.md is a one-line `@AGENTS.md` pointer at it. This is the right way round: claude-code-action deletes and re-checks-out its SENSITIVE_PATHS from the base branch before the agent starts, and CLAUDE.md is on that list while AGENTS.md is not. So the agent now reads the branch's own version of the file it is judging. The gate hard-fails a repo that isn't laid out this way, printing the fix, instead of skipping with a warning. A skip is indistinguishable from "found nothing to fix", which is how a repo silently stops being maintained. Two things the old layout forced, both now gone: - The base-branch blob comparison in prep. With AGENTS.md never reset, `git status` answers "did the agent change anything" directly. - The per-commit API loop that bailed out when a human had edited the doc in the PR. It existed because the reset hid their edit from the agent, so committing reverted their work. The agent now sees it and edits on top, which is correct. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The gate no longer lists the PR's changed files. Nothing judged that list any more, and the agent's own `gh pr diff` is already in the log, so it was an API call per run for a duplicate. The gate now needs no token and touches no network — every decision it makes reads the checkout on disk. fetch-depth drops to 1. Nothing reads a parent commit: the gate checks the tip's author and the only comparison left is the working tree against HEAD. The post-agent guard also refuses an empty AGENTS.md, not just a missing one. An Edit/Write agent cannot unlink a file but can truncate one, and that would have been committed as a "docs: update" that wipes the repo's doc. Comments that described the previous version of this unmerged file are rewritten as what a future reader needs: what to add back, and when. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A present-but-empty AGENTS.md passed the layout check. The agent is forbidden to create the file, so it would have had no claims to check and would report "nothing to do" on a repo with no doc at all — silence that means the opposite of what it looks like. Same -s predicate as the post-agent guard already uses. Found by lab/test-layout-gate.sh in apify/claude-md-lab, which covers 17 layout shapes locally. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The layout error told the reader to run `printf '@AGENTS.md\n' > CLAUDE.md`. Where CLAUDE.md is a symlink to AGENTS.md the redirect follows the link and truncates the doc to that single line -- so the gate would fail the run, hand back an instruction, and the instruction would destroy the file it was meant to move. apify-core and apify/activepieces are both in exactly that shape, and apify-hubspot-integration and apify-integrations-backend are in the inverse one, with AGENTS.md as the link. The message now states the required end state, gives the command for the common case, and names the two shapes where a shortcut loses work: a symlink must be removed rather than written through, and two real files have diverged and need a human merge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
claude-md-pr.yml -> agents-md-maintenance.yml. The doc has lived in AGENTS.md since the reset problem in claude-code-action made CLAUDE.md unusable as the source of truth, so the old name pointed at the pointer file rather than the document. Free to do now and not later: the workflow is not on main yet, so nothing pins claude-md-pr.yml@main and the rename breaks no callers. The comment claiming a rename would break every stub was written for the state after rollout; it now says so explicitly, and warns off renaming once stubs exist. claude-md-maintenance.yml keeps its name. It is the superseded post-merge workflow that already exists in the target repos, and onboarding deletes it by that exact filename. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
135 comment lines out of 358 was more than this needed. Cuts the verbose ones
and drops two that said nothing the code or the error messages next to them did
not already say:
- the gate's opening restatement of the required layout, which the two
::error:: echoes immediately below it state twice more
- "the agent's reasoning goes to the run summary either way", which the step's
own always() comment three lines up already explains
Everything load-bearing stays, because each of these was written down after
something went wrong: `'' == false` comparing equal on a payload-less event, %an
rather than %cn on API commits, check-ignore consulting the index, tr -d '\r' on
a CRLF checkout, concurrency on the job rather than the workflow, and why the doc
must live in AGENTS.md and not on claude-code-action's SENSITIVE_PATHS. The two
"deliberately nothing here" blocks stay for the same reason: they document code
that is absent on purpose, which is the only kind of decision a comment can
carry at all.
Comment-only. Verified by stripping comment lines from both versions and
diffing: every remaining line is byte-identical, and the agent prompt -- whose
markdown ## headings a naive comment filter would have eaten -- is unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new reusable workflow that keeps
AGENTS.mdaccurate.When a PR makes
AGENTS.mdwrong, a bot commits the fix to that PR's own branch and comments what it changed.Why
We already have
claude-md-maintenance.yml, which runs after merge and opens its own PR. Nobody merges those PRs, so the doc goes stale anyway. Fixing the doc in the PR that broke it means the change lands together with the code.How it works
AGENTS.md. It edits the file only if the PR made something in it wrong — a renamed script, a removed dependency, a new top-level directory.The agent only reads and writes files. Committing and commenting are ordinary steps after it finishes, so when something breaks it's clear which part did it.
How to use it
Nothing happens until a repo opts in — this is
workflow_callonly. Onboarding is two steps.1. The layout. Two regular files in the repo root, neither a symlink.
AGENTS.md— the whole docCLAUDE.md— first line is a pointer toAGENTS.md@AGENTS.md2. The workflow file.
For our own repos, both steps are apify/integrations-team#113 — it has the per-repo migration commands, the stub and the script that distributes it.
Fixes apify/integrations-team#98