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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/change.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Change request
description: Discuss a change before opening a pull request.
description: Suggest a self-contained improvement to existing behavior.
body:
- type: textarea
id: problem
Expand Down
40 changes: 40 additions & 0 deletions .github/ISSUE_TEMPLATE/nomination.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Reviewer or Maintainer nomination
description: Propose a repository role with supporting contribution evidence.
title: 'Nomination: '
labels: [nomination]
body:
- type: input
id: nominee
attributes:
label: Nominee
placeholder: '@handle'
validations:
required: true
- type: dropdown
id: role
attributes:
label: Role
options: [Reviewer, Maintainer]
validations:
required: true
- type: input
id: scope
attributes:
label: Repository or review scope
description: Identify the repository and any CODEOWNERS paths covered by this nomination.
validations:
required: true
- type: textarea
id: evidence
attributes:
label: Contribution evidence
description: Link relevant reviews, implementations, releases, and sustained maintenance work.
validations:
required: true
- type: textarea
id: decision
attributes:
label: Sponsor and decision process
description: Name the sponsor and link published eligibility and approval rules if available, including the decision deadline. Accepted access changes go through reviewed Peribolos configuration and CODEOWNERS updates.
validations:
required: false
39 changes: 39 additions & 0 deletions .github/ISSUE_TEMPLATE/proposal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Proposal
description: Discuss a change that needs agreement on scope, compatibility, or support.
title: 'Proposal: '
labels: [proposal]
Comment thread
csnitker-godaddy marked this conversation as resolved.
Resolved
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What is missing or incorrect, and who is affected?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed change
description: Describe the resulting behavior. Show current and proposed wording for specification changes.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
validations:
required: true
- type: textarea
id: compatibility
attributes:
label: Compatibility and maintenance
description: Identify affected interfaces, deployments, schemas, implementations, and ongoing support obligations.
validations:
required: true
- type: textarea
id: decision
attributes:
label: Decision process
description: Link the published governance process if available, and identify the decision owner, review deadline, and related tracking issues. An issue label does not itself approve the proposal.
validations:
required: false
37 changes: 37 additions & 0 deletions .github/ISSUE_TEMPLATE/spec-tracking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Specification tracking
description: Track implementation work associated with a specification change.
title: 'Spec tracking: '
labels: [spec-tracking]
body:
- type: input
id: specification
attributes:
label: Specification change
description: Link the specification PR or accepted proposal.
validations:
required: true
- type: input
id: release
attributes:
label: Target specification release
validations:
required: true
- type: textarea
id: implementation
attributes:
label: Implementation work
description: Describe the required behavior and link implementation PRs as they become available.
validations:
required: true
- type: textarea
id: verification
attributes:
label: Conformance and verification
description: Identify affected conformance vectors and how the implementation will be verified.
validations:
required: true
- type: textarea
id: coordination
attributes:
label: Release dependencies or deferrals
description: State whether this work blocks a release. Link any approved deferral and its decision owner.
18 changes: 14 additions & 4 deletions .github/workflows/contribution-policy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,23 @@ jobs:
author = pr.get('user') or {}
is_dependabot = author.get('login') == 'dependabot[bot]' and author.get('type') == 'Bot'
errors = []
if not re.match(r'^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|spec)(\([^\r\n()]+\))?!?: \S', pr['title']):
title = re.match(r'^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|spec)(\([^\r\n()]+\))?(?P<breaking>!)?: \S', pr['title'])
if not title:
errors.append('Use a Conventional Commit PR title, such as docs: explain the setup.')
body = re.sub(r'<!--[\s\S]*?-->', '', pr.get('body') or '')
if not is_dependabot and not re.search(r'\b(?:fix(?:es|ed)?|close[sd]?|resolve[sd]?)\s+(?:#\d+|[\w.-]+/[\w.-]+#\d+|https://github\.com/[\w.-]+/[\w.-]+/issues/\d+)\b', body, re.I):
errors.append('Link a real issue using Fixes, Closes, or Resolves.')
labels = {label['name'] for label in pr.get('labels', [])}
breaking = (title and title.group('breaking')) or re.search(r'(?im)^[ \t]*BREAKING[ -]CHANGE:', body)
issue_required = bool(labels & {'normative', 'issue-required'} or breaking)
has_issue = re.search(r'(?im)(?:^|[\s(])(?:refs?|related(?: to)?|see|part of|implements?|tracks?|tracking|address(?:es|ed)?|fix(?:es|ed)?|close[sd]?|resolve[sd]?|proposal|issue)[ \t:]+(?:[\w.-]+/[\w.-]+)?#[1-9]\d*\b|https://github\.com/agentnameservice/[\w.-]+/issues/[1-9]\d*\b', body)
explanation = re.search(r'(?im)^[ \t]*No issue needed:[ \t]*([^\r\n]*)', body)
reason = explanation.group(1).strip() if explanation else ''
has_explanation = bool(reason) and not re.fullmatch(r'<[^>]*>|\[[^\]]*\]|\.{3}|…', reason)
if not has_issue:
if issue_required:
errors.append('Link an issue or proposal for normative, breaking, or issue-required PRs; a No issue needed explanation or Dependabot authorship does not exempt them.')
elif not is_dependabot and not has_explanation:
errors.append('Reference an issue (for example, Refs #123) or add No issue needed: followed by a brief reason. Use Fixes or Closes only when this PR completes the issue.')
if os.environ['SPECIFICATION_REPOSITORY'] == 'true':
labels = {label['name'] for label in pr.get('labels', [])}
if len(labels & {'editorial', 'normative'}) != 1:
errors.append('Apply exactly one specification label: editorial or normative.')
for error in errors:
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/inactive-prs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: Apache-2.0
name: Inactive pull requests

