fix: accept pointer-only CLAUDE.md in fm-ensure-agents-md#907
Open
mattwwatson wants to merge 1 commit into
Open
fix: accept pointer-only CLAUDE.md in fm-ensure-agents-md#907mattwwatson wants to merge 1 commit into
mattwwatson wants to merge 1 commit into
Conversation
4 tasks
fm-ensure-agents-md.sh refused a project whose CLAUDE.md is a plain file containing only an @AGENTS.md include, even though that is a deliberate, working compatibility layout, so every run reported a false conflict. Inside the both-real-files branch, detect a pointer-only CLAUDE.md (@AGENTS.md variants after BOM, CRLF, and whitespace stripping) and leave it byte-for-byte untouched; every other divergent-content case still refuses as before.
mattwwatson
force-pushed
the
up/pointer-only-claude-md
branch
from
July 24, 2026 19:14
0ea99e6 to
39f3206
Compare
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.
Intent
Upstream contribution from the mattwwatson/firstmate fork: stop fm-ensure-agents-md.sh reporting a false conflict for projects whose CLAUDE.md is a deliberate pointer-only file containing an @AGENTS.md include. Detect the pointer-only form (variants tolerated after BOM/CRLF/whitespace strip) inside the both-real-files branch and leave the file byte-for-byte untouched; all other divergent-content cases still refuse. The docs/scripts.md table row was hand-merged onto upstream's current list (upstream's new rows kept, only the fm-ensure-agents-md description updated). Suite passes 14/14 locally on the upstream base.
What Changed
bin/fm-ensure-agents-md.shnow recognizes a realCLAUDE.mdwhose only content is an@AGENTS.mdinclude (after tolerating a BOM, CRLF endings, blank lines, surrounding whitespace, and a missing final newline) inside the both-real-files branch: it proceeds againstAGENTS.mdand leaves the pointer file byte-for-byte untouched instead of exiting with a false conflict. Any other divergent content — prose, headings, comments, or includes of other files — still triggers the existing refusal, and the conflict message now says "with their own content" to reflect the narrower case.tests/fm-ensure-agents-md.test.shcovering the pointer-only acceptance, tolerated byte variants, and continued refusal of pointer-plus-extra-content files (suite now 14/14).docs/architecture.mdand thedocs/scripts.mdtable row to describe theCLAUDE.mdcompatibility pointer as either a symlink or a pointer-only@AGENTS.mdinclude, hand-merged onto upstream's current script list.Risk Assessment
✅ Low: A small, well-bounded relaxation of one conflict branch with strict fail-closed fallback, correct bash-3.2-safe parsing, five targeted new tests covering accept/refuse edges, and full conformance with the stated intent; the only finding is a test-assertion fidelity nit.
Testing
Ran the fm-ensure-agents-md suite (14/14 pass, both directly and through the project's fm-test-run.sh runner) and a manual before/after CLI demo proving the end-user behavior: the base commit falsely reports a conflict for a pointer-only @AGENTS.md CLAUDE.md, while the target commit accepts it and leaves the file byte-for-byte untouched (sha256-verified), tolerates BOM/CRLF/whitespace variants, and still refuses divergent-content cases without touching either file; no UI surface is involved, so the CLI transcript is the reviewer-visible evidence.
Evidence: Before/after CLI demo transcript (false conflict on base → accepted untouched on target, variants, refusal)
--- BEFORE (base 6bcb381): exit=1 conflict: both AGENTS.md and CLAUDE.md are real files ... --- AFTER (target 0ea99e6): exit=0 unchanged: AGENTS.md with CLAUDE.md including AGENTS.md ... CLAUDE.md sha256 before == after → byte-for-byte untouched: YES (still a regular file, not a symlink) BOM/CRLF/indented/no-final-newline variant: exit=0, untouched: YES Divergent content (@AGENTS.md + extra prose): exit=1 conflict, both files untouched: YESPipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
tests/fm-ensure-agents-md.test.sh:212- The byte-for-byte-untouched assertion for the pointer-only CLAUDE.md uses[ "$(cat CLAUDE.md)" = "$before_claude" ]; command substitution strips trailing newlines on both sides, so a trailing-newline-only modification of CLAUDE.md would pass undetected. Snapshot the file withcpand compare withcmp/diff(as test_existing_agents_md_with_symlink_gains_self_governance already does for AGENTS.md) to make the assertion truly byte-exact.✅ **Test** - passed
✅ No issues found.
bash tests/fm-ensure-agents-md.test.sh— all 14 tests pass, including the 5 new pointer-only/conflict/variant testsbin/fm-test-run.sh tests/fm-ensure-agents-md.test.sh— project runner: total=1 failed=0, family pure-contract-unitManual before/after demo: base-commit script (git show 6cb...:bin/fm-ensure-agents-md.sh) reports the false conflict (exit 1); target script exits 0 withunchanged:and CLAUDE.md sha256 identical before/afterManual variant check: BOM + CRLF + indented@AGENTS.mdwith no final newline accepted and left byte-for-byte untouchedManual refusal check: CLAUDE.md with include plus extra prose exits 1 withconflict:and both files sha256-verified untouchedReviewed diff ofdocs/scripts.md— only the fm-ensure-agents-md description row changed; upstream rows intactgit status --porcelain— working tree clean after testing✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.