Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions .agents/skills/drive-pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
name: drive-pr
description: >-
Drives a ptr727/ProjectTemplate fleet pull request through its review loop, feature branch into
develop and, when asked, on to a mergeable develop -> main promotion PR, applying the
pr-review-conduct disposition to every reviewer finding along the way: fix it, decline it with
evidence, defer it behind a filed issue, or put the call to the maintainer and wait for an
explicit answer in the same turn. Use this whenever asked to drive, land, take, chase, or push
a PR toward develop or main, or to run the review loop hands off instead of narrating each
round. When the request does not say how far ("drive this PR", "land it"), ask once whether the
target is develop or a mergeable main promotion PR, rather than guessing. Triggers even when
only one PR is named, because a finding raised against the develop -> main promotion PR
routinely needs its own feature -> develop fix cycle before the promotion PR can go green, and
stopping at the first promotion-PR finding is the early exit this skill exists to prevent. Ends
at develop merged, or at a promotion PR meeting the pr-review-conduct Merge Gate, never merges
main itself, that is the separate merge-and-release skill, its own go-ahead.
---

# Drive PR

## Why This Exists

The same request repeats every time a change is ready: drive it through review, resolve whatever
a reviewer raises, and keep going until develop, or main, actually has it. Re-explaining the
finding-disposition policy and the promotion-PR wrinkle each time is the cost this skill removes.
The wrinkle: a finding raised against the develop -> main promotion PR usually cannot be fixed on
that PR directly, its diff is develop's diff against main, so the fix lands as its own
feature -> develop PR first. Stopping at the first such finding, or forgetting to loop back to the
promotion PR once the fix lands, is the early exit this skill exists to prevent.

## How Far to Drive

- Read the invocation for an explicit target first. "To develop" or "to dev" means stop once
merged into develop. "To main", "through to main", or "all the way" means continue to a
mergeable promotion PR. Act on either without asking.
- When the request names no target ("drive this PR", "land it", "take this PR"), ask once,
before the first push: develop only, or all the way to a mergeable main promotion PR. Recommend
"all the way to main" as the default, a promotion PR left to go stale once develop is ready is
the more common regret than driving one step too far.
- A repo on the operational workflow model (registry `workflowModel: operational`) has no
standing promotion PR expectation, confirm whether a promotion PR is even wanted before opening
one, per operational-vs-release-workflow's "Operational repositories" delta.

## What Invoking This Skill Authorizes

- Naming this skill, and answering its how-far question, is the maintainer's explicit, current
go-ahead for every feature -> develop squash merge the drive performs to reach that target.
- It is never authorization to merge the develop -> main promotion PR, or to dispatch a release.
Those stay in merge-and-release, invoked on its own so the maintainer keeps a checkpoint before
the harder-to-reverse step.
- The pr-review-conduct Merge Gate still gates every merge this skill performs on its own. The
go-ahead removes the "may I merge to develop" question, not the gate itself, a feature PR with
an open finding does not merge regardless of target.

## The Drive Loop

1. Isolate into a worktree per repo-worktree, based on develop, before the first edit.
2. Push the branch and open the feature -> develop PR if it does not exist yet.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
3. Drive pr-review-conduct's review loop on it to the Merge Gate, disposing of every finding per
"Disposing of Every Finding" below.
4. Merge the feature PR into develop (squash), then run repo-worktree's post-merge cleanup for
that worktree. Stop here and report the merged PR when the target is develop only.
5. Open the develop -> main promotion PR if it does not exist yet, or find the existing one.
6. Drive its review loop the same way. A finding that needs a code change never gets pushed to
the promotion PR directly, its head is develop, so land the fix as a fresh pass through steps
1 to 4 in its own worktree and branch, then return here.
7. The fix landing on develop updates the promotion PR's diff and head SHA on its own, re-request
a review on the new head and continue the loop.
8. Repeat 6 and 7 until the promotion PR itself carries no open finding and its checks are green
on the current head.
9. Report the promotion PR number and its ready state. Do not merge it.

## Disposing of Every Finding

pr-review-conduct's five outcomes are the actual rule, this is the mapping to use while driving:

