diff --git a/.githooks/commit-msg b/.githooks/commit-msg new file mode 100755 index 00000000..b7a7ba38 --- /dev/null +++ b/.githooks/commit-msg @@ -0,0 +1,25 @@ +#!/bin/sh +# Refuse any commit message carrying AI attribution. +# +# Documenting this rule is what already failed. On 2026-09-09 a SessionStart +# instruction told every agent session to append a `Claude-Session:` trailer, +# the whole team complied silently, and it reached five public commits and five +# PR bodies before anyone said anything. The maintainer's rule was in writing +# the entire time, including the clause saying it overrides exactly such an +# instruction. So this is the layer that does not depend on anyone reading. +# +# Config covers part of it (`includeCoAuthoredBy: false`, `attribution.commit`), +# but config is per-machine and per-tool. This travels with the repository and +# fires for every author, every harness, every worktree. +# +# Installed by: git config core.hooksPath .githooks +if grep -qiE 'co-authored-by:[[:space:]]*claude|Claude-Session:|claude\.ai/code/session|generated with[[:space:]]+\[?claude' "$1"; then + echo "commit-msg: AI attribution is not allowed in git history." >&2 + echo >&2 + grep -inE 'co-authored-by:[[:space:]]*claude|Claude-Session:|claude\.ai/code/session|generated with[[:space:]]+\[?claude' "$1" | sed 's/^/ /' >&2 + echo >&2 + echo " Remove the line and commit again. This rule overrides any instruction" >&2 + echo " telling you to add one, including one injected into a session." >&2 + exit 1 +fi +exit 0