Skip to content

docs(skills): maintainer-driven tool actions and duplicate-cluster resolution - #970

Open
castrojo wants to merge 3 commits into
mainfrom
pr-review-cluster-doctrine
Open

docs(skills): maintainer-driven tool actions and duplicate-cluster resolution#970
castrojo wants to merge 3 commits into
mainfrom
pr-review-cluster-doctrine

Conversation

@castrojo

@castrojo castrojo commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Why

Downstream in projectbluefin/review, the maintainer's PR-walk tool (bluefin-review queue) detects duplicate clusters but could not act on them: a local test banned pr merge outright — stricter than the doctrine it implements. The ambiguity sat here: human-gates said "agents never self-merge" without distinguishing a tool executing the maintainer's explicit keypress, and pr-review had competing-pair detection with no cluster resolution verb.

What changes

  • human-gates.md (1.1): the Merge Gate now distinguishes agent self-merge (never) from a tool executing the maintainer's explicit per-item keypress with rulesets still enforced (the documented human-decides loop). --admin, submitting reviews, and non-interactive batch mutation stay forbidden for any tool.
  • pr-review/SKILL.md (3.5): new "Duplicate-cluster resolution" subsection — survivor from diff evidence, arm the survivor first with --match-head-commit, comment before close, never --reason "not planned", linked-issue re-check, halt on first failure. Compressed to fit the 500-line hard cap (exactly 500; one stray blank line reclaimed).

Design memo driving this: projectbluefin/review session artifact, org review walk design (§0, §4, §9).

Validation

check-skill-frontmatter.sh exit 0 (500/500, warnings pre-existing), generate_skill_index.py --write + check-skill-index.sh clean.

Assisted-by: Claude Opus 4.8 via GitHub Copilot
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

@castrojo
castrojo requested review from a team and repires as code owners August 8, 2026 22:48
@castrojo
castrojo enabled auto-merge August 8, 2026 22:55

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. The carve-out is correctly bounded and the duplicate-cluster procedure is careful in the places that matter.

On the human-gates amendment. The distinction it draws is the right one — the concern behind "agents never self-merge" is unreviewed change reaching a protected branch, not the mechanical identity of the process invoking the API. A per-item maintainer decision with rulesets still enforced server-side doesn't create that risk. Retaining the three hard prohibitions is what makes it safe to state:

  • no --admin (the only one that actually bypasses protection)
  • no submitting an approving review (an agent must never manufacture the approval it then acts on — this is the load-bearing one)
  • no non-interactive batch mutation (preserves per-item intent)

--match-head-commit <sha> with the SHA read live is the best detail in here. Converting "the branch moved under us" from a race into a server-side refusal is exactly right, and it's the kind of thing that's easy to omit and impossible to notice until it bites.

Also correct: --body-file rather than --body with prose through a shell, and "a still-open issue with no remaining open PR is a finding to report, not something to silently fix." The latter keeps the agent from quietly papering over a state the human should see.


One gap I'd like addressed in the text: --auto is a deferred action, and the amendment's justification doesn't cover it.

The new human-gates paragraph rests on "the maintainer's explicit per-item keypress." But step (2) arms gh pr merge <S> --squash --auto, which lands the merge at some later point once checks pass — possibly minutes or hours after the keypress, unattended. That's still legitimate, but it isn't the same thing as the human pressing a key and the merge happening; it's the human pre-authorizing a conditional future merge.

--match-head-commit covers the obvious drift (a new push to the head), but not everything that can change between authorization and landing — the base branch advancing, a required check being reconfigured, or the superseded PRs in the cluster being reopened. Worth saying explicitly in human-gates.md that deferred/auto-merge is in scope for this carve-out and why the head-SHA pin is considered sufficient. Right now a reader could reasonably conclude auto-merge falls under "non-interactive batch mutation" and is forbidden, which contradicts the procedure in pr-review/SKILL.md. Since these two files are meant to be read together, that ambiguity is worth closing.

Minor: the ordering in the cluster procedure — arm survivor (2), then close superseded (3–4) — is the safe direction, since a failure mid-sequence leaves duplicates open rather than everything closed with nothing landing. Worth stating that rationale inline; "halting on the first failure" says what but not why this order, and the next editor might reasonably swap them to "clean up first."

Housekeeping: currently DIRTY against main — needs a rebase. Since index.json / index.md are generated by scripts/generate_skill_index.py, regenerate rather than hand-resolve those two if the conflict lands there.

…solution

human-gates: the Merge Gate binds agents, not the maintainer's own hands.
A review tool that executes a merge or close only on the maintainer's
explicit per-item keypress, with rulesets still enforced by GitHub, is the
human acting at the gate; --admin overrides, submitting reviews, and
non-interactive batch mutation remain forbidden for any tool. This
ambiguity had already produced a walker stricter than the doctrine it
implements.

pr-review: competing-pair detection could find a duplicate cluster but had
no verb for resolving it. Add the ordered procedure: survivor from diff
evidence, arm the survivor first with --match-head-commit, comment before
close, never 'not planned', then the linked-issue re-check — halting on
the first failure.

Assisted-by: Claude Opus 4.8 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo
castrojo force-pushed the pr-review-cluster-doctrine branch from 3dfa623 to 78a7c62 Compare September 7, 2026 01:32
Require human confirmation that a cluster is truly duplicate, preserve complementary PRs, and gate each merge, comment, and close action individually. Forbid batch closure so the documented maintainer tool cannot infer or automate destructive actions.

