diff --git a/.github/workflows/pr-title-check.yml b/.github/workflows/pr-title-check.yml new file mode 100644 index 00000000..86f6effa --- /dev/null +++ b/.github/workflows/pr-title-check.yml @@ -0,0 +1,21 @@ +name: PR Title Check + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + branches: [main] + +permissions: + contents: read + +jobs: + pr-title: + name: Check PR title + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Check for agent/tool PR title prefix + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: node scripts/check-pr-title.cjs "$PR_TITLE" diff --git a/AGENTS.md b/AGENTS.md index b880e99c..477aa65e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,6 +4,10 @@ adcp-go is the Go SDK and reference implementation for the Ad Context Protocol (AdCP) Trusted Match Protocol (TMP). It provides a router, targeting engine, and reference agents for real-time ad package activation with structural privacy guarantees. +## PR title hygiene + +Use concrete PR titles that describe the change. Do not prefix titles with the tool or model that authored the PR, such as `[codex]`, `[claude]`, `[cursor]`, or similar ownership tags. Put authoring-tool context in the PR body or labels when it matters, not in the review-facing title. + ## Production hardening is a first-class priority This project is designed to run in trusted execution environments (TEEs) and be embedded into existing ad tech infrastructure (e.g., Prebid Server). Every change should consider: diff --git a/scripts/check-pr-title.cjs b/scripts/check-pr-title.cjs new file mode 100644 index 00000000..6757e18d --- /dev/null +++ b/scripts/check-pr-title.cjs @@ -0,0 +1,18 @@ +#!/usr/bin/env node + +const title = (process.argv.slice(2).join(' ') || process.env.PR_TITLE || '').trim(); + +if (!title) { + console.error('PR title is empty.'); + process.exit(1); +} + +const disallowedAgentPrefix = + /^\[(codex|claude|claude-code|openai|chatgpt|copilot|cursor|aider|devin|agent|ai)\](?:\s|:|-|$)/i; + +if (disallowedAgentPrefix.test(title)) { + console.error(`Invalid PR title: ${title}`); + console.error('Remove the leading agent/tool prefix. Use a concrete PR title instead, for example:'); + console.error(' fix(ci): block agent PR title prefixes'); + process.exit(1); +}