Skip to content

Commit 8c15551

Browse files
committed
test(hooks): add CLAUDE.md filename-reference regression coverage
Issue #608 reports the commit-msg validator falsely rejected legitimate file references like "update CLAUDE.md routing index". The active three-pattern attribution regex (introduced for #480) actually already allows these — the original substring "CLAUDE" check has been gone for a while — but the test suite never asserted the filename-allow surface explicitly, so the behavior was undocumented and at risk of regression. This commit closes that gap by adding two test groups to both layered test files (PreToolUse commit-message-guard and the git commit-msg hook): 1. Filename references allowed (issue #608) - "docs: update CLAUDE.md routing index" - "fix: correct CLAUDE.local.md gitignore path" - "refactor: move CLAUDE config loader" (narrative inline) - "chore: bump CLAUDE.md version field" (mid-subject) - "docs(claude): clarify routing in CLAUDE.md" (scope + filename) 2. Known reject forms still blocked (issue #608) - "feat: generated with Claude" (prose pattern) - "fix: created by Anthropic team" (prose pattern) - "docs: written using Claude assistance" (prose pattern) The validator library hooks/lib/validate-commit-message.sh is unchanged; no behavior shift, only freshly-asserted regression coverage. global/commit-settings.md gains a one-line clarification stating that filename and narrative references to the project root config are allowed, with a pointer to the three-pattern design comment in the validator library for the precise rules. Closes #608
1 parent 414ed98 commit 8c15551

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

global/commit-settings.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
No AI/Claude attribution in commits, issues, or PRs.
44
Enforced by `settings.json` (`attribution: ""`), the `commit-message-guard` PreToolUse hook (Claude-side feedback loop), and the `commit-msg` git hook installed by `hooks/install-hooks.sh` (terminal-side gate).
55

6+
Filename references to project root config files (`CLAUDE.md`, `CLAUDE.local.md`) and narrative mentions of the config (e.g. "the CLAUDE config loader") are allowed in commit subjects — only attribution patterns (`Co-Authored-By:` trailers, bot emoji adjacent to Claude/Anthropic, "generated/created/authored {with|by|using} {Claude|Anthropic}" prose) are rejected. See the three-pattern design comment in `hooks/lib/validate-commit-message.sh` for the exact rules.
7+
68
All GitHub Issues and Pull Requests must be written in English.

tests/hooks/test-commit-message-guard.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ assert_allow '{"tool_input":{"command":"git commit -m \"feat: add claude integra
8888
assert_allow '{"tool_input":{"command":"git commit -m \"fix: anthropic API fallback\""}}' "casual 'anthropic API' → allow"
8989
assert_allow '{"tool_input":{"command":"git commit -m \"docs: clarify Claude API behavior\""}}' "casual 'Claude API behavior' → allow"
9090

91+
echo ""
92+
echo "[AI attribution — config-filename references allowed (issue #608)]"
93+
# Both enforcement layers (PreToolUse guard and git commit-msg hook) source
94+
# the same library, so the filename-allow surface must be covered here too.
95+
# These cases exercise the -m extraction path of the PreToolUse guard.
96+
assert_allow '{"tool_input":{"command":"git commit -m \"docs: update CLAUDE.md routing index\""}}' "filename ref: CLAUDE.md → allow"
97+
assert_allow '{"tool_input":{"command":"git commit -m \"fix: correct CLAUDE.local.md gitignore path\""}}' "filename ref: CLAUDE.local.md → allow"
98+
assert_allow '{"tool_input":{"command":"git commit -m \"refactor: move CLAUDE config loader\""}}' "narrative ref: 'CLAUDE config' → allow"
99+
100+
echo ""
101+
echo "[AI attribution — known reject forms still blocked (issue #608)]"
102+
# Regression guard: the false-positive surface above must not loosen the
103+
# reject surface. One representative per attribution prose pattern.
104+
assert_deny '{"tool_input":{"command":"git commit -m \"feat: generated with Claude\""}}' "prose: 'generated with Claude' → deny"
105+
assert_deny '{"tool_input":{"command":"git commit -m \"fix: created by Anthropic team\""}}' "prose: 'created by Anthropic' → deny"
106+
assert_deny '{"tool_input":{"command":"git commit -m \"docs: written using Claude assistance\""}}' "prose: 'written using Claude' → deny"
107+
91108
echo ""
92109
echo "[emoji detection]"
93110
EMOJI_PARTY=$(printf '\xf0\x9f\x8e\x89')

tests/hooks/test-commit-msg.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,26 @@ assert_accept "feat: add claude integration" "casual 'claude integration'"
103103
assert_accept "fix: anthropic API fallback" "casual 'anthropic API'"
104104
assert_accept "docs: clarify Claude API behavior" "casual 'Claude API behavior'"
105105

106+
echo ""
107+
echo "[AI attribution — config-filename references allowed (issue #608)]"
108+
# Project root config filenames are legitimate file references, not author
109+
# attribution. The validator must allow them in subjects so commit messages
110+
# that genuinely modify these files can name them precisely.
111+
assert_accept "docs: update CLAUDE.md routing index" "filename ref: CLAUDE.md in subject"
112+
assert_accept "fix: correct CLAUDE.local.md gitignore path" "filename ref: CLAUDE.local.md in subject"
113+
assert_accept "refactor: move CLAUDE config loader" "narrative ref: 'CLAUDE config' inline"
114+
assert_accept "chore: bump CLAUDE.md version field" "filename ref: CLAUDE.md mid-subject"
115+
assert_accept "docs(claude): clarify routing in CLAUDE.md" "scope + filename in subject"
116+
117+
echo ""
118+
echo "[AI attribution — known reject forms still blocked (issue #608)]"
119+
# Regression guard: tightening the false-positive surface above must not
120+
# loosen the deliberate reject surface. Each of these is a representative
121+
# from the three attribution patterns (trailer / emoji / prose).
122+
assert_reject "feat: generated with Claude" "prose: 'generated with Claude'"
123+
assert_reject "fix: created by Anthropic team" "prose: 'created by Anthropic'"
124+
assert_reject "docs: written using Claude assistance" "prose: 'written using Claude'"
125+
106126
echo ""
107127
echo "[emoji detection]"
108128
EMOJI_PARTY=$(printf '\xf0\x9f\x8e\x89')

0 commit comments

Comments
 (0)