From c227a1d1faa2c868352b756fa15e54a593c60ca7 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 7 Oct 2026 23:47:01 +0000 Subject: [PATCH 1/3] Skill: merge claude/* PRs myself once CI passes, no GitHub auto-merge Renames auto-merge to merge-after-ci. Subscribe to the PR, merge it (merge commit, pinned to the head SHA) when check has passed and the PR is clean with no changes requested, and stay silent. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_014k4kywyN5dAo39izUPvxbw --- .claude/skills/auto-merge/SKILL.md | 32 -------------------------- .claude/skills/merge-after-ci/SKILL.md | 32 ++++++++++++++++++++++++++ CLAUDE.md | 5 ++-- 3 files changed, 34 insertions(+), 35 deletions(-) delete mode 100644 .claude/skills/auto-merge/SKILL.md create mode 100644 .claude/skills/merge-after-ci/SKILL.md diff --git a/.claude/skills/auto-merge/SKILL.md b/.claude/skills/auto-merge/SKILL.md deleted file mode 100644 index cd857dc..0000000 --- a/.claude/skills/auto-merge/SKILL.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: auto-merge -description: After opening or being handed a pull request from a claude/* branch, turn on GitHub auto-merge so it merges when CI completes, and stay silent about it. Use whenever a PR is created, or when asked to auto-merge. Never merges anything that is not from a claude/* branch in this repo. ---- - -# Auto-merge when CI completes - -Use the GitHub MCP tools (`mcp__github__*`), never `gh`. **No chatter**: do not report PR status, CI progress, subscriptions -or merges, and do not answer PR events (opened, checks finished, merged, subscription notices). Speak only for the cases under -"Say something" below, in one line. - -## When -Right after a PR is opened from this session, or when a `claude/*` PR is pointed out to you. - -## Eligible PRs -Open, not a draft, head branch starts with `claude/` in this same repo, base is the default branch. Anything else: do nothing. - -## Steps -1. `enable_pr_auto_merge` with `mergeMethod: MERGE`. GitHub then merges it itself once the required `check` passes. Done: say nothing. -2. If that fails because the PR is already mergeable and the `check` run is already completed and successful - (`pull_request_read` `get_check_runs`), merge it now with `merge_pull_request`, `merge_method: merge`, and - `expectedHeadSha` set to the head SHA you just read. Say nothing. -3. Do not subscribe to the PR, and do not unsubscribe or comment. The user watches CI in the Claude Code CI button. - -## Say something (one line each) -- Auto-merge could not be enabled for any other reason (for example "Allow auto-merge" is off in the repo settings). -- CI failed and you cannot fix it, or the PR conflicts with `main` and the conflict is not a plain merge. - -## Never -- Merge or enable auto-merge on a PR from another branch, a fork, a draft, or one whose checks have failed or are missing. -- Skip, disable or re-run tests to get green; force-push; approve reviews; close PRs; delete branches. -- Turn auto-merge off for a PR the user switched it on for. diff --git a/.claude/skills/merge-after-ci/SKILL.md b/.claude/skills/merge-after-ci/SKILL.md new file mode 100644 index 0000000..f8cb0bd --- /dev/null +++ b/.claude/skills/merge-after-ci/SKILL.md @@ -0,0 +1,32 @@ +--- +name: merge-after-ci +description: Merge pull requests from claude/* branches yourself once their CI passes, silently. Use right after opening a PR, when a claude/* PR is pointed out, or when a CI-finished event arrives for one. Never merges anything that is not from a claude/* branch in this repo, and never uses GitHub's own auto-merge. +--- + +# Merge after CI passes + +Use the GitHub MCP tools (`mcp__github__*`), never `gh`. **No chatter**: do not report PR status, CI progress, subscriptions +or merges, and do not answer PR events (opened, checks finished, merged, subscription notices). Speak only for the cases under +"Say something" below, in one line. + +## Which PRs +Open, not a draft, head branch starts with `claude/` in this same repo, base is the default branch. Anything else: do nothing. + +## Steps +1. Right after a PR is opened (or when one is pointed out), subscribe to it (`subscribe_pr_activity`) so you hear when CI completes. +2. When its `check` finishes (a `check_suite.completed` event) or if CI is already done, read the PR fresh from GitHub: + `pull_request_read` `get`, `get_check_runs`, `get_reviews`, `get_review_comments`. Never rely on earlier results. +3. Merge only if ALL hold: `mergeable_state` is `clean`; every check run is `completed` with conclusion `success`; no review + is `CHANGES_REQUESTED`; no unresolved review thread. Then call `merge_pull_request` with `merge_method: merge` and + `expectedHeadSha` set to the head SHA you just read (a push that lands in between aborts the merge). Say nothing. +4. CI still running: do nothing and wait for the next event. CI red: fix it if the fix is small and yours, push, and wait again. +5. After the merge the subscription ends by itself. + +## Say something (one line each) +- CI failed and you cannot fix it, or the PR conflicts with `main` and the conflict is not a plain merge. +- A review asks for changes you cannot make on your own. + +## Never +- Enable or use GitHub's auto-merge, or touch the CI button's boxes. +- Merge a PR from another branch, a fork, a draft, or one whose checks have failed or are missing. +- Skip, disable or re-run tests to get green; force-push; approve reviews; close PRs; delete branches. diff --git a/CLAUDE.md b/CLAUDE.md index 72ef732..1dd45cc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,9 +7,8 @@ MCP data tools and web search. User-facing docs are in `README.md`; this file is - `make check`: ruff + pytest (no network, a few seconds). Run it before every commit, on Python 3.13.5 (production; `uv venv --python 3.13.5`). GitHub CI runs the latest stable Python and Node.js instead, to catch breakage from the next upgrade early. - `make prompt-report`: token breakdown of a sample request. `python bot.py [label]` runs the bot. -- Merging: after opening a PR from a `claude/*` branch, follow `.claude/skills/auto-merge/SKILL.md`: enable GitHub auto-merge and say nothing - about it. It needs "Allow auto-merge" in the repo settings and `check` as a required status on `main`; the CI button's - "Auto-merge when ready" box does the same per PR. +- Merging: after opening a PR from a `claude/*` branch, follow `.claude/skills/merge-after-ci/SKILL.md`: subscribe, merge it yourself once + its CI passes, and say nothing about it. - Tests use fakes (`tests/conftest.py`: FakeBot, user_msg; `tests/fakes.py`: ScriptedBackend, FakeMcp, fake SDK clients; `tests/fixtures/` real anonymised MCP output). Add a test next to the module you change; don't write scratch scripts. From 56dd6e9f8650a31f583ac4d54be04a058faa2c13 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 7 Oct 2026 23:47:37 +0000 Subject: [PATCH 2/3] Skill: merge a PR only when asked (merge-pr), no automation Replaces merge-after-ci. Checks CI and mergeability fresh, merges on request with a pinned head SHA, and replies in one line. No subscribing, no watching, no GitHub auto-merge. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_014k4kywyN5dAo39izUPvxbw --- .claude/skills/merge-after-ci/SKILL.md | 32 -------------------------- .claude/skills/merge-pr/SKILL.md | 29 +++++++++++++++++++++++ CLAUDE.md | 3 +-- 3 files changed, 30 insertions(+), 34 deletions(-) delete mode 100644 .claude/skills/merge-after-ci/SKILL.md create mode 100644 .claude/skills/merge-pr/SKILL.md diff --git a/.claude/skills/merge-after-ci/SKILL.md b/.claude/skills/merge-after-ci/SKILL.md deleted file mode 100644 index f8cb0bd..0000000 --- a/.claude/skills/merge-after-ci/SKILL.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: merge-after-ci -description: Merge pull requests from claude/* branches yourself once their CI passes, silently. Use right after opening a PR, when a claude/* PR is pointed out, or when a CI-finished event arrives for one. Never merges anything that is not from a claude/* branch in this repo, and never uses GitHub's own auto-merge. ---- - -# Merge after CI passes - -Use the GitHub MCP tools (`mcp__github__*`), never `gh`. **No chatter**: do not report PR status, CI progress, subscriptions -or merges, and do not answer PR events (opened, checks finished, merged, subscription notices). Speak only for the cases under -"Say something" below, in one line. - -## Which PRs -Open, not a draft, head branch starts with `claude/` in this same repo, base is the default branch. Anything else: do nothing. - -## Steps -1. Right after a PR is opened (or when one is pointed out), subscribe to it (`subscribe_pr_activity`) so you hear when CI completes. -2. When its `check` finishes (a `check_suite.completed` event) or if CI is already done, read the PR fresh from GitHub: - `pull_request_read` `get`, `get_check_runs`, `get_reviews`, `get_review_comments`. Never rely on earlier results. -3. Merge only if ALL hold: `mergeable_state` is `clean`; every check run is `completed` with conclusion `success`; no review - is `CHANGES_REQUESTED`; no unresolved review thread. Then call `merge_pull_request` with `merge_method: merge` and - `expectedHeadSha` set to the head SHA you just read (a push that lands in between aborts the merge). Say nothing. -4. CI still running: do nothing and wait for the next event. CI red: fix it if the fix is small and yours, push, and wait again. -5. After the merge the subscription ends by itself. - -## Say something (one line each) -- CI failed and you cannot fix it, or the PR conflicts with `main` and the conflict is not a plain merge. -- A review asks for changes you cannot make on your own. - -## Never -- Enable or use GitHub's auto-merge, or touch the CI button's boxes. -- Merge a PR from another branch, a fork, a draft, or one whose checks have failed or are missing. -- Skip, disable or re-run tests to get green; force-push; approve reviews; close PRs; delete branches. diff --git a/.claude/skills/merge-pr/SKILL.md b/.claude/skills/merge-pr/SKILL.md new file mode 100644 index 0000000..0c52e43 --- /dev/null +++ b/.claude/skills/merge-pr/SKILL.md @@ -0,0 +1,29 @@ +--- +name: merge-pr +description: Merge a pull request when the user asks for it ("merge", "pr merge", "merge it"), after checking its CI passed. One-line reply. Never merges on your own, never subscribes to PRs, and never uses GitHub's auto-merge. +--- + +# Merge a PR when asked + +Use the GitHub MCP tools (`mcp__github__*`), never `gh`. Only act when the user asks. Do not watch PRs, subscribe to them, +or merge anything unprompted, and do not turn on GitHub's auto-merge or touch the CI button's boxes. + +## Which PR +The one the user names, otherwise the PR for the current branch. If there is no clear candidate, say so in one line. + +## Steps +1. Read it fresh from GitHub: `pull_request_read` `get`, `get_check_runs`, `get_reviews`, `get_review_comments`. +2. Merge only if ALL hold: open and not a draft; in this repo (not a fork); `mergeable_state` is `clean`; every check run is + `completed` with conclusion `success`; no review is `CHANGES_REQUESTED`; no unresolved review thread. +3. Call `merge_pull_request` with `merge_method: merge` and `expectedHeadSha` set to the head SHA you just read. +4. Read the PR back and confirm `merged: true`. If the session is subscribed to it, unsubscribe. +5. Reply with one line: `#N merged (sha)`. + +## When it cannot merge (one line) +- CI still running or missing: say so, and do not wait or poll. +- CI red: say which check failed. +- Conflict, changes requested or an open thread: name it. Do not update the branch or fix it unless asked. + +## Never +- Merge without being asked, or merge a draft or a PR with failing, missing or pending checks. +- Skip, disable or re-run tests to get green; force-push; approve reviews; close PRs; delete branches. diff --git a/CLAUDE.md b/CLAUDE.md index 1dd45cc..3c26016 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,8 +7,7 @@ MCP data tools and web search. User-facing docs are in `README.md`; this file is - `make check`: ruff + pytest (no network, a few seconds). Run it before every commit, on Python 3.13.5 (production; `uv venv --python 3.13.5`). GitHub CI runs the latest stable Python and Node.js instead, to catch breakage from the next upgrade early. - `make prompt-report`: token breakdown of a sample request. `python bot.py [label]` runs the bot. -- Merging: after opening a PR from a `claude/*` branch, follow `.claude/skills/merge-after-ci/SKILL.md`: subscribe, merge it yourself once - its CI passes, and say nothing about it. +- Merging: only when asked; follow `.claude/skills/merge-pr/SKILL.md` (checks CI first, one-line reply). - Tests use fakes (`tests/conftest.py`: FakeBot, user_msg; `tests/fakes.py`: ScriptedBackend, FakeMcp, fake SDK clients; `tests/fixtures/` real anonymised MCP output). Add a test next to the module you change; don't write scratch scripts. From ede497e1a07a861e55b48bc24dca3d8c88c83a07 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 7 Oct 2026 23:48:19 +0000 Subject: [PATCH 3/3] Revert "Skill: merge a PR only when asked (merge-pr), no automation" This reverts commit 56dd6e9f8650a31f583ac4d54be04a058faa2c13. --- .claude/skills/merge-after-ci/SKILL.md | 32 ++++++++++++++++++++++++++ .claude/skills/merge-pr/SKILL.md | 29 ----------------------- CLAUDE.md | 3 ++- 3 files changed, 34 insertions(+), 30 deletions(-) create mode 100644 .claude/skills/merge-after-ci/SKILL.md delete mode 100644 .claude/skills/merge-pr/SKILL.md diff --git a/.claude/skills/merge-after-ci/SKILL.md b/.claude/skills/merge-after-ci/SKILL.md new file mode 100644 index 0000000..f8cb0bd --- /dev/null +++ b/.claude/skills/merge-after-ci/SKILL.md @@ -0,0 +1,32 @@ +--- +name: merge-after-ci +description: Merge pull requests from claude/* branches yourself once their CI passes, silently. Use right after opening a PR, when a claude/* PR is pointed out, or when a CI-finished event arrives for one. Never merges anything that is not from a claude/* branch in this repo, and never uses GitHub's own auto-merge. +--- + +# Merge after CI passes + +Use the GitHub MCP tools (`mcp__github__*`), never `gh`. **No chatter**: do not report PR status, CI progress, subscriptions +or merges, and do not answer PR events (opened, checks finished, merged, subscription notices). Speak only for the cases under +"Say something" below, in one line. + +## Which PRs +Open, not a draft, head branch starts with `claude/` in this same repo, base is the default branch. Anything else: do nothing. + +## Steps +1. Right after a PR is opened (or when one is pointed out), subscribe to it (`subscribe_pr_activity`) so you hear when CI completes. +2. When its `check` finishes (a `check_suite.completed` event) or if CI is already done, read the PR fresh from GitHub: + `pull_request_read` `get`, `get_check_runs`, `get_reviews`, `get_review_comments`. Never rely on earlier results. +3. Merge only if ALL hold: `mergeable_state` is `clean`; every check run is `completed` with conclusion `success`; no review + is `CHANGES_REQUESTED`; no unresolved review thread. Then call `merge_pull_request` with `merge_method: merge` and + `expectedHeadSha` set to the head SHA you just read (a push that lands in between aborts the merge). Say nothing. +4. CI still running: do nothing and wait for the next event. CI red: fix it if the fix is small and yours, push, and wait again. +5. After the merge the subscription ends by itself. + +## Say something (one line each) +- CI failed and you cannot fix it, or the PR conflicts with `main` and the conflict is not a plain merge. +- A review asks for changes you cannot make on your own. + +## Never +- Enable or use GitHub's auto-merge, or touch the CI button's boxes. +- Merge a PR from another branch, a fork, a draft, or one whose checks have failed or are missing. +- Skip, disable or re-run tests to get green; force-push; approve reviews; close PRs; delete branches. diff --git a/.claude/skills/merge-pr/SKILL.md b/.claude/skills/merge-pr/SKILL.md deleted file mode 100644 index 0c52e43..0000000 --- a/.claude/skills/merge-pr/SKILL.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: merge-pr -description: Merge a pull request when the user asks for it ("merge", "pr merge", "merge it"), after checking its CI passed. One-line reply. Never merges on your own, never subscribes to PRs, and never uses GitHub's auto-merge. ---- - -# Merge a PR when asked - -Use the GitHub MCP tools (`mcp__github__*`), never `gh`. Only act when the user asks. Do not watch PRs, subscribe to them, -or merge anything unprompted, and do not turn on GitHub's auto-merge or touch the CI button's boxes. - -## Which PR -The one the user names, otherwise the PR for the current branch. If there is no clear candidate, say so in one line. - -## Steps -1. Read it fresh from GitHub: `pull_request_read` `get`, `get_check_runs`, `get_reviews`, `get_review_comments`. -2. Merge only if ALL hold: open and not a draft; in this repo (not a fork); `mergeable_state` is `clean`; every check run is - `completed` with conclusion `success`; no review is `CHANGES_REQUESTED`; no unresolved review thread. -3. Call `merge_pull_request` with `merge_method: merge` and `expectedHeadSha` set to the head SHA you just read. -4. Read the PR back and confirm `merged: true`. If the session is subscribed to it, unsubscribe. -5. Reply with one line: `#N merged (sha)`. - -## When it cannot merge (one line) -- CI still running or missing: say so, and do not wait or poll. -- CI red: say which check failed. -- Conflict, changes requested or an open thread: name it. Do not update the branch or fix it unless asked. - -## Never -- Merge without being asked, or merge a draft or a PR with failing, missing or pending checks. -- Skip, disable or re-run tests to get green; force-push; approve reviews; close PRs; delete branches. diff --git a/CLAUDE.md b/CLAUDE.md index 3c26016..1dd45cc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,7 +7,8 @@ MCP data tools and web search. User-facing docs are in `README.md`; this file is - `make check`: ruff + pytest (no network, a few seconds). Run it before every commit, on Python 3.13.5 (production; `uv venv --python 3.13.5`). GitHub CI runs the latest stable Python and Node.js instead, to catch breakage from the next upgrade early. - `make prompt-report`: token breakdown of a sample request. `python bot.py [label]` runs the bot. -- Merging: only when asked; follow `.claude/skills/merge-pr/SKILL.md` (checks CI first, one-line reply). +- Merging: after opening a PR from a `claude/*` branch, follow `.claude/skills/merge-after-ci/SKILL.md`: subscribe, merge it yourself once + its CI passes, and say nothing about it. - Tests use fakes (`tests/conftest.py`: FakeBot, user_msg; `tests/fakes.py`: ScriptedBackend, FakeMcp, fake SDK clients; `tests/fixtures/` real anonymised MCP output). Add a test next to the module you change; don't write scratch scripts.