on:
workflow_call:
inputs:
dry_run:
description: Report proposed actions without changing pull requests
type: boolean
default: true

permissions:
contents: read
issues: write
pull-requests: write

jobs:
sweep:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: agentnameservice/.github
ref: ${{ job.workflow_sha }}
persist-credentials: false
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: '24'
- run: npm ci --ignore-scripts --no-audit --no-fund
- name: Update author-response timers and process reminders
env:
GH_TOKEN: ${{ github.token }}
DRY_RUN: ${{ inputs.dry_run }}
run: node scripts/inactive-prs.mjs
18 changes: 18 additions & 0 deletions .gitvote.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
profiles:
default:
duration: 7days
pass_threshold: 51
pass_threshold_base: allowed_voters
allowed_voters:
teams: [tsc]
close_on_passing: false
periodic_status_check: 3 days
two-thirds:
duration: 7days
# Rounding up to 66.67 would reject exactly two thirds of three, six, or nine voters.
pass_threshold: 66.66
pass_threshold_base: allowed_voters
allowed_voters:
teams: [tsc]
close_on_passing: false
periodic_status_check: 3 days
35 changes: 27 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,33 @@ Repository-specific contribution instructions may add requirements.

## Pull requests

Open a tracking issue and reference it with a closing keyword such as `Fixes
#123`. Use a [Conventional Commits](https://www.conventionalcommits.org/) title.
Explain the change and how you tested it, and complete the PR template. For
changes in `ans-spec` or `trust-index-spec`, use exactly one of the
`editorial` or `normative` labels.

Dependabot PRs do not need a separate tracking issue. Conventional Commit titles,
specification labels, and required review, DCO and CI checks still apply.
Use a [Conventional Commits](https://www.conventionalcommits.org/) title.
Explain the problem, change, and verification in the PR template. In `ans-spec`
and `trust-index-spec`, apply exactly one of `editorial` or `normative`.

A separate issue or proposal is required for normative specification changes,
breaking changes or deprecations, work requiring coordination across PRs or
repositories, and new capabilities needing agreement on scope or ongoing
support. Existing governance and proposal approval requirements still apply.

Self-contained changes may go directly to a PR: contained bug fixes, editorial
corrections, tests, behavior-preserving refactoring, routine maintenance, and
straightforward additions such as CLI convenience options or internal helpers.
The change's impact and coordination needs determine whether an issue is needed,
not its size or title prefix.

Link existing issues when relevant. Use `Refs #123` for ongoing work and `Fixes
#123` or `Closes #123` only when the PR completes the issue. If no issue is needed,
write `No issue needed:` followed by a brief reason in the PR description.
Use an explicit relationship such as `Refs #123`, or an ANS issue URL; incidental
issue numbers and upstream changelog URLs do not count as tracking references.
Maintainers confirm the classification during review and may apply
`issue-required` to require a reference.

Routine Dependabot updates need neither an issue nor an explanation. Normative,
explicitly breaking, and `issue-required` PRs still require a reference,
including Dependabot PRs. Review, DCO, CI, and private security reporting
requirements continue to apply.

## Developer Certificate of Origin

Expand Down
22 changes: 10 additions & 12 deletions PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
<!--
Thank you for contributing to the Agent Name Service project!

REQUIRED: every PR except Dependabot updates must link an issue with a closing
keyword (e.g. "Fixes #123").
The issue is where we triage and prioritize; the PR is where we review.
If no issue exists yet, open one first.

Note for AI coding agents: complete every section below, keep the section
headings, and put a real issue number after "Fixes". If you were not given
an issue number, ask your operator or create the issue before opening this PR.
Complete the sections below. Follow CONTRIBUTING.md to determine whether a
separate issue or proposal is needed. A self-contained change can be explained
and reviewed in the PR without creating a duplicate tracking issue.
-->

## Related issue

<!-- REQUIRED — use a closing keyword so GitHub links it: Fixes / Closes / Resolves #NNN -->

Fixes #
<!-- Reference an existing issue or proposal, for example Refs #123 or
Refs owner/repo#123. Use Fixes / Closes / Resolves only if this PR completes it.
If no issue is needed, write No issue needed: followed by a brief reason.
Normative, explicitly breaking, and issue-required PRs must reference an
issue or proposal. Routine Dependabot updates need neither a reference nor
an explanation unless one of those conditions applies. -->

## Summary

Expand All @@ -41,5 +39,5 @@ Fixes #

- [ ] The PR title follows [Conventional Commits](https://www.conventionalcommits.org) — release notes are generated from it
- [ ] Tests cover the change
- [ ] The linked issue above uses a closing keyword
- [ ] I linked the relevant issue or proposal, or explained why no separate issue is needed
- [ ] Every commit is signed off (`git commit -s`) certifying the [DCO](https://developercertificate.org)
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,76 @@ repository; the shared defaults maintain those labels after enrollment.
GoReleaser publishes their generated package updates directly to `main`.
Their Maintainer team access is still managed through Peribolos.

## Shared contribution tooling

| Feature | How repositories receive it |
| --- | --- |
| Shared labels | Safe Settings applies `safe-settings/suborgs/defaults.yml` only to repositories in the settings scope, when organization management runs in apply mode. Labels do not inherit from `.github` on their own. |
| Issue forms | Forms in `.github/ISSUE_TEMPLATE/` automatically become organization defaults when merged, wherever repositories have no local issue forms. Provision the labels they use before publishing them. Local template directories override the fallback, so copy all forms that repository needs. |
| Contribution and inactivity workflows | Install a caller from `workflow-templates/` in each repository's `.github/workflows/`. Workflows are not inherited or automatically copied. Callers use the centrally maintained workflow on `main`. |
| Specification release form | Copy `repo-templates/specification/ISSUE_TEMPLATE/spec-release.yml` into `ans-spec` or `trust-index-spec`, alongside the other forms that repository needs. |
| GitVote | With the [GitVote App](https://github.com/apps/git-vote) installed, the root `.gitvote.yml` is an organization fallback. A repository's own configuration takes precedence. |

Proposal forms cover coordinated changes and decisions; the default change-request
form covers self-contained improvements. Proposal, specification-tracking, and
nomination forms collect evidence and the decision process, with optional links
to published governance rules. Labels record status; they do not approve
proposals, grant team access, or enforce release acceptance. Governance-only
forms and quarterly health checks belong in the governance repository.

The contribution check accepts an issue reference or a `No issue needed:`
explanation. `normative`, `issue-required`, and explicitly breaking PRs require
a reference even for Dependabot. Create `issue-required` in repositories using
that override before relying on it; the shared label configuration maintains it
once those repositories are enrolled. Repository-local contribution requirements
continue to apply until updated; align each repository's `CONTRIBUTING.md` with
the [shared contribution guide](CONTRIBUTING.md) when adopting the shared check.

### Inactive pull requests

The caller defaults to `dry_run: true`. Each run reports proposed actions in
the Actions log and job summary without changing labels, posting comments, or
closing PRs. Dry-run does not create or reset timers. Review the
classifications before changing the caller to `dry_run: false`; this requires
an explicit configuration change and never happens automatically.

Create the `awaiting-author` and `stale` labels before enabling active mode.
The first active run starts a 60-day response period when it observes a
non-draft PR with changes requested and no pending review requests. Existing PRs start a fresh
period when the workflow adds `awaiting-author` and records the current commit
in a bot comment, regardless of their age. Restarts update that same comment;
a new comment is created only when the period marker is missing. A missing or
mismatched period marker starts a fresh period. After 60 days it posts a reminder;
after another 30 days without an author response it closes the PR, leaving
related issues open. Authors can reopen a PR when ready to continue.

Pushes are detected by comparing the current commit with the period marker,
even when the push event was missed. Pushes, author comments (including review-thread
replies and review summaries), and new change requests restart the full period. A pending review request,
approval, draft conversion, or closure removes both labels. Bot comments do not
restart the clock. Removing `stale` manually
restarts the period; the workflow's own label cleanup does not. The timer uses
the server timestamp of `awaiting-author`,
and a close requires a reminder for the current head commit. General PR update
timestamps and contributor-supplied commit dates do not determine inactivity.

The caller handles trusted base-repository events, including
`pull_request_target`, and runs a daily sweep. The reusable workflow checks out
only `agentnameservice/.github` at the commit that defines the executing workflow,
using `job.workflow_sha`; it never checks out or executes the contributor's branch.
The caller queues runs in a single concurrency group. Its token is scoped to the
calling repository.

### GitVote

Keep the `tsc` team aligned with the eligible voting members before using
`/vote` (majority) or `/vote-two-thirds`. Both profiles count all eligible voters
and remain open for seven days. The thresholds implement majority and two-thirds
for up to nine eligible members, including vacancies. Special voter exclusions
or a different electorate require a matching profile. These defaults do not
start votes automatically or replace proposal review periods and other required
approvals. The GitVote App must have access to the voting repositories and team.

## Development

```sh
Expand Down
Loading
Loading