fix: require authorship only in PR descriptions
test / test (pull_request) Successful in 9s

Align the shared naming checker with the Human-directed PR-only attribution policy. Preserve visible PR provenance, naming, tracking, current identity exemptions, available base/head commits and nonempty-range validation without inspecting commit messages.

Verify Human and named-Agent callers against legacy, plain, malformed, misplaced and nonfinal commit trailers; retain missing/malformed PR attribution and invalid-range rejection. All 79 offline contract tests, shell syntax and whitespace checks pass.

Ticket: https://agenthub.fritzlab.net/t-d12vqnp63v5d

Policy decision: websites/docs.fritzlab.net#454 (comment)
This commit is contained in:
dfritz committed 2026-10-18 15:43:30 +00:00
1 parent 2f18a5fd5b
commit 31b42b1851
4 files changed
+66 -32

No files matched your search

+52 -6
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Tests for check.sh — exercises valid/invalid branch+title matrices.
# Tests for check.sh — exercises naming, PR attribution, and commit ranges.
set -euo pipefail
SCRIPT="$(cd "$(dirname "$0")/.." && pwd)/check.sh"
@@ -98,6 +98,26 @@ check_chore_contract() {
fi
}
check_author_contract() {
local desc="$1" want_fail="$2" author="$3" body="$4" base="$5" head="$6"
local out rc=0
out=$(cd "${FIXTURES}" && HEAD_BRANCH="chore/contract" \
PR_TITLE="Align PR attribution policy" PR_AUTHOR="$author" \
PR_BODY="$body" GITEA_SERVER_URL="https://code.test" GITEA_TOKEN="test-token" \
GITEA_REPOSITORY="action/check-naming" GITEA_PR_NUMBER=1 PATH="${TEST_BIN}:$PATH" \
BASE_SHA="$base" HEAD_SHA="$head" bash "$SCRIPT" 2>&1) || rc=$?
local got_lines=0
printf '%s\n' "$out" | grep -qE '^FAIL' && got_lines=1 || true
if [ "$rc" -eq "$want_fail" ] && [ "$got_lines" -eq "$want_fail" ]; then
echo "PASS [$desc]"
PASS=$((PASS + 1))
else
echo "FAIL [$desc]: expected exit=$want_fail fail-lines=$want_fail, got exit=$rc fail-lines=$got_lines"
echo " output: $out"
FAIL=$((FAIL + 1))
fi
}
# break-glass
check "dfritz exempt — invalid branch" 0 "totally/wrong-branch" "no prefix" "dfritz"
check "dfritz exempt — mismatch" 0 "dev/bug-abc/thing" "[bug-xyz] Thing" "dfritz"
@@ -233,20 +253,46 @@ else
fi
git -C "${FIXTURES}" commit --allow-empty -q -m "unwatermarked change"
BAD_HEAD=$(git -C "${FIXTURES}" rev-parse HEAD)
check_contract "agenthub 779 commits reject missing watermark" "$BODY" "$GOOD_HEAD" "$BAD_HEAD" "must end with an Authored-By"
PLAIN_HEAD=$(git -C "${FIXTURES}" rev-parse HEAD)
check_contract_pass "Bug-backed commits need no watermark" "$BODY" "$GOOD_HEAD" "$PLAIN_HEAD"
check_chore_contract "chore requires PR attribution" "" "$BASE" "$GOOD_HEAD" "## Attribution must contain"
check_chore_contract "chore commits require watermark" "$(canonical_body bug-unused)" "$GOOD_HEAD" "$BAD_HEAD" "must end with an Authored-By"
git -C "${FIXTURES}" commit --allow-empty -q -m $'misplaced trailer\nAuthored-By: Codex (GPT-5) <noreply@openai.com>'
MISPLACED_HEAD=$(git -C "${FIXTURES}" rev-parse HEAD)
check_contract "commit watermark requires blank separator" "$BODY" "$BAD_HEAD" "$MISPLACED_HEAD" "must end with an Authored-By"
git -C "${FIXTURES}" commit --allow-empty -q -m "trailer not final" -m $'Authored-By: Codex (GPT-5) <noreply@openai.com>\nextra text'
NONFINAL_HEAD=$(git -C "${FIXTURES}" rev-parse HEAD)
check_contract "commit watermark must be final trailer" "$BODY" "$MISPLACED_HEAD" "$NONFINAL_HEAD" "must end with an Authored-By"
git -C "${FIXTURES}" commit --allow-empty -q -m "malformed legacy attribution" -m "Authored-By: incomplete"
MALFORMED_HEAD=$(git -C "${FIXTURES}" rev-parse HEAD)
# Existing Human exemption is unchanged; other Humans and named Agents satisfy
# the same PR-description contract independently of any commit-message footer.
for author in dfritz human-contributor architect; do
for scenario in legacy plain misplaced nonfinal malformed; do
case "$scenario" in
legacy) head="$GOOD_HEAD" ;;
plain) head="$PLAIN_HEAD" ;;
misplaced) head="$MISPLACED_HEAD" ;;
nonfinal) head="$NONFINAL_HEAD" ;;
malformed) head="$MALFORMED_HEAD" ;;
esac
check_author_contract "$author accepts $scenario commit messages" 0 "$author" "$BODY" "$BASE" "$head"
done
done
for author in human-contributor architect; do
check_author_contract "$author requires PR-description attribution" 1 "$author" "" "$BASE" "$PLAIN_HEAD"
check_author_contract "$author rejects a missing PR model" 1 "$author" \
$'## Attribution\n- Authored-By: Codex <noreply@openai.com>' "$BASE" "$PLAIN_HEAD"
check_author_contract "$author rejects a non-noreply PR address" 1 "$author" \
$'## Attribution\n- Authored-By: Codex (GPT-5) <person@example.invalid>' "$BASE" "$PLAIN_HEAD"
done
check_author_contract "dfritz exemption still ignores PR attribution and commit range" 0 dfritz "" not-a-sha not-a-sha
check_contract "missing commit range rejects" "$BODY" "$GOOD_HEAD" "$GOOD_HEAD" "contains no PR commits"
check_contract "invalid SHA rejects before git" "$BODY" "not-a-sha" "$GOOD_HEAD" "lowercase hexadecimal"
check_contract "unavailable commit rejects" "$BODY" 0000000000000000000000000000000000000000 "$GOOD_HEAD" "must name available commits"
echo ""
echo "Results: ${PASS} passed, ${FAIL} failed"