diff --git a/.github/settings.yml b/.github/settings.yml index bc9fc5e..d223212 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -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. diff --git a/AGENTS.md b/AGENTS.md index b8a793e..1bfade8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 `-`. + - *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: `. Use a real issue whenever the + change needs discussion or has acceptance criteria. +2. **Branch** off `main`, named `-` (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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 005de91..907cf5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 `-` (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 `-` (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 @@ -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 #` 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. @@ -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