From d9ce33893bda1bfebf359937efd4f1418c9521f0 Mon Sep 17 00:00:00 2001 From: kperry Date: Thu, 16 Jul 2026 14:31:17 -0500 Subject: [PATCH 1/5] build: enforce DCO sign-off on pull requests Add a DCO status check requiring every human-authored commit to carry a Signed-off-by trailer matching the commit author or committer, certifying https://developercertificate.org. Bot-opened PRs (Dependabot, release-please) are exempt and merge commits are skipped. Assisted-by: Claude Code (claude-fable-5) Co-Authored-By: Claude Fable 5 Signed-off-by: kperry --- .github/workflows/dco.yml | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/dco.yml diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml new file mode 100644 index 0000000..4974a2c --- /dev/null +++ b/.github/workflows/dco.yml @@ -0,0 +1,59 @@ +name: DCO + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +jobs: + dco: + name: DCO + # Bot-opened PRs (Dependabot, release-please) are exempt: bots cannot + # certify the DCO. A skipped job still satisfies a required status check. + if: ${{ !endsWith(github.event.pull_request.user.login, '[bot]') }} + runs-on: ubuntu-latest + steps: + - name: Verify Signed-off-by on every commit + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + PR: ${{ github.event.pull_request.number }} + run: | + set -euo pipefail + bad=0 + # Merge commits and bot-authored commits are skipped; every other + # commit needs a Signed-off-by trailer whose email matches the + # commit author or committer (Developer Certificate of Origin). + for row in $(gh api "repos/${REPO}/pulls/${PR}/commits" --paginate \ + --jq '.[] | select((.parents | length) < 2) | select(((.author.login // "") | endswith("[bot]")) | not) | @base64'); do + field() { echo "$row" | base64 -d | jq -r "$1"; } + sha=$(field '.sha') + author_email=$(field '.commit.author.email' | tr '[:upper:]' '[:lower:]') + committer_email=$(field '.commit.committer.email' | tr '[:upper:]' '[:lower:]') + signoff_emails=$(field '.commit.message' \ + | grep -E '^Signed-off-by: .+ <[^<>@ ]+@[^<>@ ]+>$' \ + | sed -E 's/.*<([^<>]+)>.*/\1/' \ + | tr '[:upper:]' '[:lower:]' || true) + ok=0 + for email in $signoff_emails; do + if [ "$email" = "$author_email" ] || [ "$email" = "$committer_email" ]; then + ok=1 + fi + done + if [ "$ok" -ne 1 ]; then + echo "::error::commit ${sha} has no Signed-off-by matching its author or committer (${author_email})" + bad=1 + fi + done + if [ "$bad" -ne 0 ]; then + echo "" + echo "One or more commits lack a valid DCO sign-off." + echo "Certify the Developer Certificate of Origin (https://developercertificate.org)" + echo "by signing each commit:" + echo " new commits: git commit -s" + echo " existing commits: git rebase --signoff origin/main && git push --force-with-lease" + exit 1 + fi + echo "All commits carry a valid Signed-off-by." From c95783190d5d7c857abf25afc92a79f017e115df Mon Sep 17 00:00:00 2001 From: kperry Date: Thu, 16 Jul 2026 14:37:13 -0500 Subject: [PATCH 2/5] docs: add org-wide default CONTRIBUTING guide Organization-wide baseline inherited by repos without their own CONTRIBUTING.md: issue-first PRs with closing keywords, Conventional Commit titles, DCO sign-off per the Linux Foundation model, and AI-assistance disclosure per the kernel convention. Assisted-by: Claude Code (claude-fable-5) Co-Authored-By: Claude Fable 5 Signed-off-by: kperry --- CONTRIBUTING.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8f422de --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# Contributing + +These are the organization-wide contribution guidelines for +[agentnameservice](https://github.com/agentnameservice) repositories. +A repository may extend them with project-specific guidance in its own +`CONTRIBUTING.md`; where one exists, it takes precedence. + +## Pull Requests + +- Open an issue first and reference it from your pull request with a closing + keyword (e.g. `Fixes #123`) — issues are where triage and prioritization + happen. +- PR titles follow [Conventional Commits](https://www.conventionalcommits.org); + release notes are generated from them. + +## Developer Certificate of Origin + +This organization follows the Linux Foundation contribution model. Every +commit must carry a `Signed-off-by:` trailer certifying the +[Developer Certificate of Origin](https://developercertificate.org) — your +assertion that you have the right to submit the change under the project's +license. Sign off each commit with: + +``` +git commit -s +``` + +Missing sign-offs on an existing branch can be fixed with +`git rebase --signoff origin/main` followed by a force-push. The `DCO` +status check enforces this on every pull request; PRs opened by bots +(Dependabot, release-please) are exempt, and merge commits are skipped. + +## AI-Assisted Contributions + +AI-assisted contributions are welcome **with disclosure**, following the +[Linux kernel convention](https://docs.kernel.org/process/coding-assistants.html): + +- Disclose the tooling in the pull request's **AI assistance** section, + naming the tool and model, e.g. `Assisted-by: Claude Code (claude-fable-5)`. +- AI tools must never add `Signed-off-by:` lines. DCO certification belongs + to the human submitter, who remains fully responsible for the correctness + and licensing of the contribution. From 382bae6c4aee641f0d37965b3fed229940c7b15c Mon Sep 17 00:00:00 2001 From: kperry Date: Thu, 16 Jul 2026 14:52:27 -0500 Subject: [PATCH 3/5] build: extract DCO check into an org-shared reusable workflow The verification logic moves to dco-check.yml (on: workflow_call) so every repo in the org calls one implementation instead of carrying its own copy; dco.yml becomes a thin caller. This repo references the reusable workflow by local path so its own PRs always exercise the version they change. Assisted-by: Claude Code (claude-fable-5) Co-Authored-By: Claude Fable 5 Signed-off-by: kperry --- .github/workflows/dco-check.yml | 61 +++++++++++++++++++++++++++++++++ .github/workflows/dco.yml | 52 +++------------------------- 2 files changed, 66 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/dco-check.yml diff --git a/.github/workflows/dco-check.yml b/.github/workflows/dco-check.yml new file mode 100644 index 0000000..6502c4e --- /dev/null +++ b/.github/workflows/dco-check.yml @@ -0,0 +1,61 @@ +name: DCO check (reusable) + +# Org-shared DCO verification, called from each repository's thin dco.yml +# caller. Fix or extend the policy here — never in the per-repo callers. + +on: + workflow_call: {} + +permissions: + contents: read + +jobs: + dco: + name: DCO + # Bot-opened PRs (Dependabot, release-please) are exempt: bots cannot + # certify the DCO. A skipped job still satisfies a required status check. + if: ${{ !endsWith(github.event.pull_request.user.login, '[bot]') }} + runs-on: ubuntu-latest + steps: + - name: Verify Signed-off-by on every commit + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + PR: ${{ github.event.pull_request.number }} + run: | + set -euo pipefail + bad=0 + # Merge commits and bot-authored commits are skipped; every other + # commit needs a Signed-off-by trailer whose email matches the + # commit author or committer (Developer Certificate of Origin). + for row in $(gh api "repos/${REPO}/pulls/${PR}/commits" --paginate \ + --jq '.[] | select((.parents | length) < 2) | select(((.author.login // "") | endswith("[bot]")) | not) | @base64'); do + field() { echo "$row" | base64 -d | jq -r "$1"; } + sha=$(field '.sha') + author_email=$(field '.commit.author.email' | tr '[:upper:]' '[:lower:]') + committer_email=$(field '.commit.committer.email' | tr '[:upper:]' '[:lower:]') + signoff_emails=$(field '.commit.message' \ + | grep -E '^Signed-off-by: .+ <[^<>@ ]+@[^<>@ ]+>$' \ + | sed -E 's/.*<([^<>]+)>.*/\1/' \ + | tr '[:upper:]' '[:lower:]' || true) + ok=0 + for email in $signoff_emails; do + if [ "$email" = "$author_email" ] || [ "$email" = "$committer_email" ]; then + ok=1 + fi + done + if [ "$ok" -ne 1 ]; then + echo "::error::commit ${sha} has no Signed-off-by matching its author or committer (${author_email})" + bad=1 + fi + done + if [ "$bad" -ne 0 ]; then + echo "" + echo "One or more commits lack a valid DCO sign-off." + echo "Certify the Developer Certificate of Origin (https://developercertificate.org)" + echo "by signing each commit:" + echo " new commits: git commit -s" + echo " existing commits: git rebase --signoff origin/main && git push --force-with-lease" + exit 1 + fi + echo "All commits carry a valid Signed-off-by." diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml index 4974a2c..3526c4c 100644 --- a/.github/workflows/dco.yml +++ b/.github/workflows/dco.yml @@ -1,5 +1,9 @@ name: DCO +# Thin caller for this repo's own PRs. The shared check itself lives in +# dco-check.yml in this repository and is referenced by path so pull +# requests here always exercise the version they change. + on: pull_request: types: [opened, synchronize, reopened] @@ -10,50 +14,4 @@ permissions: jobs: dco: name: DCO - # Bot-opened PRs (Dependabot, release-please) are exempt: bots cannot - # certify the DCO. A skipped job still satisfies a required status check. - if: ${{ !endsWith(github.event.pull_request.user.login, '[bot]') }} - runs-on: ubuntu-latest - steps: - - name: Verify Signed-off-by on every commit - env: - GH_TOKEN: ${{ github.token }} - REPO: ${{ github.repository }} - PR: ${{ github.event.pull_request.number }} - run: | - set -euo pipefail - bad=0 - # Merge commits and bot-authored commits are skipped; every other - # commit needs a Signed-off-by trailer whose email matches the - # commit author or committer (Developer Certificate of Origin). - for row in $(gh api "repos/${REPO}/pulls/${PR}/commits" --paginate \ - --jq '.[] | select((.parents | length) < 2) | select(((.author.login // "") | endswith("[bot]")) | not) | @base64'); do - field() { echo "$row" | base64 -d | jq -r "$1"; } - sha=$(field '.sha') - author_email=$(field '.commit.author.email' | tr '[:upper:]' '[:lower:]') - committer_email=$(field '.commit.committer.email' | tr '[:upper:]' '[:lower:]') - signoff_emails=$(field '.commit.message' \ - | grep -E '^Signed-off-by: .+ <[^<>@ ]+@[^<>@ ]+>$' \ - | sed -E 's/.*<([^<>]+)>.*/\1/' \ - | tr '[:upper:]' '[:lower:]' || true) - ok=0 - for email in $signoff_emails; do - if [ "$email" = "$author_email" ] || [ "$email" = "$committer_email" ]; then - ok=1 - fi - done - if [ "$ok" -ne 1 ]; then - echo "::error::commit ${sha} has no Signed-off-by matching its author or committer (${author_email})" - bad=1 - fi - done - if [ "$bad" -ne 0 ]; then - echo "" - echo "One or more commits lack a valid DCO sign-off." - echo "Certify the Developer Certificate of Origin (https://developercertificate.org)" - echo "by signing each commit:" - echo " new commits: git commit -s" - echo " existing commits: git rebase --signoff origin/main && git push --force-with-lease" - exit 1 - fi - echo "All commits carry a valid Signed-off-by." + uses: ./.github/workflows/dco-check.yml From a208add6d131d52e993b38bd6bc298748e4d5ec5 Mon Sep 17 00:00:00 2001 From: kperry Date: Thu, 16 Jul 2026 14:59:43 -0500 Subject: [PATCH 4/5] build: use the org-wide DCO app instead of a per-repo workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DCO enforcement moves to https://github.com/apps/dco — the standard across Linux Foundation projects — which validates sign-offs per commit and exempts bot-authored commits and merges by default. Drop the Actions workflow and point CONTRIBUTING at the app. Assisted-by: Claude Code (claude-fable-5) Co-Authored-By: Claude Fable 5 Signed-off-by: kperry --- .github/workflows/dco-check.yml | 61 --------------------------------- .github/workflows/dco.yml | 17 --------- CONTRIBUTING.md | 6 ++-- 3 files changed, 4 insertions(+), 80 deletions(-) delete mode 100644 .github/workflows/dco-check.yml delete mode 100644 .github/workflows/dco.yml diff --git a/.github/workflows/dco-check.yml b/.github/workflows/dco-check.yml deleted file mode 100644 index 6502c4e..0000000 --- a/.github/workflows/dco-check.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: DCO check (reusable) - -# Org-shared DCO verification, called from each repository's thin dco.yml -# caller. Fix or extend the policy here — never in the per-repo callers. - -on: - workflow_call: {} - -permissions: - contents: read - -jobs: - dco: - name: DCO - # Bot-opened PRs (Dependabot, release-please) are exempt: bots cannot - # certify the DCO. A skipped job still satisfies a required status check. - if: ${{ !endsWith(github.event.pull_request.user.login, '[bot]') }} - runs-on: ubuntu-latest - steps: - - name: Verify Signed-off-by on every commit - env: - GH_TOKEN: ${{ github.token }} - REPO: ${{ github.repository }} - PR: ${{ github.event.pull_request.number }} - run: | - set -euo pipefail - bad=0 - # Merge commits and bot-authored commits are skipped; every other - # commit needs a Signed-off-by trailer whose email matches the - # commit author or committer (Developer Certificate of Origin). - for row in $(gh api "repos/${REPO}/pulls/${PR}/commits" --paginate \ - --jq '.[] | select((.parents | length) < 2) | select(((.author.login // "") | endswith("[bot]")) | not) | @base64'); do - field() { echo "$row" | base64 -d | jq -r "$1"; } - sha=$(field '.sha') - author_email=$(field '.commit.author.email' | tr '[:upper:]' '[:lower:]') - committer_email=$(field '.commit.committer.email' | tr '[:upper:]' '[:lower:]') - signoff_emails=$(field '.commit.message' \ - | grep -E '^Signed-off-by: .+ <[^<>@ ]+@[^<>@ ]+>$' \ - | sed -E 's/.*<([^<>]+)>.*/\1/' \ - | tr '[:upper:]' '[:lower:]' || true) - ok=0 - for email in $signoff_emails; do - if [ "$email" = "$author_email" ] || [ "$email" = "$committer_email" ]; then - ok=1 - fi - done - if [ "$ok" -ne 1 ]; then - echo "::error::commit ${sha} has no Signed-off-by matching its author or committer (${author_email})" - bad=1 - fi - done - if [ "$bad" -ne 0 ]; then - echo "" - echo "One or more commits lack a valid DCO sign-off." - echo "Certify the Developer Certificate of Origin (https://developercertificate.org)" - echo "by signing each commit:" - echo " new commits: git commit -s" - echo " existing commits: git rebase --signoff origin/main && git push --force-with-lease" - exit 1 - fi - echo "All commits carry a valid Signed-off-by." diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml deleted file mode 100644 index 3526c4c..0000000 --- a/.github/workflows/dco.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: DCO - -# Thin caller for this repo's own PRs. The shared check itself lives in -# dco-check.yml in this repository and is referenced by path so pull -# requests here always exercise the version they change. - -on: - pull_request: - types: [opened, synchronize, reopened] - -permissions: - contents: read - -jobs: - dco: - name: DCO - uses: ./.github/workflows/dco-check.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f422de..5295a03 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,8 +27,10 @@ git commit -s Missing sign-offs on an existing branch can be fixed with `git rebase --signoff origin/main` followed by a force-push. The `DCO` -status check enforces this on every pull request; PRs opened by bots -(Dependabot, release-please) are exempt, and merge commits are skipped. +status check — the org-wide [DCO app](https://github.com/apps/dco), the +same enforcement used across Linux Foundation projects — validates this +on every pull request; bot-authored commits (Dependabot, release-please) +and merge commits are exempt. ## AI-Assisted Contributions From 77cfd0b0888936b26232511a8724b11c31eebf29 Mon Sep 17 00:00:00 2001 From: kperry Date: Thu, 16 Jul 2026 15:39:20 -0500 Subject: [PATCH 5/5] chore: trigger DCO evaluation Empty commit; the hosted DCO app missed this PR's reopen event, and a push reliably delivers a fresh pull_request synchronize event. Assisted-by: Claude Code (claude-fable-5) Co-Authored-By: Claude Fable 5 Signed-off-by: kperry