From 693c470a96d0e2888d09d60f2eddee8fad6404e7 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Sat, 18 Jul 2026 13:29:43 -0700 Subject: [PATCH 1/2] agents|fix: Name the branch deletion in the merge-pr approval ask Fixes an issue where merging a pull request that deletes the remote branch required a second authorization: the approval ask named only the merge, while the deletion appeared only in a metadata line the permission auto-classifier does not read. The ask now names the branch deletion it authorizes, so a single merge approval also covers the deletion. --- packages/agents/content/skills/merge-pr/SKILL.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/agents/content/skills/merge-pr/SKILL.md b/packages/agents/content/skills/merge-pr/SKILL.md index 793b3139..76fc7db6 100644 --- a/packages/agents/content/skills/merge-pr/SKILL.md +++ b/packages/agents/content/skills/merge-pr/SKILL.md @@ -40,7 +40,7 @@ gh pr view {pr} --json number,title,body,labels,headRefName,baseRefName,url If no PR can be resolved or discovered, stop with: "No open PR found for branch `{branch_name}`. Create one with `{skill:create-pr}` first." -Capture `title` (PR title), `body` (PR body), `labels` (label objects), and `number` from the response. These feed the steps below. +Capture `title` (PR title), `body` (PR body), `labels` (label objects), `number`, and `headRefName` (head branch) from the response. These feed the steps below. ### 3. Resolve scope and type @@ -144,10 +144,16 @@ Proposed merge for PR #{pr_number}: {body} β–² -Proceed with merge? πŸ‘πŸΌπŸ‘ŽπŸΌ +{confirmation} ``` -The triangle delimiters wrap the title and body β€” the parts that will actually be published. Append any additional context (CI status, branch fate, repo-specific commentary) between the closing `β–²` and the `Proceed with merge?` line, outside the delimited region. Everything outside the triangles is metadata for the user's decision. +The triangle delimiters wrap the title and body β€” the parts that will actually be published. Append any additional context (CI status, branch fate, repo-specific commentary) between the closing `β–²` and the `{confirmation}` line, outside the delimited region. Everything outside the triangles is metadata for the user's decision. + +Render `{confirmation}` so the ask itself names every destructive side effect the approval authorizes. The permission auto-classifier grants only what the ask text names, so a branch deletion shown only in the `Delete:` line above is not authorized β€” the ask must name it too: + +- `none` β†’ `Merge PR #{pr_number}? πŸ‘πŸΌπŸ‘ŽπŸΌ` +- `remote` β†’ `Merge PR #{pr_number} and delete the remote branch {headRefName}? πŸ‘πŸΌπŸ‘ŽπŸΌ` +- `both` β†’ `Merge PR #{pr_number} and delete the local and remote branch {headRefName}? πŸ‘πŸΌπŸ‘ŽπŸΌ` If the user declines, stop with no API call and no artifact. If they approve, continue. From 5a6711154da7f55f3a9760d4ac4af7bae34b8449 Mon Sep 17 00:00:00 2001 From: William Thorsen Date: Sat, 18 Jul 2026 13:31:33 -0700 Subject: [PATCH 2/2] agents|feat: Require asks to name the side effects they authorize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Asks that authorize a consequential, hard-to-reverse side effect β€” deleting a remote branch, force-pushing, closing an issue β€” must now name that side effect in the ask text, not only in metadata shown beside it. Consent extends only to what an ask names, for a human reader and equally for a permission auto-classifier that reads the ask text alone, so a side effect present only in adjacent metadata is left unauthorized. --- packages/agents/content/skills/_data/action-items.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/agents/content/skills/_data/action-items.md b/packages/agents/content/skills/_data/action-items.md index 6d9c7a73..8af4622c 100644 --- a/packages/agents/content/skills/_data/action-items.md +++ b/packages/agents/content/skills/_data/action-items.md @@ -30,6 +30,8 @@ An item is a question, punctuated as one, naming the concrete action: - **Not this:** "Should I do something about the trap?" β€” vague. The user cannot answer without first asking what you mean. - **Not this:** "Add the packaging note to #977." β€” declarative. It reads as a statement of what you are about to do, and pre-empts the decision that is the user's to make. +**Naming side effects.** An ask that authorizes a consequential, hard-to-reverse side effect β€” deleting a remote branch, force-pushing, closing an issue β€” must name it in the ask text, not only in metadata beside it. Consent extends only to what the ask names β€” for the human, and for a permission auto-classifier, which reads the ask text and nothing around it. + ### Kinds | Prefix | Kind | Marker |