- Real, so fix it. Push the fix, reply with its commit SHA (outcome 1).
- Not real, or real but out of scope here, so decline in the thread with evidence: the command
and its output, the code path, or the rule that governs it. An assertion never closes a finding
on its own (outcome 2).
- Real and worth doing, but later, so file the issue first, then reply with its link (outcome 4).
- Real, fixable, but a value call rather than a scope boundary, or the agent genuinely does not
know which of the above applies, so ask the maintainer directly, whatever the runtime's own
interactive-question mechanism is, and get an explicit answer in the same turn, a plan to ask
later is resolution by silence (outcome 3).
- The same finding keeps recurring against correct code, fix the class, sharpen a name, add a
comment, or take the rule itself to the maintainer, rather than re-arguing the instance every
round (outcome 5).

## Mechanics Live Elsewhere

- Review loop mechanics, the Merge Gate, and `scripts/pr_review.py`: pr-review-conduct.
- Branch rules, never delete develop, the EOL-only conflict, issue-closing keywords belonging on
the promotion PR: operational-vs-release-workflow.
- Worktree isolation and post-merge cleanup: repo-worktree.

## Stop and Ask, Beyond the How-Far Question

- A genuine design trade-off, a recurring finding pattern, or an architectural redesign proposal
each escalate per pr-review-conduct's own list, restated there, not duplicated here.
- An unrecognized review shape blocks the gate on its own, file an issue naming it and ask, never
guess what new wording probably meant.
113 changes: 113 additions & 0 deletions .agents/skills/merge-and-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
name: merge-and-release
description: >-
Merges a ready develop -> main promotion PR for any ptr727/ProjectTemplate fleet repo and, when
asked, dispatches the release, in this hub always refreshing this machine's installed Skills
from the newly promoted content as part of that release step, never as a separate ask. Use this
whenever asked to merge main, ship a release, cut a release, or finish a promotion once its PR
is already green and fully resolved (produced by drive-pr or by hand). When the request does
not say how far ("merge main", "ship it"), ask once whether to merge only or merge and release,
rather than guessing which the maintainer wants this time. Triggers even when the phrasing is
as short as "merge main and release", because that already states the scope and is itself the
explicit, current go-ahead this skill acts on without asking again, though it never substitutes
for the pr-review-conduct Merge Gate, a promotion PR that is not actually green and fully
resolved gets reported and stopped on, not merged.
---

# Merge and Release

## Why This Exists

Once drive-pr (or a maintainer by hand) leaves a promotion PR ready, the same two steps follow
every time: merge it, and usually dispatch the release it unblocks. In this hub a promotion can
also change `.agents/skills` content this very session depends on, so the release step always
carries a Skills refresh with it there, never a separate branch to ask about, an ambiguous "merge
and release" on the hub must not leave the maintainer unsure whether Skills got refreshed. One
skill covers all of it, scoped down by what the maintainer actually asks for.

## How Far to Go

- Read the invocation for an explicit scope first. "Just merge" or "merge only" means stop after
the merge. "Merge and release", "ship it", or "cut a release" means also dispatch, and in this
hub also refresh Skills as part of that same step. Act on either without asking.
- When the request names no scope ("merge main"), ask once, before merging: merge only, or merge
and release. Recommend "merge and release" as the default on a release-model repo, a promotion
merged without its release is the more common regret there. Recommend "merge only" as the
default on an operational repo (registry `workflowModel: operational`), where a release is a
separate, deliberate dispatch rather than an automatic follow-on to a promotion, per
operational-vs-release-workflow's "Operational repositories" delta.
- Detect the hub automatically, `git remote get-url origin` or `gh repo view --json
nameWithOwner` naming `ptr727/ProjectTemplate`. There the release scope silently includes the
Skills refresh, a downstream repo never sees it, it has no `.agents/skills` of its own to
refresh.

## What Invoking This Skill Authorizes

- Naming this skill, and answering its how-far question, is the maintainer's explicit, current
go-ahead to merge the promotion PR and to perform the scope chosen, for the one repo and PR in
front of the agent. It is never a standing mode carried to the next PR.
- It is never permission to merge a PR that fails the Merge Gate. Re-verify the gate at
invocation time, a check from earlier in the session can be stale.

## The Procedure

