From 1e56295251e25ef270dadf1584c9a6dcf2dcfe0d Mon Sep 17 00:00:00 2001 From: yeasy Date: Thu, 23 Jul 2026 13:13:39 -0700 Subject: [PATCH] fix(ci): close two silent false negatives in Identity Guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .github/workflows/identity-guard.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/identity-guard.yaml b/.github/workflows/identity-guard.yaml index 65e1e1e..da9f071 100644 --- a/.github/workflows/identity-guard.yaml +++ b/.github/workflows/identity-guard.yaml @@ -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