一键导入
gwt-manage-pr
Use when the user wants to create, inspect, update, or unblock a pull request and expects one visible entrypoint for the PR lifecycle.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when the user wants to create, inspect, update, or unblock a pull request and expects one visible entrypoint for the PR lifecycle.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when execution should start from a GitHub Issue, gwt-spec Issue, or approved standalone task through one build/test/verify loop.
Use when implementation should proceed from an approved SPEC or approved standalone task, and the work should run through the build/test/verify loop.
Use when implementation needs verification before completion or before opening a PR. Defines a project-agnostic Generic Verification Contract: classify changed surfaces, autodetect the project's test runners from manifests (Cargo.toml / package.json / pyproject.toml / go.mod / ProjectSettings / *.sln / etc.), run the appropriate unit / integration / E2E / visual tests for the project, emit an evidence bundle that lists exactly which tests were executed, then hand off to the user with a 4-step 導線 (build → launch → navigate → observe) and check items before declaring Overall: PASS. Triggers: 'verify', 'run tests', 'pre-PR check', 'gwt-verify'.
Use when an idea, spec question, or implementation gap needs investigation and discussion before deciding how work should proceed.
Use when the user wants to resolve an existing GitHub Issue by number or URL, especially when the workflow should continue through a direct fix unless a SPEC is needed.
Use when the user wants to register new work from a bug report, idea, or task description and an existing GitHub Issue number is not already known.
| name | gwt-manage-pr |
| description | Use when the user wants to create, inspect, update, or unblock a pull request and expects one visible entrypoint for the PR lifecycle. |
Single skill for the full PR lifecycle: create, check status, fix blockers, and deliver (drive to merge). Auto-detects the appropriate mode from current branch PR state, or accepts an explicit mode from the user. Deliver mode is opt-in only and is never auto-detected.
Use the current user's language for decision summaries, blocker reports, and next-step guidance returned from this workflow.
Canonical agent-facing surface is gwtd JSON operations pr.* and
actions.* for PR inspection, create/update, and fix flows. The current
implementation may still use GitHub REST / gh internally as transport, while
GraphQL remains the transport for unresolved review threads and thread
reply/resolve.
Every final user-facing report from this workflow MUST state whether a PR was
created, updated, fixed, delivered (driven to merge), or left unchanged. When a
PR was created, pushed to, fixed, or delivered, include a PR Update Summary
derived from the actual diff, commit range, and PR body. Do not invent changes
from intent alone.
PR Update Summary must include:
NoneFor check and NO ACTION results, explicitly say no PR update was made.
If an existing PR is only inspected, summarize the current PR status separately
from PR Update Summary so the report does not imply new changes were pushed.
Final report shape:
## PR Result
- Action: Created | Updated | Fixed | Delivered | Checked | No Action
- PR: #<number> <url> | None
- Branches: <base> <- <head>
### PR Update Summary
- Commits: <count or range>
- Updates:
- <what changed>
- Related: #<issue/spec> | None
- Verification: <commands/checks and status>
### Next
- <remaining blocker or "None">
Omit PR Update Summary only when no PR was created, updated, or fixed; in
that case include PR Update: none in the result.
Before executing any gwtd ... command from this skill or its references,
resolve GWT_BIN first: executable GWT_BIN_PATH, then command -v gwtd,
then $GWT_PROJECT_ROOT/target/debug/gwtd or ./target/debug/gwtd. Run the
command as "$GWT_BIN" ...; if none exists, stop with an actionable
gwtd not found error.
On invocation, run Shared Preflight, then route:
mergeable: CONFLICTING|DIRTY|BEHIND → fixN > 0 + no open PR → createN > 0 + open PR + clean merge state → create (push-only + post-push fix)N = 0 + open PR → fix (check CI / reviews / conflicts)N = 0 + no open PR → report NO ACTIONEvery mode begins with these steps. The order is intentional — commit count against the base branch comes before PR state lookup so that the MERGED shortcut ("PR is done therefore nothing to do") is structurally impossible.
Repo + branches:
git rev-parse --show-toplevel / git rev-parse --abbrev-ref HEADdevelop unless user specifies.Branch protection: Only develop may target main. Refuse any other branch targeting main.
Working tree state: git status --porcelain. If dirty, pause and present options (continue / abort / cleanup). Do not auto-commit/stash.
Fetch: git fetch origin
Commit count against base (mandatory first check):
N=$(git rev-list --count "origin/$base..HEAD")
Baseline ref rule: ALWAYS compare against
origin/<base>(the PR target branch, defaultorigin/develop). NEVER useorigin/<head>(the remote tracking branch of the current branch) — that only tells you if commits are pushed, not whether develop has your work. Confusing the two is the root cause of the MERGED-state false NO ACTION bug.
PR lookup + open-PR check:
pr.current as the normal read path for the current branch.no current pull request as the canonical no-PR sentinel.has_open_pr = any entry with state == "open" && merged_at == nullmergeable:. CONFLICTING, DIRTY, and BEHIND are blocking merge states and immediately upgrade routing to fix.Route using the 2×2 matrix, with merge-state override:
| Commits (N) | Open PR? | Action |
|---|---|---|
| N > 0 | No | CREATE new PR |
| N > 0 | Yes | PUSH ONLY to existing PR → then FIX |
| N = 0 | Yes | FIX (CI / reviews / conflicts) |
| N = 0 | No | NO ACTION |
If the open PR reports mergeable: CONFLICTING, DIRTY, or BEHIND,
use FIX immediately instead of push-only/create. Outside that
override, PR state (MERGED / CLOSED) is not consulted.
Use the Ready PR Gate before any push, PR create, PR update, or state change that would present the branch as Ready for review. A PR may be Ready for review only when all of the following are true:
gwt-verify --mode pre-pr returns Overall: PASSUser Verification Result is confirmed, n/a, or
skipped(<reason>)In gwt-managed execution worktrees the canonical operations enforce part of
this mechanically (SPEC-3248 P8b): non-draft pr.create and pr.ready
refuse when the session's Execution Control Record is terminally blocked, or
active without a fresh all-passing Verification Run Record (written by JSON
operation verify.run). Run the pre-PR matrix through verify.run so the
evidence exists before the Ready handoff; Draft PR creation stays available
mid-work.
gwt-verify is a project-agnostic Generic Verification Contract: it
autodetects the host project's test runners (Cargo.toml / package.json /
pyproject.toml / go.mod / ProjectSettings / *.sln / etc.), runs the
appropriate unit / integration / E2E / visual tests for the changed
surfaces, emits a Test Inventory naming exactly which tests were
executed, and hands off to the user with a 4-step 導線 + Check Items
before finalizing the report. Project-local AGENTS.md / README testing
instructions always take precedence over the generic matrix.
Draft PR is the only allowed PR state for unfinished, partially
verified, acceptance-incomplete, or blocker-bearing work. Draft PR is
allowed for CI, shared visibility, and early review, but the PR body
must set State: Draft, list known blockers, list Remaining acceptance,
and avoid any claim that the change is complete or a releaseable slice.
Full gwt-verify --mode pre-pr is not required solely to create or
update a Draft PR, but the agent must include the exact verification
that was run and the reason full Ready verification is not yet claimed.
The Ready PR Gate fails when any of:
gwt-verify --mode pre-pr returns Overall: FAILfailed: tooling-missing is recordedUser Verification Result is pending (handoff never completed) or
rejected(<reason>) (user declined). The user's reason is preserved
in the evidence bundle.On Ready PR Gate failure, do not push a Ready/non-draft update, do not
create a Ready PR, and do not mark an existing Draft PR as Ready for
review. Either keep/create the PR as Draft PR with explicit blockers, or
return NO ACTION and route the failure for repair (back to the TDD
loop or gwt-discussion) before retrying.
This applies equally to Create and Fix modes. Every code-changing
re-push to a Ready/non-draft PR must be preceded by a fresh
gwt-verify --mode pre-pr PASS with a satisfied
User Verification Result.
Detailed logic in references/create-flow.md.
Create mode is entered from the Preflight 2×2 matrix when N > 0.
CONFLICTING / DIRTY / BEHIND → enter Fix mode before any push-only path.params.draft:true unless the Ready PR Gate is satisfied.origin/$base, merge origin/$base first (never rebase). Push after merge.<type>(<scope>): <subject> (Conventional Commits)feat/fix/docs/chore/refactor/test/ci/perffeat//fix/ must match title typegwt-manage-pr/references/pr-body-template.md<!-- GUIDE: ... --> comments from final outputTODO in required sections; derive content from diff/Issues/SPECs before asking userClosing Issues: Closes #N or None only. Bare #N without keyword is forbidden.pr.create with params.base, optional
params.head, params.title, params.body, optional params.labels, and
params.draft.pr.edit with params.number, optional
params.title, optional params.body, and optional params.add_labels
(at least one of them is required).pr.ready with params.number marks a
Draft PR Ready for review — only after the Ready PR Gate passes.
pr.draft converts a Ready PR back to Draft.gh
internally, but agent-facing workflow should stay on gwtd JSON operations.After PR creation or push, automatically enter fix mode and use JSON
operations pr.checks, pr.reviews, pr.review_threads, actions.logs, and
actions.job_logs as the normal inspection path.
Detailed logic in references/check-flow.md.
Read-only mode. Do not create/switch branches, push, or create/edit PRs.
pr.currentpr.viewpr.checkspr.reviewspr.review_threadsactions.logs / actions.job_logsHuman-readable summary using signal prefixes:
| Prefix | Action | Meaning |
|---|---|---|
>> | CREATE PR | Create a new PR |
> | PUSH ONLY | Push to existing PR |
~ | FIX | Fix CI / reviews / conflicts on existing PR |
-- | NO ACTION | Nothing to do |
!! | MANUAL CHECK | Manual check required |
Per-status templates:
Templates map directly from the Preflight 2×2 matrix:
>> CREATE PR -- <N> new commit(s) not covered by any PR.> PUSH ONLY -- Unmerged PR #<number> open for <head>. + PR URL~ FIX -- PR #<number> is <mergeable>; resolve base sync/conflicts before push-only.~ FIX -- PR #<number> open, checking CI/reviews/conflicts.-- NO ACTION -- No commits ahead of <base>, no open PR.!! MANUAL CHECK -- Could not determine commit count. + reasonAppend (!) Worktree has uncommitted changes. when dirty.
The commit count N = git rev-list --count origin/<base>..HEAD is
computed in the Shared Preflight and is the primary routing signal.
Check mode simply reports it:
N > 0 + no open PR → >> CREATE PR -- <N> new commit(s) not in any PR.N > 0 + open PR + clean merge state → > PUSH ONLY -- Unmerged PR open. + PR URLmergeable: CONFLICTING|DIRTY|BEHIND → ~ FIX -- PR is blocked by merge state.N = 0 + open PR → report CI / review / conflict statusN = 0 + no open PR → -- NO ACTIONThe old "Post-Merge Commit Check" logic (merge_commit ancestry,
fallback chain) is subsumed by git rev-list --count origin/<base>..HEAD
which directly answers "does develop have all my work?" regardless of
PR state.
Detailed logic in references/fix-flow.md.
mergeable / mergeStateStatus fields (CONFLICTING/DIRTY/BEHIND)CHANGES_REQUESTED state## Diagnosis Report: PR #<number>
**Merge Verdict: BLOCKED | CLEAR**
Blocking items: <N>
---
### BLOCKING
#### B1. [CATEGORY] <1-line title>
- **What:** Factual statement
- **Where:** file_path:line / check name / branch ref
- **Evidence:** Verbatim quote from output
- **Action:** Specific fix with file path/command
- **Auto-fix:** Yes | No (needs confirmation)
---
### INFORMATIONAL
#### I1. [CATEGORY] <1-line title>
- **What / Note**
---
**Summary:** <N> blocking, <M> informational.
Categories: CONFLICT, BRANCH-BEHIND, CI-FAILURE, CHANGE-REQUEST, UNRESOLVED-THREAD, REVIEW-COMMENT
Classification:
Each CHANGE-REQUEST, UNRESOLVED-THREAD, and UNANSWERED-COMMENT is a separate B-item.
Auto-fix: Yes --> proceed directly to fix.Auto-fix: No --> ask user about those items only.git fetch origin <base> && git merge origin/<base> && git pushNo reviewer comment may be left unanswered or unresolved.
pr.review_threads.reply_and_resolve to reply to and resolve all unresolved
threads on the PR.resolveReviewThread.Post a PR summary comment via JSON operation pr.comment.
Re-run inspection with --mode all. Loop until exit code 0.
Same CI check fails 3 consecutive iterations --> report to user, ask continue/abort/change approach.
Detailed logic in references/deliver-flow.md.
Deliver mode drives a verified, Ready PR all the way to a merged state: enable
GitHub auto-merge, then run the existing Fix loop against every blocker (CI /
reviews / threads / conflicts) and poll until merged_at is set. Deliver
composes Fix mode — it does not reimplement blocker resolution.
Deliver mode is opt-in only: it is entered only when the user explicitly asks to deliver / drive to merge / merge / land / ship the PR. The Mode Auto-Detection matrix never selects Deliver on its own, because enabling auto-merge is an outward-facing, hard-to-reverse action — once armed, GitHub merges the PR the moment required checks go green. If no open PR exists, Deliver first falls back to Create (Ready PR Gate applies) and then drives the newly created PR.
Do not enable auto-merge until the Ready PR Gate passes for the PR scope. Deliver applies a stricter gate than Create/Fix because auto-merge removes the last human checkpoint:
gwt-verify --mode pre-pr returns Overall: PASSUser Verification Result is confirmed or n/a (not pending,
rejected(<reason>), or skipped(<reason>) — a skip is enough to create a
PR but not to merge unattended)If verification is pending, do not run gh pr merge --auto. Stop and
route the failure for repair (back to the TDD loop, gwt-verify, or
gwt-discussion). Never downgrade a pending result to skipped to pass the
gate.
Auto-merge may be armed only when the PR is fully clear (no blocking CI, no
conflict/BEHIND, no unresolved thread, no open CHANGES_REQUESTED) and the
Hard PR Gate is satisfied. Before any code-changing push, disable
auto-merge first (gh pr merge --disable-auto <number>); after the push,
re-run the Hard PR Gate and only then re-arm. This makes GitHub merge
only a snapshot that passed verification, and inherits the skill's rule that
every code-changing re-push needs a fresh gwt-verify --mode pre-pr PASS — it
does not override it.
pr.current or the
user-supplied number; read state with pr.view ([MERGED] bracket plus
mergeable: / merge_state: / ci: / review: lines).--mode all and resolve every BLOCKING item through
the existing Fix Implementation / Comment Response flow — before arming.
Re-gate per the Core invariant on each code-changing push.gh repo view --json ...,viewerDefaultMergeMethod); never hardcode --squash.gh pr merge --auto --merge <number> (transport exception — there is no pr.merge JSON operation;
gh pr merge is allowed). --auto waits only for required checks; on repos
that do not enforce conversation-resolution/approval branch protection,
prefer poll-then-merge (gh pr merge --merge <number> after re-reading
pr.view CLEAN) over --auto.pr.view ~30s. On any new blocker (BEHIND, new failing check, new
thread/CHANGES_REQUESTED): gh pr merge --disable-auto, resolve, re-gate,
re-arm. Re-run only infrastructure-transient CI failures with
gh run rerun <run-id> --failed (max 3); a test/build timeout or compile/
test failure is code, not transient — fix it. The poll is bounded (~20 polls
/ ~10 min) then hands off via board.post.pr.view shows [MERGED] (GitHub merged_at set), then
report Delivered. "Auto-merge enabled" is not "merged."The same blocker (same CI check name, same unresolved thread, same conflict)
surviving 3 consecutive drive iterations → stop, report what was tried each
iteration, and ask the user continue / abort / change approach. Do
not loop indefinitely; the merged-state poll is bounded and hands off via
board.post (params.kind:"blocked") when CI stays pending.
Driving to merge can span CI runs longer than one turn. Optionally arm a "PR
merged" completion goal so monitoring survives turn boundaries, using the same
goal-start contract as /release step 5.4 (Codex create_goal; Claude Code
pane.send of /goal <condition>). Arming the goal is best effort and never
replaces the in-loop pr.view poll.
| Prohibited | Required Alternative |
|---|---|
| "We should look into..." | "Edit path/file.ts:42 to..." |
| "There seem to be some issues" | "3 blocking items detected" |
| "This might be causing..." | "Root cause: <error from log>" |
| "Consider fixing..." | "Action: Fix <what> in <where>" |
| "Various CI checks are failing" | "2 CI checks failing: build, lint" |
\n) in final comment text.When work is tracked in Issues:
Progress
- ...
Done
- ...
Next
- ...
PR lifecycle work is driven through canonical gwtd JSON operations pr.* and
actions.*. Do not depend on retired repo-local helper script
paths when running this workflow.
references/create-flow.md -- PR creation workflow detailsreferences/check-flow.md -- PR status checking detailsreferences/fix-flow.md -- CI/conflict/review fix detailsreferences/deliver-flow.md -- drive-to-merge (auto-merge + Fix loop + merged watch) detailsreferences/pr-body-template.md -- PR body template