Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Explain what changed and why.
- [ ] Documentation updated when contributor or user behavior changes
- [ ] No GitHub, GitLab, AI provider, telemetry, or external-service dependency was added to core analysis
- [ ] JSON compatibility was preserved or the compatibility impact is explained
- [ ] Branch name, PR title, and commit messages avoid coding agent or tool names

## Scope

Expand Down
81 changes: 81 additions & 0 deletions .github/scripts/check-public-metadata.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env sh
set -eu

blocked_name_pattern='(^|[[:space:]_./-])(codex|claude|gemini|copilot|cursor|windsurf|aider|devin)([[:space:]_./-]|$)'
failed=0

check_value() {
label="$1"
value="${2:-}"

if [ -z "$value" ]; then
return 0
fi

if printf '%s\n' "$value" | grep -Eiq "$blocked_name_pattern"; then
echo "::error title=Blocked coding tool name::${label} contains a blocked coding tool name. Use a product, issue, or behavior-focused name instead."
failed=1
fi
}

collect_commit_messages() {
output_file="$1"
: > "$output_file"

if [ -n "${PRMAVEN_COMMIT_MESSAGES_FILE:-}" ]; then
cat "$PRMAVEN_COMMIT_MESSAGES_FILE" > "$output_file"
return 0
fi

if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
return 0
fi

base_sha="${PRMAVEN_BASE_SHA:-}"
head_sha="${PRMAVEN_HEAD_SHA:-}"
push_before="${PRMAVEN_PUSH_BEFORE:-}"
push_after="${PRMAVEN_PUSH_AFTER:-}"

if [ -n "$base_sha" ] && [ -n "$head_sha" ] &&
git cat-file -e "$base_sha^{commit}" 2>/dev/null &&
git cat-file -e "$head_sha^{commit}" 2>/dev/null; then
git log --format=%B --no-merges "$base_sha..$head_sha" > "$output_file" || :
return 0
fi

if [ -n "$push_before" ] &&
[ "$push_before" != "0000000000000000000000000000000000000000" ] &&
[ -n "$push_after" ] &&
git cat-file -e "$push_before^{commit}" 2>/dev/null &&
git cat-file -e "$push_after^{commit}" 2>/dev/null; then
git log --format=%B --no-merges "$push_before..$push_after" > "$output_file" || :
return 0
fi

git log --format=%B --no-merges -n 50 > "$output_file" || :
}

check_value "Pull request title" "${PRMAVEN_PR_TITLE:-}"
check_value "Branch name" "${PRMAVEN_HEAD_REF:-}"

messages_file="$(mktemp)"
collect_commit_messages "$messages_file"

if [ -s "$messages_file" ] && grep -Eiq "$blocked_name_pattern" "$messages_file"; then
echo "::error title=Blocked coding tool name::Commit messages contain a blocked coding tool name. Use product, issue, or behavior-focused commit messages instead."
failed=1
fi

rm -f "$messages_file"

if [ "$failed" -ne 0 ]; then
cat <<'MSG'
Public repository metadata must not include coding agent or tool names.

Rename the branch, pull request title, or commit message so the project history
describes the product change rather than the automation used to produce it.
MSG
exit 1
fi

echo "Public metadata naming guard passed."
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ env:
PRMAVEN_MIN_COVERAGE: "70"

jobs:
metadata-guard:
name: Agent name guard
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Validate public metadata
env:
PRMAVEN_PR_TITLE: ${{ github.event.pull_request.title }}
PRMAVEN_HEAD_REF: ${{ github.event.pull_request.head.ref || github.ref_name }}
PRMAVEN_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PRMAVEN_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PRMAVEN_PUSH_BEFORE: ${{ github.event.before }}
PRMAVEN_PUSH_AFTER: ${{ github.sha }}
run: sh .github/scripts/check-public-metadata.sh

quality:
name: Quality gate
runs-on: ubuntu-latest
Expand Down Expand Up @@ -186,6 +205,7 @@ jobs:
name: All CI checks
runs-on: ubuntu-latest
needs:
- metadata-guard
- quality
- test
- race
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Every new issue and pull request receives the standard contributor thank-you mes
- Do not add telemetry.
- Do not require external services for core tests.
- Do not commit generated binaries, local caches, or private CI logs.
- Keep branch names, pull request titles, commit messages, and merge messages focused on the product change. Do not include coding agent or tool names such as `codex`, `claude`, `gemini`, `copilot`, `cursor`, `windsurf`, `aider`, or `devin`.

