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
11 changes: 11 additions & 0 deletions .github/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ repository:
delete_branch_on_merge: true
allow_update_branch: true

# Labels that should exist in every repo.
#
# NOT YET APPLIED. `apply-settings.py` acts on `repository`, `branches` and `rulesets`
# only, so these labels are still created per repo by hand with `gh label create`. This
# block is the canonical set; teaching the reconciler to apply it is the remaining work on
# https://github.com/swimblocks/.github/issues/46, which stays open until it lands.
labels:
- name: no-issue
color: ededed
description: Change small enough to skip the issue-first rule; rationale is in the PR body

# Branch protection for public repos is handled via GitHub Rulesets (see `rulesets:` below),
# which support bypass actors so org owners and repo admins can force-push without extra steps
# — just `git push origin main --force`. GitHub records the bypass in the audit log.
Expand Down
7 changes: 6 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ gcloud auth application-default login
For **every** change:

1. **Open a GitHub issue first.** Describe the change. This is the unit of work.
2. **Branch** off `main`, named `<issue-number>-<short-slug>`.
- *Exception:* a change small enough to explain itself — a typo, a doc clarification,
recording a decision already made — may go straight to a PR. Label it `no-issue` and
end the description with `NO-ISSUE: <short reason>`. Use a real issue whenever the
change needs discussion or has acceptance criteria.
2. **Branch** off `main`, named `<issue-number>-<short-slug>` (or a descriptive slug, for a
`no-issue` PR).
3. **Make focused commits.** Coherent, single-purpose. Run `ruff check .` and `pytest -q`
locally before pushing.
4. **Hand off for local review — do not open the PR.** Nobody opens a pull request carrying
Expand Down
27 changes: 26 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ explicitly overrides it.
## Workflow: issue → branch → PR → squash-merge

1. **Open an issue first.** Describe the problem or feature. This is the unit of work.
2. **Branch** off `main`, named `<issue-number>-<short-slug>` (e.g. `42-fix-date-parsing`).
See [the `no-issue` exception](#the-no-issue-exception) for changes small enough to
skip this.
2. **Branch** off `main`, named `<issue-number>-<short-slug>` (e.g. `42-fix-date-parsing`),
or a descriptive slug when there is no issue.
3. **Do the work.** Keep commits coherent. Run tests + lint locally before pushing.
4. **Read the change before it becomes a PR.** A pull request is a claim that its author
stands behind the change, so nobody opens one carrying work the author hasn't actually
Expand All @@ -43,6 +46,7 @@ explicitly overrides it.
PR description. A question written into a PR reads as though the author is asking their
reviewers, which sponsors a question they never asked.
5. **Open a PR** whose description includes `Closes #<issue-number>` and explains the *why*.
A `no-issue` PR has no number to close, and carries the `NO-ISSUE:` trailer instead.
6. **CI must be green** (lint + tests) before merge.
7. **Hand off for merge.** Agents do **not** self-merge: after CI is green, post the PR link
and stop.
Expand All @@ -53,6 +57,27 @@ explicitly overrides it.
deletes the branch. The squash commit message should carry the meaningful detail, not just
the PR title.

### The `no-issue` exception

A change small enough to explain itself — a typo, a doc clarification, recording a decision
already made — may go straight to a PR. Label it `no-issue` and end the description with a
trailer saying why:

```
NO-ISSUE: Clarifying Documentation
```

The ceremony in step 1 is worth paying whenever a change needs a decision recorded, argued,
or found again later. It is pure overhead when the change carries its own justification in
one paragraph. The label and the trailer are what keep the exception **visible and
auditable** rather than silent: every PR that skipped the issue says so, in a form you can
search for.

Use a real issue whenever the change needs discussion, has acceptance criteria, or is
something a future reader would look for in the tracker. Changes to the rules in this file
are always in that category — a policy that nobody can find the reasoning for is a policy
that gets re-litigated.

### Solo-admin merge path

Until a second code owner exists, the author satisfying `require_code_owner_reviews` on their
Expand Down
Loading