From 3f1994698edda416b6966e12b96427535640c645 Mon Sep 17 00:00:00 2001 From: Tri Lam Date: Wed, 13 May 2026 05:18:29 -0700 Subject: [PATCH 1/2] Apply Wave-1 follow-ups: tests, automation, doc-truth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four small follow-ups on the contribution-safeguards bundle. 1. dco-check_test.sh sets `commit.gpgsign=false` and `tag.gpgsign=false` in the sandbox repo before any commit. Without this, contributors who have run scripts/setup-signing.sh (and therefore have `commit.gpgsign=true` in their ~/.gitconfig) would see the test commits attempt to sign with a key not present in the temp repo's context — a false negative in our own test suite. 2. scripts/apply-branch-protection.sh applies the rules in .github/branch-protection.yml directly via `gh api`. Idempotent; safe to re-run. Replaces the manual-UI-clicks-then-pray pattern with one command. Drift between the intent doc and live settings becomes a re-run away from being fixed. 3. AGENTS.md now documents the kernel coding-assistants.rst trailer format (`Assisted-by: : []`) as preferred, with the simple form still accepted. Aligns the doc with the format every commit on this branch already uses. 4. The "Aim for under 500 lines" guidance is removed from CONTRIBUTING.md and the matching bullet in AGENTS.md. We explicitly chose not to enforce a PR size cap; the soft guidance was misleading. Replaced with "split when the diff outgrows the concern, not when it crosses an arbitrary line count". Refs RFC-0003. Assisted-by: Anthropic:claude-opus-4-7 [Claude Code] Signed-off-by: Tri Lam --- .github/scripts/dco-check_test.sh | 6 +++ AGENTS.md | 16 ++++++-- CONTRIBUTING.md | 5 +-- scripts/apply-branch-protection.sh | 66 ++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 6 deletions(-) create mode 100755 scripts/apply-branch-protection.sh diff --git a/.github/scripts/dco-check_test.sh b/.github/scripts/dco-check_test.sh index 4d9336ea..357d4cfa 100755 --- a/.github/scripts/dco-check_test.sh +++ b/.github/scripts/dco-check_test.sh @@ -12,6 +12,12 @@ cd "$tmp" git init -q -b main git config user.email "tester@example.com" git config user.name "Tester" +# Disable commit signing locally: a contributor who ran scripts/setup-signing.sh +# has commit.gpgsign=true globally, which would make these test commits try to +# sign with a key that isn't available in the sandbox repo. The test is about +# DCO trailers, not about signing. +git config commit.gpgsign false +git config tag.gpgsign false git commit --allow-empty -q -m "Init" expect_pass() { diff --git a/AGENTS.md b/AGENTS.md index 5d587da3..cb368d6f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,20 +11,30 @@ This document is for both humans and AI coding assistants. It describes how AI t ## Disclosing AI assistance -When a commit was authored with significant AI help, add a trailer to the commit message: +When a commit was authored with significant AI help, add a trailer to the commit message. The preferred format names the agent, model, and tool: ``` -Assisted-by: +Assisted-by: : [] ``` Examples: +``` +Assisted-by: Anthropic:claude-opus-4-7 [Claude Code] +Assisted-by: OpenAI:gpt-5 [Codex CLI] +Assisted-by: Google:gemini-2.5-pro [Gemini CLI] +``` + +The simpler `Assisted-by: ` form is also accepted: + ``` Assisted-by: Claude Code Assisted-by: GitHub Copilot Assisted-by: Cursor ``` +The richer format aligns with the Linux kernel's `coding-assistants.rst` convention and gives reviewers more context for the same one-line cost. + Do **not** use `Co-Authored-By:` for AI tools. That trailer is reserved for human collaborators and breaks DCO / contributor-license tooling that expects a real identity behind every co-author. CI rejects PRs whose commits include a `Co-Authored-By:` line naming an AI tool (Claude, Copilot, Cursor, ChatGPT, Gemini, etc.); fix the trailer with `git commit --amend` or rewrite history with `git rebase -i` before pushing. > **Heads-up for Claude Code users:** Claude Code defaults to adding a `Co-Authored-By: Claude` trailer. Disable it for this repo, or strip it before committing. The `Assisted-by:` trailer is the equivalent disclosure that *passes* the policy. @@ -42,7 +52,7 @@ Do **not** use `Co-Authored-By:` for AI tools. That trailer is reserved for huma AI tools are good at producing more code than is needed. When using one: -- Keep PRs under 500 lines, per [`CONTRIBUTING.md`](CONTRIBUTING.md). +- Keep PRs focused on one concern, per [`CONTRIBUTING.md`](CONTRIBUTING.md). Split when the diff outgrows the concern. - Don't refactor unrelated code in the same PR. - Don't add speculative abstractions, unused helpers, or "future-proofing" code. - Don't add comments that restate the code; STYLE.md requires comments only where the *why* is non-obvious. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 686471f1..f7e280a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,13 +32,12 @@ make ci # what CI runs: license-check + vet + lint + test + build ## Pull requests -- **Small is better.** Aim for under 500 lines changed. Split larger work into multiple PRs. -- **One concern per PR.** Don't mix refactors with feature work. +- **One concern per PR.** Don't mix refactors with feature work. Smaller PRs are easier to review — split when the diff outgrows the concern, not when it crosses an arbitrary line count. - **Tests required** for new functionality. Bug fixes should include a regression test. - **Atomic commits.** Each commit must build and pass tests on its own. - **Sign off your commits**: `git commit -s`. We require [DCO](https://developercertificate.org/). - **Sign your commits cryptographically.** `main` requires signed commits. The fastest path is SSH signing — run `scripts/setup-signing.sh` once and it configures `gpg.format=ssh`, `user.signingkey`, `commit.gpgsign=true`, `tag.gpgsign=true`. Register the same SSH key as a "Signing Key" in your GitHub account (Settings → SSH and GPG keys). Sigstore `gitsign` (keyless OIDC) is an accepted alternative; see [sigstore.dev/gitsign](https://docs.sigstore.dev/cosign/signing/git_support/). -- **AI-assisted commits**: add `Assisted-by: ` trailer to your commit message. Do not use `Co-Authored-By:` for AI tools. +- **AI-assisted commits**: add an `Assisted-by:` trailer disclosing the agent, model, and tool, e.g. `Assisted-by: Anthropic:claude-opus-4-7 [Claude Code]`. The simpler form `Assisted-by: ` is accepted but the richer format is preferred. Do not use `Co-Authored-By:` for AI tools — CI rejects it (see [`AGENTS.md`](AGENTS.md)). ## Commit message format diff --git a/scripts/apply-branch-protection.sh b/scripts/apply-branch-protection.sh new file mode 100755 index 00000000..d08b5310 --- /dev/null +++ b/scripts/apply-branch-protection.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# apply-branch-protection.sh — apply the rules described in +# .github/branch-protection.yml to the `main` branch via gh api. +# +# Idempotent: safe to re-run; every key is reapplied on every invocation. +# Requires `gh auth login` with `repo` scope. Run from a repo clone (the +# script uses the origin remote to discover :owner/:repo). +# +# To change a setting: +# 1. Edit .github/branch-protection.yml so intent matches the new state. +# 2. Edit this script's JSON payload to match the new state. +# 3. Re-run the script. +# +# Future improvement: parse the YAML directly so the payload is generated +# from the intent doc, eliminating the chance of drift between the two. +# Today the script is hand-mirrored from the YAML — drift is a P1 bug. +set -euo pipefail + +if ! command -v gh >/dev/null 2>&1; then + echo "error: 'gh' CLI is required (https://cli.github.com/)" >&2 + exit 1 +fi + +repo=$(gh repo view --json nameWithOwner --jq '.nameWithOwner' 2>/dev/null || true) +if [ -z "$repo" ]; then + echo "error: could not determine repo (run from a clone with origin set)" >&2 + exit 1 +fi + +echo "Applying branch protection to $repo:main …" + +gh api \ + -X PUT "repos/${repo}/branches/main/protection" \ + -H "Accept: application/vnd.github+json" \ + --input - <<'JSON' +{ + "required_status_checks": { + "strict": true, + "contexts": [ + "verify", + "build (linux-amd64)", + "build (linux-arm64)", + "Analyze (go)", + "govulncheck", + "release-notes block edited", + "no AI co-author trailer", + "dco sign-off" + ] + }, + "enforce_admins": true, + "required_pull_request_reviews": { + "required_approving_review_count": 1, + "require_code_owner_reviews": true, + "dismiss_stale_reviews": true + }, + "restrictions": null, + "required_linear_history": true, + "allow_force_pushes": false, + "allow_deletions": false, + "required_conversation_resolution": true, + "required_signatures": true +} +JSON + +echo "Branch protection applied. Verify in Settings → Branches or with:" +echo " gh api repos/${repo}/branches/main/protection --jq ." From 600daae275218bbaf95ff9fa4fac2b344c30700a Mon Sep 17 00:00:00 2001 From: Tri Lam Date: Wed, 13 May 2026 10:00:49 -0700 Subject: [PATCH 2/2] Trim superfluous comments from Wave-1 follow-ups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three small wording cuts after a fresh-eyes pass: - .github/scripts/dco-check_test.sh: 4-line signing-disable comment collapsed to one. The "why" is non-obvious enough to keep one line; the other three were prose. - scripts/apply-branch-protection.sh: dropped the "Future improvement: parse the YAML directly..." block. Forward-looking comments rot per PRINCIPLES §2; the drift hazard will surface when it bites. Header trimmed from 16 lines to 7. - CONTRIBUTING.md: AI-assisted commits bullet now points at AGENTS.md for the trailer format instead of duplicating examples inline. Net: -12 lines, no behavior change, all tests still green. Refs RFC-0003. Assisted-by: Anthropic:claude-opus-4-7 [Claude Code] Signed-off-by: Tri Lam --- .github/scripts/dco-check_test.sh | 5 +---- CONTRIBUTING.md | 2 +- scripts/apply-branch-protection.sh | 15 +++------------ 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/.github/scripts/dco-check_test.sh b/.github/scripts/dco-check_test.sh index 357d4cfa..7b589cb3 100755 --- a/.github/scripts/dco-check_test.sh +++ b/.github/scripts/dco-check_test.sh @@ -12,10 +12,7 @@ cd "$tmp" git init -q -b main git config user.email "tester@example.com" git config user.name "Tester" -# Disable commit signing locally: a contributor who ran scripts/setup-signing.sh -# has commit.gpgsign=true globally, which would make these test commits try to -# sign with a key that isn't available in the sandbox repo. The test is about -# DCO trailers, not about signing. +# Disable signing — the sandbox repo has no key; this test is about DCO trailers. git config commit.gpgsign false git config tag.gpgsign false git commit --allow-empty -q -m "Init" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7e280a8..61f62e75 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,7 @@ make ci # what CI runs: license-check + vet + lint + test + build - **Atomic commits.** Each commit must build and pass tests on its own. - **Sign off your commits**: `git commit -s`. We require [DCO](https://developercertificate.org/). - **Sign your commits cryptographically.** `main` requires signed commits. The fastest path is SSH signing — run `scripts/setup-signing.sh` once and it configures `gpg.format=ssh`, `user.signingkey`, `commit.gpgsign=true`, `tag.gpgsign=true`. Register the same SSH key as a "Signing Key" in your GitHub account (Settings → SSH and GPG keys). Sigstore `gitsign` (keyless OIDC) is an accepted alternative; see [sigstore.dev/gitsign](https://docs.sigstore.dev/cosign/signing/git_support/). -- **AI-assisted commits**: add an `Assisted-by:` trailer disclosing the agent, model, and tool, e.g. `Assisted-by: Anthropic:claude-opus-4-7 [Claude Code]`. The simpler form `Assisted-by: ` is accepted but the richer format is preferred. Do not use `Co-Authored-By:` for AI tools — CI rejects it (see [`AGENTS.md`](AGENTS.md)). +- **AI-assisted commits**: add an `Assisted-by:` trailer (see [`AGENTS.md`](AGENTS.md) for format). Never use `Co-Authored-By:` for AI tools — CI rejects it. ## Commit message format diff --git a/scripts/apply-branch-protection.sh b/scripts/apply-branch-protection.sh index d08b5310..4c2ca497 100755 --- a/scripts/apply-branch-protection.sh +++ b/scripts/apply-branch-protection.sh @@ -1,19 +1,10 @@ #!/usr/bin/env bash # apply-branch-protection.sh — apply the rules described in # .github/branch-protection.yml to the `main` branch via gh api. +# Idempotent; requires `gh auth login` with `repo` scope. # -# Idempotent: safe to re-run; every key is reapplied on every invocation. -# Requires `gh auth login` with `repo` scope. Run from a repo clone (the -# script uses the origin remote to discover :owner/:repo). -# -# To change a setting: -# 1. Edit .github/branch-protection.yml so intent matches the new state. -# 2. Edit this script's JSON payload to match the new state. -# 3. Re-run the script. -# -# Future improvement: parse the YAML directly so the payload is generated -# from the intent doc, eliminating the chance of drift between the two. -# Today the script is hand-mirrored from the YAML — drift is a P1 bug. +# To change a setting: edit both .github/branch-protection.yml (intent) and +# the JSON payload below (live state), then re-run. set -euo pipefail if ! command -v gh >/dev/null 2>&1; then