diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..68fa358 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,53 @@ +# CLAUDE.md - Kagenti Automation Repository + +## DCO Sign-Off (Mandatory) + +All commits **must** include a `Signed-off-by` trailer (Developer Certificate of Origin). +Always use the `-s` flag when committing: + +```sh +git commit -s -m "feat: Add new feature" +``` + +This adds a line like `Signed-off-by: Your Name ` to the commit message. +PRs without DCO sign-off will fail CI checks. To retroactively sign-off existing commits: + +```sh +git rebase --signoff main +``` + +## Commit Attribution Policy + +When creating git commits, do NOT use `Co-Authored-By` trailers for AI attribution. +Instead, use `Assisted-By` to acknowledge AI assistance without inflating contributor stats: + + Assisted-By: Claude (Anthropic AI) + +Never add `Co-authored-by`, `Made-with`, or similar trailers that GitHub parses as co-authorship. + +A `commit-msg` hook in `scripts/hooks/commit-msg` enforces this automatically. +Install it by configuring the hooks path: + +```sh +git config core.hooksPath scripts/hooks +``` + +## PR Description Attribution + +When generating PR descriptions, summaries, or any PR metadata, use +`Assisted-By: Claude Code` — never `Generated by Claude Code` or similar phrasing. +The work is the developer's; Claude Code assists. This differs from the commit +trailer format (`Assisted-By: Claude (Anthropic AI) `) +because PR body text is human-readable and doesn't need the email for git tooling. +This applies to: + +- PR body text (e.g., the footer line) +- Commit message trailers referenced in PR descriptions +- Any auto-generated changelogs or release notes + +## Scope Discipline + +Only commit files directly related to the PR's stated purpose. Do not bundle +unrelated changes (tooling, configs, hooks, formatting) into a PR unless the +PR is explicitly for that purpose. If a prerequisite change is needed, open a +separate PR for it first. diff --git a/scripts/hooks/commit-msg b/scripts/hooks/commit-msg new file mode 100755 index 0000000..1e80680 --- /dev/null +++ b/scripts/hooks/commit-msg @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +COMMIT_MSG_FILE="$1" +TEMP_FILE=$(mktemp) + +# Check if any AI co-author trailers exist before stripping +HAS_AI_TRAILER=false +if grep -qi -E '^Co-authored-by:.*(Claude|Cursor|anthropic)' "$COMMIT_MSG_FILE"; then + HAS_AI_TRAILER=true +fi + +# Strip Co-authored-by lines for Claude/Cursor and Made-with lines +grep -vi -E '^Co-authored-by:.*(Claude|Cursor|anthropic|cursor)' "$COMMIT_MSG_FILE" \ + | grep -vi '^Made-with:' \ + > "$TEMP_FILE" || true + +# Remove trailing blank lines (awk is portable across macOS/Linux unlike sed labels) +awk '/^[[:space:]]*$/{buf=buf $0 ORS; next} {if(buf) printf "%s",buf; buf=""; print}' "$TEMP_FILE" > "$COMMIT_MSG_FILE" + +# If AI trailers were present, add Assisted-By instead +if [ "$HAS_AI_TRAILER" = true ]; then + # Ensure there's a blank line before the trailer + echo "" >> "$COMMIT_MSG_FILE" + echo "Assisted-By: Claude (Anthropic AI) " >> "$COMMIT_MSG_FILE" +fi + +rm -f "$TEMP_FILE"