From 893b039a3a1441772f4a6848e1fb4a971d54fd34 Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Sat, 26 Sep 2026 19:46:32 +0100 Subject: [PATCH 1/6] docs(runbooks): add a pull-request runbook (#668) Branch naming, opening, the ADR-0026 review gate including the maintainer-elected fallback decided on #664, merge, and post-merge steps, in one place for humans and agents, with each rule pointing at the ADR or workflow that owns it. Declared in the instruction manifest. Refs #668 --- .github/instruction-surfaces.json | 12 ++++++++ runbooks/pull-requests.md | 51 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 runbooks/pull-requests.md diff --git a/.github/instruction-surfaces.json b/.github/instruction-surfaces.json index 34f798077..881404fee 100644 --- a/.github/instruction-surfaces.json +++ b/.github/instruction-surfaces.json @@ -650,6 +650,18 @@ "review_owner": "z-shell maintainers", "canonical_for": ["worktree-management-procedure"] }, + { + "id": "runbook-pull-requests", + "path": "runbooks/pull-requests.md", + "kind": "runbook", + "authority": "canonical-detail", + "consumers": ["codex", "claude-code", "copilot", "gemini-cli", "human"], + "tasks": ["pull-request", "code-review", "github-operations"], + "file_patterns": ["**"], + "required": true, + "review_owner": "z-shell maintainers", + "canonical_for": ["pull-request-lifecycle"] + }, { "id": "runbook-triage", "path": "runbooks/triage.md", diff --git a/runbooks/pull-requests.md b/runbooks/pull-requests.md new file mode 100644 index 000000000..3a0f9648a --- /dev/null +++ b/runbooks/pull-requests.md @@ -0,0 +1,51 @@ +# Runbook: Pull requests + +Use this runbook for every pull request to a z-shell repository, whoever opens it: a maintainer, a contributor, or an agent. It collects in one place the steps that are otherwise spread across `AGENTS.md`, [ADR-0003](../decisions/0003-conventional-commits.md), [ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md), [ADR-0026](../decisions/0026-review-triggers-and-fallback.md), [`branch-protection.md`](branch-protection.md), and `.github/workflows/commit-lint.yml`. Where this runbook and one of those disagree, the ADR or the workflow wins; fix the runbook. + +## 1. Before the branch + +- Read the owning issue and its acceptance criteria. The pull request is measured against them. +- Name the branch before creating it. The pattern is the `BRANCH_PATTERN` default in `.github/workflows/commit-lint.yml`: + - `feature-`, `bug-` or `hotfix-`, optionally followed by `-` (for example `bug-480` or `feature-668-pull-requests`); + - or `/` with a slash after a Conventional Commits type (for example `docs/pull-requests-runbook`). `docs-488` matches neither and fails the required check. +- A repository may be stricter; its `AGENTS.md` says so (z-shell/F-Sy-H accepts only `feature|bug|hotfix-`). +- Branch from the repository's base: `main`, except `next` for z-shell/zi ([ADR-0019](../decisions/0019-trunk-on-main-default.md), [`branch-protection.md`](branch-protection.md)). + +## 2. Opening + +- Title and commits follow Conventional Commits ([ADR-0003](../decisions/0003-conventional-commits.md)): `type(scope): description`, with the description at most 72 characters, including an issue suffix such as `(#123)`. +- Fill in the repository's pull-request template (the organization default is Summary, Verification, Agent handoff). +- Reference the owning issue in the body ([ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md)). Use `Closes #N` only when this diff meets every acceptance criterion of #N. Otherwise use `Refs #N`, say which criteria remain, and open or update a follow-up issue. +- When the change departs from what the issue asked for, say so in the body and get the maintainer's agreement before merging. A departure hidden behind `Closes` closes the issue on criteria nobody agreed to. +- Every factual or causal claim in the change and the body is checked, or marked as not yet verified. +- Run the repository's own checks before asking for review, and put the commands and their results under Verification. + +## 3. Review + +Reviews follow [ADR-0026](../decisions/0026-review-triggers-and-fallback.md). + +1. When the head is ready (checks green, body complete), request Copilot once. Confirm the request by a `review_requested` event on the pull request's timeline. An empty `requested_reviewers` list in the API response means the request did not register. +2. If the request does not register, a class 2, 3 or 4 repository may use the fallback (`lib/repository-classes.yml`). Run `.github/skills/code-review/SKILL.md` against `.github/instructions/code-review-generic.instructions.md` on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. +3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on #664; the ADR-0026 amendment is pending. +4. Class 1 repositories never use the fallback: they wait for Copilot or a second human. +5. Any push after a review, a rebase included, voids it for the merge gate. Request again, or post a new fallback, on the new head. +6. Act on every review thread with a fix, or a reply saying why not. The ruleset requires resolved threads (`required_review_thread_resolution`, [ADR-0013](../decisions/0013-repository-settings-baseline.md)). + +## 4. Merge + +- All required checks pass on the head, the review of record covers that same head, and no thread is unresolved. +- Topic branches squash-merge. Persistent-branch promotion uses a merge commit ([`branch-protection.md`](branch-protection.md)). Pass `--match-head-commit ` so a push between checking and merging fails the merge. +- For a squash merge, pass the message explicitly and check it, as [`branch-protection.md`](branch-protection.md) describes for trailers. +- When the body says `Closes #N`, re-check the criteria against the merged diff. If one is not met, reopen #N or open a follow-up at once. + +## 5. After merge + +- Move the Project 28 item as [`project-tracker.md`](project-tracker.md) describes. +- File the follow-ups promised in the body or in review replies, and link them. +- Delete the branch and any local worktree only with the maintainer's authorization. + +## See also + +- [`triage.md`](triage.md), for the issue a pull request starts from. +- [`learning-capture.md`](learning-capture.md), for lessons a pull request teaches. +- #668, for why this runbook exists. From f0a25d52dd8b538432a06e8c75718c7c383f86b6 Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Sat, 26 Sep 2026 20:55:13 +0100 Subject: [PATCH 2/6] docs(runbooks): align PR runbook review steps with ADR-0026 (#668) Require a maintainer decision before the not-registered fallback, limit push voiding to fallback reviews and restore the two-round cap, keep merge commits for zi hotfix synchronization, name #664 as an interim exception to ADR precedence, cover zi hotfix bases and issue closing at promotion, and add the automation-only diff exemption from ADR-0026 decision 4. --- runbooks/pull-requests.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/runbooks/pull-requests.md b/runbooks/pull-requests.md index 3a0f9648a..58733dd4b 100644 --- a/runbooks/pull-requests.md +++ b/runbooks/pull-requests.md @@ -1,6 +1,6 @@ # Runbook: Pull requests -Use this runbook for every pull request to a z-shell repository, whoever opens it: a maintainer, a contributor, or an agent. It collects in one place the steps that are otherwise spread across `AGENTS.md`, [ADR-0003](../decisions/0003-conventional-commits.md), [ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md), [ADR-0026](../decisions/0026-review-triggers-and-fallback.md), [`branch-protection.md`](branch-protection.md), and `.github/workflows/commit-lint.yml`. Where this runbook and one of those disagree, the ADR or the workflow wins; fix the runbook. +Use this runbook for every pull request to a z-shell repository, whoever opens it: a maintainer, a contributor, or an agent. It collects in one place the steps that are otherwise spread across `AGENTS.md`, [ADR-0003](../decisions/0003-conventional-commits.md), [ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md), [ADR-0026](../decisions/0026-review-triggers-and-fallback.md), [`branch-protection.md`](branch-protection.md), and `.github/workflows/commit-lint.yml`. Where this runbook and one of those disagree, the ADR or the workflow wins; fix the runbook. One interim exception: until the ADR-0026 amendment lands, the maintainer decision recorded on [#664](https://github.com/z-shell/.github/issues/664) also governs fallback reviews, and section 3 follows it where it extends ADR-0026. ## 1. Before the branch @@ -9,7 +9,7 @@ Use this runbook for every pull request to a z-shell repository, whoever opens i - `feature-`, `bug-` or `hotfix-`, optionally followed by `-` (for example `bug-480` or `feature-668-pull-requests`); - or `/` with a slash after a Conventional Commits type (for example `docs/pull-requests-runbook`). `docs-488` matches neither and fails the required check. - A repository may be stricter; its `AGENTS.md` says so (z-shell/F-Sy-H accepts only `feature|bug|hotfix-`). -- Branch from the repository's base: `main`, except `next` for z-shell/zi ([ADR-0019](../decisions/0019-trunk-on-main-default.md), [`branch-protection.md`](branch-protection.md)). +- Branch from the repository's base: `main`, except `next` for z-shell/zi ([ADR-0019](../decisions/0019-trunk-on-main-default.md), [`branch-protection.md`](branch-protection.md)). In zi a `hotfix-*` branch may start from and target `main`, and is then synchronized into `next` as [`branch-protection.md`](branch-protection.md) describes. ## 2. Opening @@ -24,19 +24,23 @@ Use this runbook for every pull request to a z-shell repository, whoever opens i Reviews follow [ADR-0026](../decisions/0026-review-triggers-and-fallback.md). +A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4): gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips the steps below. A pull request that touches anything else is reviewed. + 1. When the head is ready (checks green, body complete), request Copilot once. Confirm the request by a `review_requested` event on the pull request's timeline. An empty `requested_reviewers` list in the API response means the request did not register. -2. If the request does not register, a class 2, 3 or 4 repository may use the fallback (`lib/repository-classes.yml`). Run `.github/skills/code-review/SKILL.md` against `.github/instructions/code-review-generic.instructions.md` on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. +2. If the request does not register, the pull request is blocked on quota, not ready. In a class 2, 3 or 4 repository (`lib/repository-classes.yml`) the maintainer may then decide to use the fallback instead of waiting; an agent does not take that decision on its own. Run `.github/skills/code-review/SKILL.md` against `.github/instructions/code-review-generic.instructions.md` on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. 3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on #664; the ADR-0026 amendment is pending. 4. Class 1 repositories never use the fallback: they wait for Copilot or a second human. -5. Any push after a review, a rebase included, voids it for the merge gate. Request again, or post a new fallback, on the new head. -6. Act on every review thread with a fix, or a reply saying why not. The ruleset requires resolved threads (`required_review_thread_resolution`, [ADR-0013](../decisions/0013-repository-settings-baseline.md)). +5. Act on every review thread with a fix, or a reply saying why not. The ruleset requires resolved threads (`required_review_thread_resolution`, [ADR-0013](../decisions/0013-repository-settings-baseline.md)). +6. Batch the thread fixes and push them once before the next Copilot request; that is one round. After the second round in which Copilot raises only implementation-level or wording findings, the maintainer decides whether to defer the rest to an issue instead of requesting a third review. +7. Any push after a fallback review, a rebase included, voids it (#664). Post a new fallback review on the new head before merging. ## 4. Merge -- All required checks pass on the head, the review of record covers that same head, and no thread is unresolved. -- Topic branches squash-merge. Persistent-branch promotion uses a merge commit ([`branch-protection.md`](branch-protection.md)). Pass `--match-head-commit ` so a push between checking and merging fails the merge. +- All required checks pass on the head, a review of record has posted, and no thread is unresolved. A fallback review of record must be on that same head (section 3, step 7). +- Short-lived topic branches usually squash-merge. Persistent-branch promotion, and a zi hotfix synchronization branch that carries a merge commit of `main` into `next`, use a merge commit so the ancestry survives ([`branch-protection.md`](branch-protection.md)). Pass `--match-head-commit ` so a push between checking and merging fails the merge. - For a squash merge, pass the message explicitly and check it, as [`branch-protection.md`](branch-protection.md) describes for trailers. - When the body says `Closes #N`, re-check the criteria against the merged diff. If one is not met, reopen #N or open a follow-up at once. +- In zi, a pull request merged into `next` leaves its issue open, because GitHub closes issues only from the default branch. Close those issues by hand when `next` is promoted to `main`, not earlier (zi's `AGENTS.md`). ## 5. After merge From 081938a73ed452c3b1024d9f33d9ec6639594529 Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:06:43 +0100 Subject: [PATCH 3/6] docs(runbooks): resolve fallback review findings on PR runbook (#668) Require merge commits for every zi pull request into main, exempt declared automation-only diffs from the merge-gate review, add the meta:no-issue path, cite commit-lint.yml for the 72-character limit, match the branch regex (lowercase slugs, feature/bug/hotfix slash form), point stricter repositories at the branch-pattern input, restore the ADR-0026 decision 4 condition, name the Copilot reviewer and scope it to where configured, describe Project 28 as automatic, and link cross-repository references. --- runbooks/pull-requests.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/runbooks/pull-requests.md b/runbooks/pull-requests.md index 58733dd4b..72950db9b 100644 --- a/runbooks/pull-requests.md +++ b/runbooks/pull-requests.md @@ -6,16 +6,16 @@ Use this runbook for every pull request to a z-shell repository, whoever opens i - Read the owning issue and its acceptance criteria. The pull request is measured against them. - Name the branch before creating it. The pattern is the `BRANCH_PATTERN` default in `.github/workflows/commit-lint.yml`: - - `feature-`, `bug-` or `hotfix-`, optionally followed by `-` (for example `bug-480` or `feature-668-pull-requests`); - - or `/` with a slash after a Conventional Commits type (for example `docs/pull-requests-runbook`). `docs-488` matches neither and fails the required check. -- A repository may be stricter; its `AGENTS.md` says so (z-shell/F-Sy-H accepts only `feature|bug|hotfix-`). -- Branch from the repository's base: `main`, except `next` for z-shell/zi ([ADR-0019](../decisions/0019-trunk-on-main-default.md), [`branch-protection.md`](branch-protection.md)). In zi a `hotfix-*` branch may start from and target `main`, and is then synchronized into `next` as [`branch-protection.md`](branch-protection.md) describes. + - `feature-`, `bug-` or `hotfix-`, optionally followed by a lowercase `-` (for example `bug-480` or `feature-668-pull-requests`); + - or `/` with a slash after a Conventional Commits type, or `feature`, `bug` or `hotfix` (for example `docs/pull-requests-runbook`). `docs-488` matches neither and fails the required check. +- A repository may be stricter through the `branch-pattern` input of its commit-lint caller (z-shell/F-Sy-H accepts only `feature|bug|hotfix-`, with no slug). +- Branch from the repository's base: `main`, except `next` for z-shell/zi ([ADR-0019](../decisions/0019-trunk-on-main-default.md), [`branch-protection.md`](branch-protection.md)). In zi a `hotfix-*` branch may start from and target `main`, must pass zi's main-branch source guard, and is then synchronized into `next` as [`branch-protection.md`](branch-protection.md) describes. ## 2. Opening -- Title and commits follow Conventional Commits ([ADR-0003](../decisions/0003-conventional-commits.md)): `type(scope): description`, with the description at most 72 characters, including an issue suffix such as `(#123)`. +- Title and commits follow Conventional Commits ([ADR-0003](../decisions/0003-conventional-commits.md)): `type(scope): description`. `.github/workflows/commit-lint.yml` limits the description to 72 characters, including an issue suffix such as `(#123)`. - Fill in the repository's pull-request template (the organization default is Summary, Verification, Agent handoff). -- Reference the owning issue in the body ([ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md)). Use `Closes #N` only when this diff meets every acceptance criterion of #N. Otherwise use `Refs #N`, say which criteria remain, and open or update a follow-up issue. +- Reference the owning issue in the body ([ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md)). Use `Closes #N` only when this diff meets every acceptance criterion of #N. Otherwise use `Refs #N`, say which criteria remain, and open or update a follow-up issue. When no issue owns the work, such as gitlink reconciliation, a maintainer (not an agent) applies the `meta:no-issue` label instead. - When the change departs from what the issue asked for, say so in the body and get the maintainer's agreement before merging. A departure hidden behind `Closes` closes the issue on criteria nobody agreed to. - Every factual or causal claim in the change and the body is checked, or marked as not yet verified. - Run the repository's own checks before asking for review, and put the commands and their results under Verification. @@ -24,27 +24,27 @@ Use this runbook for every pull request to a z-shell repository, whoever opens i Reviews follow [ADR-0026](../decisions/0026-review-triggers-and-fallback.md). -A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4): gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips the steps below. A pull request that touches anything else is reviewed. +A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4), limited to changes a machine produced and CI validates in full: gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips the steps below. A pull request that touches anything else is reviewed. -1. When the head is ready (checks green, body complete), request Copilot once. Confirm the request by a `review_requested` event on the pull request's timeline. An empty `requested_reviewers` list in the API response means the request did not register. +1. When the head is ready (checks green, body complete) and Copilot review is configured for the repository, request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline. An empty `requested_reviewers` list in the API response means the request did not register. 2. If the request does not register, the pull request is blocked on quota, not ready. In a class 2, 3 or 4 repository (`lib/repository-classes.yml`) the maintainer may then decide to use the fallback instead of waiting; an agent does not take that decision on its own. Run `.github/skills/code-review/SKILL.md` against `.github/instructions/code-review-generic.instructions.md` on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. -3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on #664; the ADR-0026 amendment is pending. +3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664); the ADR-0026 amendment is pending. 4. Class 1 repositories never use the fallback: they wait for Copilot or a second human. 5. Act on every review thread with a fix, or a reply saying why not. The ruleset requires resolved threads (`required_review_thread_resolution`, [ADR-0013](../decisions/0013-repository-settings-baseline.md)). 6. Batch the thread fixes and push them once before the next Copilot request; that is one round. After the second round in which Copilot raises only implementation-level or wording findings, the maintainer decides whether to defer the rest to an issue instead of requesting a third review. -7. Any push after a fallback review, a rebase included, voids it (#664). Post a new fallback review on the new head before merging. +7. Any push after a fallback review, a rebase included, voids it ([z-shell/.github#664](https://github.com/z-shell/.github/issues/664)). Post a new fallback review on the new head before merging. ## 4. Merge -- All required checks pass on the head, a review of record has posted, and no thread is unresolved. A fallback review of record must be on that same head (section 3, step 7). -- Short-lived topic branches usually squash-merge. Persistent-branch promotion, and a zi hotfix synchronization branch that carries a merge commit of `main` into `next`, use a merge commit so the ancestry survives ([`branch-protection.md`](branch-protection.md)). Pass `--match-head-commit ` so a push between checking and merging fails the merge. +- All required checks pass on the head, a review of record has posted (unless the whole diff is a declared automation-only class, section 3), and no thread is unresolved. A fallback review of record must be on that same head (section 3, step 7). +- Short-lived topic branches usually squash-merge. Persistent-branch promotion, every zi pull request into `main` (a `hotfix-*` included, since zi's `main` ruleset allows only merge commits), and a zi hotfix synchronization branch that carries a merge commit of `main` into `next` use a merge commit, so the ancestry survives ([`branch-protection.md`](branch-protection.md)). Pass `--match-head-commit ` so a push between checking and merging fails the merge. - For a squash merge, pass the message explicitly and check it, as [`branch-protection.md`](branch-protection.md) describes for trailers. - When the body says `Closes #N`, re-check the criteria against the merged diff. If one is not met, reopen #N or open a follow-up at once. - In zi, a pull request merged into `next` leaves its issue open, because GitHub closes issues only from the default branch. Close those issues by hand when `next` is promoted to `main`, not earlier (zi's `AGENTS.md`). ## 5. After merge -- Move the Project 28 item as [`project-tracker.md`](project-tracker.md) describes. +- Confirm that Project 28's built-in workflow moved the item to `Done` ([`project-tracker.md`](project-tracker.md)). In zi the issue item stays open until promotion. - File the follow-ups promised in the body or in review replies, and link them. - Delete the branch and any local worktree only with the maintainer's authorization. @@ -52,4 +52,4 @@ A repository's `AGENTS.md` may declare automation-only diff classes that need no - [`triage.md`](triage.md), for the issue a pull request starts from. - [`learning-capture.md`](learning-capture.md), for lessons a pull request teaches. -- #668, for why this runbook exists. +- [z-shell/.github#668](https://github.com/z-shell/.github/issues/668), for why this runbook exists. From 6ce8aafaaaf757bb09ca3197e331490fdda5e76f Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:22:54 +0100 Subject: [PATCH 4/6] docs(runbooks): tighten Copilot confirmation and review of record (#668) Count only a review_requested event for Copilot as confirmation, demote the empty requested_reviewers list to an early sign, and name the review of record where Copilot is not configured: a human review or, in classes 2 to 4, a maintainer-elected fallback. Keep thread handling for exempt automation-only diffs, allow the instructions file from z-shell/.github, check Project 28 only when the merge closed the issue, require lowercase slash-form slugs, and link ADR-0032. --- runbooks/pull-requests.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/runbooks/pull-requests.md b/runbooks/pull-requests.md index 72950db9b..d93c1c19b 100644 --- a/runbooks/pull-requests.md +++ b/runbooks/pull-requests.md @@ -7,7 +7,7 @@ Use this runbook for every pull request to a z-shell repository, whoever opens i - Read the owning issue and its acceptance criteria. The pull request is measured against them. - Name the branch before creating it. The pattern is the `BRANCH_PATTERN` default in `.github/workflows/commit-lint.yml`: - `feature-`, `bug-` or `hotfix-`, optionally followed by a lowercase `-` (for example `bug-480` or `feature-668-pull-requests`); - - or `/` with a slash after a Conventional Commits type, or `feature`, `bug` or `hotfix` (for example `docs/pull-requests-runbook`). `docs-488` matches neither and fails the required check. + - or `/` with a slash after a Conventional Commits type, or `feature`, `bug` or `hotfix` (for example `docs/pull-requests-runbook`). `docs-488` matches neither and fails the required check. - A repository may be stricter through the `branch-pattern` input of its commit-lint caller (z-shell/F-Sy-H accepts only `feature|bug|hotfix-`, with no slug). - Branch from the repository's base: `main`, except `next` for z-shell/zi ([ADR-0019](../decisions/0019-trunk-on-main-default.md), [`branch-protection.md`](branch-protection.md)). In zi a `hotfix-*` branch may start from and target `main`, must pass zi's main-branch source guard, and is then synchronized into `next` as [`branch-protection.md`](branch-protection.md) describes. @@ -24,10 +24,10 @@ Use this runbook for every pull request to a z-shell repository, whoever opens i Reviews follow [ADR-0026](../decisions/0026-review-triggers-and-fallback.md). -A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4), limited to changes a machine produced and CI validates in full: gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips the steps below. A pull request that touches anything else is reviewed. +A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4), limited to changes a machine produced and CI validates in full: gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips steps 1 to 4, 6 and 7; any review thread that is opened on it is still handled under step 5. A pull request that touches anything else is reviewed. -1. When the head is ready (checks green, body complete) and Copilot review is configured for the repository, request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline. An empty `requested_reviewers` list in the API response means the request did not register. -2. If the request does not register, the pull request is blocked on quota, not ready. In a class 2, 3 or 4 repository (`lib/repository-classes.yml`) the maintainer may then decide to use the fallback instead of waiting; an agent does not take that decision on its own. Run `.github/skills/code-review/SKILL.md` against `.github/instructions/code-review-generic.instructions.md` on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. +1. When the head is ready (checks green, body complete) and Copilot review is configured for the repository, request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline whose requested reviewer is `Copilot` (the login the timeline shows for the bot); an event for a team or a user, such as a CODEOWNERS request, does not count. Copilot missing from `requested_reviewers` in the response to the request is an early sign that it did not register, not the test. Where Copilot review is not configured, the review of record is a human review or, in classes 2 to 4, a maintainer-elected fallback (step 3). +2. If the request does not register, the pull request is blocked on quota, not ready. In a class 2, 3 or 4 repository (`lib/repository-classes.yml`) the maintainer may then decide to use the fallback instead of waiting; an agent does not take that decision on its own. Run `.github/skills/code-review/SKILL.md` against `code-review-generic.instructions.md` (the repository's `.github/instructions/` copy, else the z-shell/.github one) on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. 3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664); the ADR-0026 amendment is pending. 4. Class 1 repositories never use the fallback: they wait for Copilot or a second human. 5. Act on every review thread with a fix, or a reply saying why not. The ruleset requires resolved threads (`required_review_thread_resolution`, [ADR-0013](../decisions/0013-repository-settings-baseline.md)). @@ -44,7 +44,7 @@ A repository's `AGENTS.md` may declare automation-only diff classes that need no ## 5. After merge -- Confirm that Project 28's built-in workflow moved the item to `Done` ([`project-tracker.md`](project-tracker.md)). In zi the issue item stays open until promotion. +- When the merge closed the issue, confirm that Project 28's built-in workflow moved its item to `Done` ([`project-tracker.md`](project-tracker.md)). In zi the issue item stays open until promotion. - File the follow-ups promised in the body or in review replies, and link them. - Delete the branch and any local worktree only with the maintainer's authorization. @@ -52,4 +52,5 @@ A repository's `AGENTS.md` may declare automation-only diff classes that need no - [`triage.md`](triage.md), for the issue a pull request starts from. - [`learning-capture.md`](learning-capture.md), for lessons a pull request teaches. +- [ADR-0032](../decisions/0032-organization-procedures-live-once-as-public-runbooks.md), for why procedures like this one live in runbooks. - [z-shell/.github#668](https://github.com/z-shell/.github/issues/668), for why this runbook exists. From dc9d3fa97a071a040a2ede3f1ee30c54c8067e55 Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:36:45 +0100 Subject: [PATCH 5/6] docs(runbooks): require a fresh Copilot event and cite the #664 rulings (#668) Count only a Copilot review_requested event created after the current request, so an earlier round's event cannot stand in for one that did not register. Cite the 2026-09-26 maintainer decision on #664 for the review of record where Copilot review is not configured, and widen the interim exception in the introduction to cover both #664 decisions. --- runbooks/pull-requests.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runbooks/pull-requests.md b/runbooks/pull-requests.md index d93c1c19b..892defa24 100644 --- a/runbooks/pull-requests.md +++ b/runbooks/pull-requests.md @@ -1,6 +1,6 @@ # Runbook: Pull requests -Use this runbook for every pull request to a z-shell repository, whoever opens it: a maintainer, a contributor, or an agent. It collects in one place the steps that are otherwise spread across `AGENTS.md`, [ADR-0003](../decisions/0003-conventional-commits.md), [ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md), [ADR-0026](../decisions/0026-review-triggers-and-fallback.md), [`branch-protection.md`](branch-protection.md), and `.github/workflows/commit-lint.yml`. Where this runbook and one of those disagree, the ADR or the workflow wins; fix the runbook. One interim exception: until the ADR-0026 amendment lands, the maintainer decision recorded on [#664](https://github.com/z-shell/.github/issues/664) also governs fallback reviews, and section 3 follows it where it extends ADR-0026. +Use this runbook for every pull request to a z-shell repository, whoever opens it: a maintainer, a contributor, or an agent. It collects in one place the steps that are otherwise spread across `AGENTS.md`, [ADR-0003](../decisions/0003-conventional-commits.md), [ADR-0022](../decisions/0022-issue-traceability-on-pull-requests.md), [ADR-0026](../decisions/0026-review-triggers-and-fallback.md), [`branch-protection.md`](branch-protection.md), and `.github/workflows/commit-lint.yml`. Where this runbook and one of those disagree, the ADR or the workflow wins; fix the runbook. One interim exception: until the ADR-0026 amendment lands, the maintainer decisions recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664) also govern reviews (a fallback elected up front, and the review of record where Copilot review is not configured), and section 3 follows them where they extend ADR-0026. ## 1. Before the branch @@ -26,7 +26,7 @@ Reviews follow [ADR-0026](../decisions/0026-review-triggers-and-fallback.md). A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4), limited to changes a machine produced and CI validates in full: gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips steps 1 to 4, 6 and 7; any review thread that is opened on it is still handled under step 5. A pull request that touches anything else is reviewed. -1. When the head is ready (checks green, body complete) and Copilot review is configured for the repository, request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline whose requested reviewer is `Copilot` (the login the timeline shows for the bot); an event for a team or a user, such as a CODEOWNERS request, does not count. Copilot missing from `requested_reviewers` in the response to the request is an early sign that it did not register, not the test. Where Copilot review is not configured, the review of record is a human review or, in classes 2 to 4, a maintainer-elected fallback (step 3). +1. When the head is ready (checks green, body complete) and Copilot review is configured for the repository, request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline, created after this request, whose requested reviewer is `Copilot` (the login the timeline shows for the bot); an event for a team or a user, such as a CODEOWNERS request, does not count. Copilot missing from `requested_reviewers` in the response to the request is an early sign that it did not register, not the test. Where Copilot review is not configured, the review of record is a human review or, in classes 2 to 4, a maintainer-elected fallback (step 3). This follows the maintainer decision of 2026-09-26 recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664); the ADR-0026 amendment is pending. 2. If the request does not register, the pull request is blocked on quota, not ready. In a class 2, 3 or 4 repository (`lib/repository-classes.yml`) the maintainer may then decide to use the fallback instead of waiting; an agent does not take that decision on its own. Run `.github/skills/code-review/SKILL.md` against `code-review-generic.instructions.md` (the repository's `.github/instructions/` copy, else the z-shell/.github one) on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. 3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664); the ADR-0026 amendment is pending. 4. Class 1 repositories never use the fallback: they wait for Copilot or a second human. From 1d7e3e94f78d43f583593d14ad35e539d53cf48a Mon Sep 17 00:00:00 2001 From: Sal <59910950+ss-o@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:47:28 +0100 Subject: [PATCH 6/6] docs(runbooks): scope the Copilot check to the base branch (#668) Decide whether Copilot review is configured from the ruleset of the pull request's base branch, as the #664 ruling does, so a zi pull request into next, which has no copilot_code_review rule, takes the no-Copilot path. Link the #664 comment that records the ruling. --- runbooks/pull-requests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runbooks/pull-requests.md b/runbooks/pull-requests.md index 892defa24..aaa6b244e 100644 --- a/runbooks/pull-requests.md +++ b/runbooks/pull-requests.md @@ -26,7 +26,7 @@ Reviews follow [ADR-0026](../decisions/0026-review-triggers-and-fallback.md). A repository's `AGENTS.md` may declare automation-only diff classes that need no review of record (ADR-0026 decision 4), limited to changes a machine produced and CI validates in full: gitlink pointer moves in a meta-workspace, the generated-fixture refreshes that go with them, and dependency bumps opened by Renovate or Dependabot. A pull request made only of a declared class skips steps 1 to 4, 6 and 7; any review thread that is opened on it is still handled under step 5. A pull request that touches anything else is reviewed. -1. When the head is ready (checks green, body complete) and Copilot review is configured for the repository, request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline, created after this request, whose requested reviewer is `Copilot` (the login the timeline shows for the bot); an event for a team or a user, such as a CODEOWNERS request, does not count. Copilot missing from `requested_reviewers` in the response to the request is an early sign that it did not register, not the test. Where Copilot review is not configured, the review of record is a human review or, in classes 2 to 4, a maintainer-elected fallback (step 3). This follows the maintainer decision of 2026-09-26 recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664); the ADR-0026 amendment is pending. +1. When the head is ready (checks green, body complete) and Copilot review is configured for the pull request's base branch (a `copilot_code_review` rule in the ruleset that governs it), request `copilot-pull-request-reviewer[bot]` once. Confirm the request by a `review_requested` event on the pull request's timeline, created after this request, whose requested reviewer is `Copilot` (the login the timeline shows for the bot); an event for a team or a user, such as a CODEOWNERS request, does not count. Copilot missing from `requested_reviewers` in the response to the request is an early sign that it did not register, not the test. Where the repository, or the pull request's base branch, has no Copilot review configured, the review of record is a human review or, in classes 2 to 4, a maintainer-elected fallback (step 3). This follows the maintainer decision of 2026-09-26 [recorded on z-shell/.github#664](https://github.com/z-shell/.github/issues/664#issuecomment-5849672588); the ADR-0026 amendment is pending. 2. If the request does not register, the pull request is blocked on quota, not ready. In a class 2, 3 or 4 repository (`lib/repository-classes.yml`) the maintainer may then decide to use the fallback instead of waiting; an agent does not take that decision on its own. Run `.github/skills/code-review/SKILL.md` against `code-review-generic.instructions.md` (the repository's `.github/instructions/` copy, else the z-shell/.github one) on the current head. Post the result as a pull-request review with inline threads for its findings, opening with `Fallback review under ADR-0026: Copilot request not registered on `. The marker line without that review is not a review. 3. A maintainer may elect the fallback up front, without requesting Copilot, in classes 2 to 4. The review then opens with `Fallback review under ADR-0026: maintainer elected, no Copilot request on ` and is executed the same way. This follows the maintainer decision recorded on [z-shell/.github#664](https://github.com/z-shell/.github/issues/664); the ADR-0026 amendment is pending. 4. Class 1 repositories never use the fallback: they wait for Copilot or a second human.