1. Identify the open develop -> main promotion PR for this repo, stop and report if none is open.
2. From a hub checkout, `scripts/` is not carried into downstream repos, run `scripts/pr_review.py
status [number] --repo owner/repo` on it and confirm the pr-review-conduct Merge Gate. Stop
and report exactly what is missing rather than merging on a partial gate.
3. `gh pr merge [number] --merge --repo owner/repo`. Never `--delete-branch`, the promotion PR's
head is `develop`.
4. Confirm the merge landed, `mergedAt` set, `main`'s tip matching the merge commit.
5. In the hub, when the chosen scope includes a release, first bring this checkout to the merged
content: `git fetch origin main`, then `git checkout -B main origin/main` to force the local
`main` to the fetched tip regardless of what it pointed to before. `skills_install.py` stamps
and installs from whatever this checkout's HEAD already is, so a plain `git checkout main`
would leave a local `main` that already existed pointing at its old, pre-fetch commit, and
skip the refresh silently. Only then run `python3 scripts/skills_install.py
--report`, then `python3 scripts/skills_install.py` to install, and confirm `--report` now
reads current, always, not only when separately asked. This refreshes only the machine running
this session, per skill-lifecycle, every other machine still refreshes on its own next run or
`docs/host-setup.md` "Fleet Skills Install" cadence.
6. When the chosen scope includes a release, first check the registry's `releaseTrigger` for this
repo in `registry/repos.json`, three shapes. Report that no release is configured and go to
step 8 without dispatching or watching anything when it reads `none`. For `publish-on-merge`,
the merge in step 3 is itself the trigger, no dispatch is needed, note that and go to step 7 to
watch the run it produced. Otherwise (`two-phase` or `dispatch-only`), dispatch, `gh workflow
run publish-release.yml --ref main --repo owner/repo`, or `--ref develop` only when the
maintainer explicitly asked for a prerelease dispatch instead, then go to step 7.
7. Correlate the specific run this step's trigger produced rather than assuming the newest one is
it. After an explicit dispatch, `gh run list --repo owner/repo --workflow
publish-release.yml --branch main --event workflow_dispatch --json databaseId,createdAt` (or
`--branch develop` for a prerelease dispatch), matched by `createdAt` against the dispatch
time. For a `publish-on-merge` repo, the same query with `--event push` instead, matched by
`createdAt` against the step 3 merge time. Poll only when exactly one candidate matches, report
and stop rather than guessing when zero or more than one do, a concurrent run of a different
event on the same branch must never be mistaken for this one. Poll that one run id to
completion in one
bounded background wait with an explicit timeout, `timeout <seconds> gh run watch <run-id>
--repo owner/repo --exit-status` on a host with GNU `timeout`, or the equivalent bounded-wait
mechanism on a host without it (macOS without coreutils, native Windows), and report a timeout
separately from a completed run's own conclusion, the tag or version it produced. A run that
fails, times out, or never starts is reported, never silently retried.
8. Run the repo-worktree post-merge cleanup regardless of how steps 5 through 7 ended, no release
configured, a merge-triggered release, a dispatch failure, an ambiguous run match, a timeout,
or a failed run all still reach this step, the merge in step 3 already landed by then and
cleanup is never conditioned on the release outcome. Fetch and prune, fast-forward the base
clone to
`develop`, remove any worktree the completed task leaves behind.

## Mechanics Live Elsewhere

- The Merge Gate itself: pr-review-conduct.
- Never delete develop, no-op republish, the operational repos' dispatch-only model:
operational-vs-release-workflow.
- What the dispatch actually builds and publishes: workflow-ci-contract.
- Skills install and report semantics: skill-lifecycle.
- Cleanup mechanics: repo-worktree.

## Stop and Report, Never Guess

- A merge conflict, a newly failing check, or a gate item that regressed since drive-pr finished
are each a stop, report the exact state, never force or retry blindly.
- `gh pr merge` or `gh workflow run` failing is reported with its actual output, never
suppressed, never assumed harmless on the agent's side alone.
2 changes: 2 additions & 0 deletions .claude-plugin/fleet-skills/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
"./skills/comment-and-doc-style",
"./skills/copilot-instructions-keeper",
"./skills/dotnet-codestyle",
"./skills/drive-pr",
"./skills/fleet-conformance-check",
"./skills/git-commit-conventions",
"./skills/merge-and-release",
Comment thread
qodo-code-review[bot] marked this conversation as resolved.
"./skills/operational-vs-release-workflow",
"./skills/pr-review-conduct",
"./skills/python-codestyle",
Expand Down
2 changes: 1 addition & 1 deletion .claude-plugin/fleet-skills/.source-digest
Original file line number Diff line number Diff line change
@@ -1 +1 @@
598e6a55149a7fde
28b5244e2b0a06ad
Loading