## Good First Contributions

Expand Down Expand Up @@ -79,6 +80,7 @@ Expected standard:
- Tests are included.
- The diff is scoped.
- The contribution does not perform unrelated refactors.
- Public metadata describes the product change, not the automation used to produce it.

## Maintainers

Expand Down
3 changes: 3 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Runs on:

Jobs:

- `Agent name guard`: validates that branch names, pull request titles, and commit messages do not include coding agent or tool names.
- `Quality gate`: `gofmt`, `go vet`, and unit tests.
- `Go tests`: Linux, Windows, macOS, Go 1.22.x, and current stable Go.
- `Race detector`: `go test -race ./...` on Linux.
Expand Down Expand Up @@ -118,6 +119,8 @@ Recommended required status:

- `All CI checks`

`All CI checks` includes the public metadata guard so pull requests cannot merge when branch names, pull request titles, or commit messages include blocked coding agent or tool names.

Keep security checks visible, but avoid making scheduled security tooling a blocker for focused contributor PRs until the project has more maintainers.

Only users with maintainer-level repository permissions should merge pull requests. See [MAINTAINERS.md](../MAINTAINERS.md).
Expand Down
3 changes: 3 additions & 0 deletions docs/oss-guardrails.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The project follows a conservative OSS posture inspired by mature Maven ecosyste
- Pull request head branches are deleted after merge.
- Conversation resolution is required before merge.
- Repository workflow token permissions default to `contents: read`.
- `All CI checks` includes a public metadata guard that blocks branch names, pull request titles, and commit messages containing coding agent or tool names.
- Secret scanning, secret scanning push protection, and Dependabot security updates are enabled for the public repository.
- Core analysis must not require network access, provider tokens, telemetry, AI services, or hosted APIs.

Expand All @@ -29,6 +30,7 @@ The project follows a conservative OSS posture inspired by mature Maven ecosyste
- Keep issue bodies explicit about dependencies and acceptance criteria.
- Keep `status: blocked` issues blocked until their dependency is closed or intentionally waived.
- Do not merge contributor PRs without a relevant type label, area label, and stage label when the PR belongs to the roadmap.
- Keep public metadata product-focused: branch names, pull request titles, commit messages, and merge messages should not include coding agent or tool names.
- Prefer fixture-based tests for parser and CLI behavior.

## Workflow Safety
Expand All @@ -38,6 +40,7 @@ The project follows a conservative OSS posture inspired by mature Maven ecosyste
- Comment-only automations may read base-repository templates and write comments.
- Release package jobs may receive `id-token: write` and `attestations: write` only to generate GitHub artifact and SBOM attestations.
- Release publishing jobs may receive `contents: write`; other jobs should stay read-only unless a specific need is documented.
- Required CI should keep the public metadata guard in the aggregate `All CI checks` gate.

## Local-First Product Guardrail

Expand Down
4 changes: 3 additions & 1 deletion docs/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Required public-mode controls:
- Require conversation resolution before merge.
- Disable force pushes.
- Disable branch deletion.
- Keep the public metadata guard inside `All CI checks` so agent or tool names in branch names, pull request titles, and commit messages block merges.
- Maintain a repository ruleset for `main` that rejects commit messages containing blocked coding agent or tool names when GitHub rulesets are available.
- Delete pull request head branches after merge.
- Keep merge rights limited to users with write, maintain, or admin access.
- Keep `@Will-thom` as the repository-wide code owner through `.github/CODEOWNERS`.
Expand All @@ -49,7 +51,7 @@ Repository-level workflow token default:

Workflow-specific policy:

- `CI` uses `contents: read`.
- `CI` uses `contents: read`; its public metadata guard checks branch names, pull request titles, and commit messages before `All CI checks` can pass.
- `Security` uses `contents: read`, `security-events: write`, and `pull-requests: read`.
- `Release` defaults to `contents: read`; package jobs receive `id-token: write` and `attestations: write` only for GitHub artifact and SBOM attestations; only the release publishing job receives `contents: write`.
- `Thank Contributor` uses `contents: read`, `issues: write`, and `pull-requests: write` only to read the base repository template through the GitHub API and write a comment. It must not check out or execute contributor code.
Expand Down
Loading