fix(ci): close two silent false negatives in Identity Guard

An audit found the guard could miss commits it exists to catch.

1. SIGPIPE. Three inner checks used `printf ... | grep -q` under
   `set -euo pipefail`. When grep -q matches early it exits, printf dies of
   SIGPIPE, pipefail turns the pipeline non-zero, the `if` goes false, and the
   offending commit is silently not reported — the guard then prints its
   success line. This file already documents the hazard in a comment and had
   fixed it for the two outer pre-filters; the three inner ones were left as
   pipes. Now here-strings, like the rest.

   Demonstrated on a synthetic revert-style commit (an AI trailer quoted near
   the top, then a 200KB body): the pipe form MISSES it, the here-string form
   detects it. A trailer in the conventional last position happens to survive
   the pipe form, because grep must read to the end before matching — which is
   why this never showed up in practice.

2. `chatgpt` was in BAD_NAME and BAD_ANY but not BAD_TRAILER, so a
   Co-authored-by naming ChatGPT with an email outside anthropic.com/openai.com
   was not caught. Confirmed by test, then added.

Verified before pushing this time: the amended script flags an AI-authored
commit, a large-body early trailer, and a ChatGPT trailer, and scans
claude_guide's full 345-commit history with zero false positives — that repo
has 46 commits with Claude or Anthropic in the subject, none of which are
identity or trailer hits.
This commit is contained in:
yeasy
2026-07-23 13:13:39 -07:00
parent 52f6c73478
commit 1e56295251
+4 -4
View File
@@ -81,7 +81,7 @@ jobs:
# 的书所以只检查身份字段与 Co-authored-by 尾注绝不扫描自由文本
BAD_EMAIL='@([a-z0-9.-]+\.)?(anthropic|openai)\.com$'
BAD_NAME='^(claude([ ._-]?code)?|codex|chatgpt|copilot|anthropic|openai)(\[bot\])?$'
BAD_TRAILER='^[[:space:]]*co-authored-by:.*(claude|anthropic|codex|copilot|openai)'
BAD_TRAILER='^[[:space:]]*co-authored-by:.*(claude|anthropic|codex|copilot|openai|chatgpt)'
# 粗筛BAD_EMAIL BAD_NAME 命中的行必然含下列词之一
# 因此它是二者的超集用来跳过绝大多数干净提交不会漏判
BAD_ANY='(claude|anthropic|codex|chatgpt|copilot|openai)'
@@ -101,8 +101,8 @@ jobs:
if [ "$role" = author ]; then name="$an"; mail="$ae"; else name="$cn"; mail="$ce"; fi
lname="$(printf '%s' "$name" | tr '[:upper:]' '[:lower:]')"
lmail="$(printf '%s' "$mail" | tr '[:upper:]' '[:lower:]')"
if printf '%s' "$lmail" | grep -qE "$BAD_EMAIL" \
|| printf '%s' "$lname" | grep -qE "$BAD_NAME"; then
if grep -qE "$BAD_EMAIL" <<<"$lmail" \
|| grep -qE "$BAD_NAME" <<<"$lname"; then
echo "::error::${sha} ${role} identity is an AI assistant: ${name} <${mail}>"
failed=1
fi
@@ -118,7 +118,7 @@ jobs:
while read -r sha; do
[ -n "$sha" ] || continue
body="$(git log -1 --format='%B' "$sha")"
if printf '%s' "$body" | grep -qiE "$BAD_TRAILER"; then
if grep -qiE "$BAD_TRAILER" <<<"$body"; then
echo "::error::${sha} has a Co-authored-by trailer referencing an AI assistant"
printf '%s' "$body" | grep -iE "$BAD_TRAILER" | sed 's/^/ /'
failed=1