Assisted-by: GPT-5.6 Luna via GitHub Copilot

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically the cleanest PR in this queue — but the human-gates.md paragraph is a policy change, not a docs change

Verified against current main:

  • merges clean, validate green
  • python3 scripts/generate_skill_index.py --checkdocs/skills/index.json and index.md are up to date (40 skills) — the index is properly regenerated here (2026-08-182026-09-06, moving forward, 40 skills preserved, with the matching version/last_updated bumps for human-gates and pr-review). Several other open docs PRs in this queue regress that file backwards; this one is the correct pattern.
  • python3 scripts/check-doc-links.sh → exit 0, so the new references/duplicate-cluster.md link from pr-review/SKILL.md resolves
  • bash scripts/check-skill-frontmatter.sh → only the pre-existing brew-lifecycle/SKILL.md is 208 lines (soft max 200) warning, unchanged from main
  • python3 -m pytest tests/test_skill_docs.py → 10 passed
  • nothing under system_files/, so no bluefin / bluefin-lts / dakota blast radius

The duplicate-cluster half is uncontroversial and, judging by this queue, needed — #942 is superseded by merged #1020, #1018 duplicates a bluespeed recipe already on main, and #1080/#1073 are a dependent pair. "Arm the survivor before closing the rest" is exactly the right ordering.

The part that deserves a deliberate yes, not a skim

The human-gates.md addition materially loosens the Merge gate:

This gate binds agents, not the maintainer's own hands. A review tool that executes a merge or close only on the maintainer's explicit per-item keypress — with rulesets and branch protection still enforced by GitHub — is the human acting at the gate, not an agent self-merging.

Read narrowly this is obviously true: a maintainer pressing a key per item is a human decision. But it is being written into the document that defines what agents may not do, and the load-bearing words are all in the carve-out — "explicit", "per-item", "keypress". Two questions worth answering in the thread before this merges, because after it merges this paragraph is what future agents will cite:

  1. What enforces "per-item"? The prohibition list that follows forbids "non-interactive batch mutation", but nothing here distinguishes fifteen individually-confirmed keypresses from a fifteen-item confirm-all prompt that is technically per-item. If pr-review's card loop is the intended vehicle, saying so by name would bound this to the reviewed implementation rather than to any tool that claims a keypress.
  2. Does "close" carry the same weight as "merge"? Merge is gated by branch protection and rulesets, as the paragraph notes. Close is not — GitHub enforces nothing, so a mis-keyed close is unprotected by anything except the human's attention. The roadmap in #1073 separately proposes auto-closing superseded agent PRs, which is the same authority with the keypress removed. Worth being explicit that the carve-out covers keypress-confirmed close only, so #1073's item 5 cannot lean on this paragraph.

Neither is a defect in the diff; both are about how narrowly this reads in six months. If the answers are "the pr-review card loop, one keypress per card, close included and auto-close excluded", then saying that in the text makes this a clean merge from my side.


Generated by Claude Code

Address hanthor's review on #970 in the text of human-gates.md:

- Name the reviewed vehicle: the pr-review card loop, one keypress per
  card, never a confirm-all prompt spanning items.
- State that close carries the same weight as merge: the carve-out covers
  keypress-confirmed closes only, so an auto-close without a per-item
  keypress (e.g. the obsolescence remedy proposed in #1073) cannot lean
  on this paragraph.
- State that arming auto-merge on the keypress is the same decision
  deferred until checks pass, in scope only with --match-head-commit
  pinning the reviewed head so drift fails server-side.

human-gates 1.1 -> 1.2; index.json/index.md regenerated with
scripts/generate_skill_index.py --write. check-skill-frontmatter.sh,
generate_skill_index.py --check, check-doc-links.sh, and
tests/test_skill_docs.py (10 passed) all green.

Assisted-by: Kimi K3 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
castrojo pushed a commit that referenced this pull request Sep 12, 2026
Address hanthor's review on #1073: Phase 0 item 5 read as adopted
intent to auto-close agent PRs, an agent mutation of human-visible
state that conflicts with docs/skills/human-gates.md. Rephrase to
detect-and-flag: detection is automated, the close itself requires a
per-item human keypress, matching the carve-out #970 negotiates.

The proposal content (adopt the remedy at all) remains a maintainer
decision; this change only removes the doctrine conflict from the text.

Assisted-by: Kimi K3 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo
castrojo disabled auto-merge September 12, 2026 12:34
@castrojo
castrojo enabled auto-merge September 12, 2026 12:35
@castrojo
castrojo requested a review from ahmedadan September 12, 2026 12:37
@castrojo

Copy link
Copy Markdown
Contributor Author

K3 final batch audit (970/1000/1073/1080 cohort) — 970 verified and armed for landing.

Verified against current main (56d81ef):

State: hanthor's approval stands (1 of 2 required by the main — merge queue ruleset). This PR is castrojo-authored, so the batch reviewer's castrojo-token approval cannot count here — a second human maintainer approval is needed (ahmedadan / repires requested). Auto-merge is armed; it enters the squash merge queue automatically once the second approval lands.

@castrojo castrojo added the lgtm This PR has been approved by a maintainer label Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants