@fro.bot/systematic 2.3.3 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +12 -13
  2. package/agents/design/design-implementation-reviewer.md +2 -19
  3. package/agents/design/design-iterator.md +2 -31
  4. package/agents/design/figma-design-sync.md +2 -22
  5. package/agents/docs/ankane-readme-writer.md +2 -19
  6. package/agents/document-review/adversarial-document-reviewer.md +3 -2
  7. package/agents/document-review/coherence-reviewer.md +5 -7
  8. package/agents/document-review/design-lens-reviewer.md +3 -4
  9. package/agents/document-review/feasibility-reviewer.md +3 -4
  10. package/agents/document-review/product-lens-reviewer.md +25 -6
  11. package/agents/document-review/scope-guardian-reviewer.md +3 -4
  12. package/agents/document-review/security-lens-reviewer.md +3 -4
  13. package/agents/research/best-practices-researcher.md +4 -21
  14. package/agents/research/framework-docs-researcher.md +2 -19
  15. package/agents/research/git-history-analyzer.md +2 -19
  16. package/agents/research/issue-intelligence-analyst.md +2 -24
  17. package/agents/research/learnings-researcher.md +7 -28
  18. package/agents/research/repo-research-analyst.md +3 -32
  19. package/agents/research/slack-researcher.md +128 -0
  20. package/agents/review/agent-native-reviewer.md +109 -195
  21. package/agents/review/architecture-strategist.md +3 -19
  22. package/agents/review/cli-agent-readiness-reviewer.md +1 -27
  23. package/agents/review/code-simplicity-reviewer.md +5 -19
  24. package/agents/review/data-integrity-guardian.md +3 -19
  25. package/agents/review/data-migration-expert.md +3 -19
  26. package/agents/review/deployment-verification-agent.md +3 -19
  27. package/agents/review/pattern-recognition-specialist.md +4 -20
  28. package/agents/review/performance-oracle.md +3 -31
  29. package/agents/review/project-standards-reviewer.md +5 -5
  30. package/agents/review/schema-drift-detector.md +3 -19
  31. package/agents/review/security-sentinel.md +3 -25
  32. package/agents/review/testing-reviewer.md +3 -3
  33. package/agents/workflow/lint.md +1 -2
  34. package/agents/workflow/pr-comment-resolver.md +54 -22
  35. package/agents/workflow/spec-flow-analyzer.md +2 -25
  36. package/package.json +1 -1
  37. package/skills/agent-native-architecture/SKILL.md +28 -27
  38. package/skills/agent-native-architecture/references/agent-execution-patterns.md +3 -3
  39. package/skills/agent-native-architecture/references/agent-native-testing.md +1 -1
  40. package/skills/agent-native-architecture/references/mobile-patterns.md +1 -1
  41. package/skills/andrew-kane-gem-writer/SKILL.md +5 -5
  42. package/skills/ce-brainstorm/SKILL.md +43 -181
  43. package/skills/ce-compound/SKILL.md +143 -89
  44. package/skills/ce-compound-refresh/SKILL.md +48 -5
  45. package/skills/ce-ideate/SKILL.md +27 -242
  46. package/skills/ce-plan/SKILL.md +165 -81
  47. package/skills/ce-review/SKILL.md +348 -125
  48. package/skills/ce-review/references/findings-schema.json +5 -0
  49. package/skills/ce-review/references/persona-catalog.md +2 -2
  50. package/skills/ce-review/references/resolve-base.sh +5 -2
  51. package/skills/ce-review/references/subagent-template.md +25 -3
  52. package/skills/ce-work/SKILL.md +95 -242
  53. package/skills/ce-work-beta/SKILL.md +154 -301
  54. package/skills/dhh-rails-style/SKILL.md +13 -12
  55. package/skills/document-review/SKILL.md +56 -109
  56. package/skills/document-review/references/findings-schema.json +0 -23
  57. package/skills/document-review/references/subagent-template.md +13 -18
  58. package/skills/dspy-ruby/SKILL.md +8 -8
  59. package/skills/every-style-editor/SKILL.md +3 -2
  60. package/skills/frontend-design/SKILL.md +2 -3
  61. package/skills/git-commit/SKILL.md +1 -1
  62. package/skills/git-commit-push-pr/SKILL.md +81 -265
  63. package/skills/git-worktree/SKILL.md +20 -21
  64. package/skills/lfg/SKILL.md +10 -17
  65. package/skills/onboarding/SKILL.md +2 -2
  66. package/skills/onboarding/scripts/inventory.mjs +31 -7
  67. package/skills/proof/SKILL.md +134 -28
  68. package/skills/resolve-pr-feedback/SKILL.md +7 -2
  69. package/skills/setup/SKILL.md +1 -1
  70. package/skills/test-browser/SKILL.md +10 -11
  71. package/skills/test-xcode/SKILL.md +6 -3
  72. package/dist/lib/manifest.d.ts +0 -39
@@ -5,43 +5,21 @@ description: Commit, push, and open a PR with an adaptive, value-first descripti
5
5
 
6
6
  # Git Commit, Push, and PR
7
7
 
8
- Go from working tree changes to an open pull request in a single workflow, or update an existing PR description. The key differentiator of this skill is PR descriptions that communicate *value and intent* proportional to the complexity of the change.
8
+ Go from working changes to an open pull request, or rewrite an existing PR description.
9
+
10
+ **Asking the user:** When this skill says "ask the user", use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If unavailable, present the question and wait for a reply.
9
11
 
10
12
  ## Mode detection
11
13
 
12
- If the user is asking to update, refresh, or rewrite an existing PR description (with no mention of committing or pushing), this is a **description-only update**. The user may also provide a focus for the update (e.g., "update the PR description and add the benchmarking results"). Note any focus instructions for use in DU-3.
14
+ If the user is asking to update, refresh, or rewrite an existing PR description (with no mention of committing or pushing), this is a **description-only update**. The user may also provide a focus (e.g., "update the PR description and add the benchmarking results"). Note any focus for DU-3.
13
15
 
14
16
  For description-only updates, follow the Description Update workflow below. Otherwise, follow the full workflow.
15
17
 
16
- ## Reusable PR probe
17
-
18
- When checking whether the current branch already has a PR, keep using current-branch `gh pr view` semantics. Do **not** switch to `gh pr list --head "<branch>"` just to avoid the no-PR exit path. That branch-name search can select the wrong PR in multi-fork repos.
19
-
20
- Also do **not** run bare `gh pr view --json ...` in a way that lets the shell tool render the expected no-PR state as a red failed step. Capture the output and exit code yourself so you can interpret "no PR for this branch" as normal workflow state:
21
-
22
- ```bash
23
- if PR_VIEW_OUTPUT=$(gh pr view --json url,title,state 2>&1); then
24
- PR_VIEW_EXIT=0
25
- else
26
- PR_VIEW_EXIT=$?
27
- fi
28
- printf '%s\n__GH_PR_VIEW_EXIT__=%s\n' "$PR_VIEW_OUTPUT" "$PR_VIEW_EXIT"
29
- ```
30
-
31
- Interpret the result this way:
32
-
33
- - `__GH_PR_VIEW_EXIT__=0` and JSON with `state: OPEN` -> an open PR exists for the current branch
34
- - `__GH_PR_VIEW_EXIT__=0` and JSON with a non-OPEN state -> treat as no open PR
35
- - non-zero exit with output indicating `no pull requests found for branch` -> expected no-PR state
36
- - any other non-zero exit -> real error (auth, network, repo config, etc.)
37
-
38
- ---
39
-
40
18
  ## Context
41
19
 
42
20
  **If you are not OpenCode**, skip to the "Context fallback" section below and run the command there to gather context.
43
21
 
44
- **If you are OpenCode**, the six labeled sections below (Git status, Working tree diff, Current branch, Recent commits, Remote default branch, Existing PR check) contain pre-populated data. Use them directly throughout this skill -- do not re-run these commands.
22
+ **If you are OpenCode**, the six labeled sections below contain pre-populated data. Use them directly -- do not re-run these commands.
45
23
 
46
24
  **Git status:**
47
25
  !`git status`
@@ -56,10 +34,10 @@ Interpret the result this way:
56
34
  !`git log --oneline -10`
57
35
 
58
36
  **Remote default branch:**
59
- !`git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo '__DEFAULT_BRANCH_UNRESOLVED__'`
37
+ !`git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo 'DEFAULT_BRANCH_UNRESOLVED'`
60
38
 
61
39
  **Existing PR check:**
62
- !`PR_OUT=$(gh pr view --json url,title,state 2>&1); PR_EXIT=$?; printf '%s\n__GH_PR_VIEW_EXIT__=%s\n' "$PR_OUT" "$PR_EXIT"`
40
+ !`gh pr view --json url,title,state 2>/dev/null || echo 'NO_OPEN_PR'`
63
41
 
64
42
  ### Context fallback
65
43
 
@@ -68,51 +46,44 @@ Interpret the result this way:
68
46
  Run this single command to gather all context:
69
47
 
70
48
  ```bash
71
- printf '=== STATUS ===\n'; git status; printf '\n=== DIFF ===\n'; git diff HEAD; printf '\n=== BRANCH ===\n'; git branch --show-current; printf '\n=== LOG ===\n'; git log --oneline -10; printf '\n=== DEFAULT_BRANCH ===\n'; git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo '__DEFAULT_BRANCH_UNRESOLVED__'; printf '\n=== PR_CHECK ===\n'; PR_OUT=$(gh pr view --json url,title,state 2>&1); PR_EXIT=$?; printf '%s\n__GH_PR_VIEW_EXIT__=%s\n' "$PR_OUT" "$PR_EXIT"
49
+ printf '=== STATUS ===\n'; git status; printf '\n=== DIFF ===\n'; git diff HEAD; printf '\n=== BRANCH ===\n'; git branch --show-current; printf '\n=== LOG ===\n'; git log --oneline -10; printf '\n=== DEFAULT_BRANCH ===\n'; git rev-parse --abbrev-ref origin/HEAD 2>/dev/null || echo 'DEFAULT_BRANCH_UNRESOLVED'; printf '\n=== PR_CHECK ===\n'; gh pr view --json url,title,state 2>/dev/null || echo 'NO_OPEN_PR'
72
50
  ```
73
51
 
74
- Interpret the PR check result using the Reusable PR probe rules above.
75
-
76
52
  ---
77
53
 
78
54
  ## Description Update workflow
79
55
 
80
56
  ### DU-1: Confirm intent
81
57
 
82
- Ask the user to confirm: "Update the PR description for this branch?" Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the question and wait for the user's reply.
83
-
84
- If the user declines, stop.
58
+ Ask the user: "Update the PR description for this branch?" If declined, stop.
85
59
 
86
60
  ### DU-2: Find the PR
87
61
 
88
- Use the current branch and existing PR check from the context above. If the current branch is empty (detached HEAD), report that there is no branch to update and stop.
89
-
90
- Interpret the PR check result using the Reusable PR probe rules above:
91
-
92
- - If it returns PR data with `state: OPEN`, an open PR exists for the current branch.
93
- - If it returns PR data with a non-OPEN state (CLOSED, MERGED), treat this as "no open PR." Report that no open PR exists for this branch and stop.
94
- - If it exits non-zero and the output indicates that no pull request exists for the current branch, treat that as the normal "no PR for this branch" state. Report that no open PR exists for this branch and stop.
95
- - If it errors for another reason (auth, network, repo config), report the error and stop.
62
+ Use the current branch and existing PR check from context. If the current branch is empty (detached HEAD), report no branch and stop. If the PR check returned `state: OPEN`, note the PR `url` from the context block — this is the unambiguous reference to pass downstream — and proceed to DU-3. Otherwise, report no open PR and stop.
96
63
 
97
64
  ### DU-3: Write and apply the updated description
98
65
 
99
- Read the current PR description:
66
+ Read the current PR description to drive the compare-and-confirm step later:
100
67
 
101
68
  ```bash
102
69
  gh pr view --json body --jq '.body'
103
70
  ```
104
71
 
105
- Follow the "Detect the base branch and remote" and "Gather the branch scope" sections of Step 6 to get the full branch diff. Use the PR found in DU-2 as the existing PR for base branch detection. Classify commits per the "Classify commits before writing" section -- this is especially important for description updates, where the recent commits that prompted the update are often fix-up work (code review fixes, lint fixes) rather than feature work. Then write a new description following the writing principles in Step 6, driven by the feature commits and the final diff. If the user provided a focus, incorporate it into the description alongside the branch diff context.
72
+ **Generate the updated title and body** load the `ce-pr-description` skill with the PR URL from DU-2 (e.g., `https://github.com/owner/repo/pull/123`). The URL preserves repo/PR identity even when invoked from a worktree or subdirectory where the current repo is ambiguous. If the user provided a focus (e.g., "include the benchmarking results"), append it as free-text steering after the URL. The skill returns a `{title, body_file}` block (body in an OS temp file) without applying or prompting.
106
73
 
107
- Compare the new description against the current one and summarize the substantial changes for the user (e.g., "Added coverage of the new caching layer, updated test plan, removed outdated migration notes"). If the user provided a focus, confirm it was addressed. Ask the user to confirm before applying. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the summary and wait for the user's reply.
74
+ If `ce-pr-description` returns a "not open" or other graceful-exit message instead of a `{title, body_file}` pair, report that message and stop.
108
75
 
109
- If confirmed, apply:
76
+ **Evidence decision:** `ce-pr-description` preserves any existing `## Demo` or `## Screenshots` block from the current body by default. If the user's focus asks to refresh or remove evidence, pass that intent as steering text — the skill will honor it. If no evidence block exists and one would benefit the reader, invoke `ce-demo-reel` separately to capture, then re-invoke `ce-pr-description` with updated steering that references the captured evidence.
77
+
78
+ **Compare and confirm** — briefly explain what the new description covers differently from the old one. This helps the user decide whether to apply; the description itself does not narrate these differences. Summarize from the body already in context (from the bash call that wrote `body_file`); do not `cat` the temp file, which would re-emit the body.
79
+
80
+ - If the user provided a focus, confirm it was addressed.
81
+ - Ask the user to confirm before applying.
82
+
83
+ If confirmed, apply with the returned title and body file:
110
84
 
111
85
  ```bash
112
- gh pr edit --body "$(cat <<'EOF'
113
- Updated description here
114
- EOF
115
- )"
86
+ gh pr edit --title "<returned title>" --body "$(cat "<returned body_file>")"
116
87
  ```
117
88
 
118
89
  Report the PR URL.
@@ -123,9 +94,9 @@ Report the PR URL.
123
94
 
124
95
  ### Step 1: Gather context
125
96
 
126
- Use the context above (git status, working tree diff, current branch, recent commits, remote default branch, and existing PR check). All data needed for this step and Step 3 is already available -- do not re-run those commands.
97
+ Use the context above. All data needed for this step and Step 3 is already available -- do not re-run those commands.
127
98
 
128
- The remote default branch value returns something like `origin/main`. Strip the `origin/` prefix to get the branch name. If it returned `__DEFAULT_BRANCH_UNRESOLVED__` or a bare `HEAD`, try:
99
+ The remote default branch value returns something like `origin/main`. Strip the `origin/` prefix. If it returned `DEFAULT_BRANCH_UNRESOLVED` or a bare `HEAD`, try:
129
100
 
130
101
  ```bash
131
102
  gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
@@ -133,49 +104,43 @@ gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
133
104
 
134
105
  If both fail, fall back to `main`.
135
106
 
136
- If the current branch from the context above is empty, the repository is in detached HEAD state. Explain that a branch is required before committing and pushing. Ask whether to create a feature branch now. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply.
107
+ If the current branch is empty (detached HEAD), explain that a branch is required. Ask whether to create a feature branch now.
108
+ - If yes, derive a branch name from the change content, create with `git checkout -b <branch-name>`, and use that for the rest of the workflow.
109
+ - If no, stop.
137
110
 
138
- - If the user agrees, derive a descriptive branch name from the change content, create it with `git checkout -b <branch-name>`, then run `git branch --show-current` again and use that result as the current branch name for the rest of the workflow.
139
- - If the user declines, stop.
111
+ If the working tree is clean (no staged, modified, or untracked files), determine the next action:
140
112
 
141
- If the git status from the context above shows a clean working tree (no staged, modified, or untracked files), check whether there are unpushed commits or a missing PR before stopping. The current branch and existing PR check are already available from the context above. Additionally:
113
+ 1. Run `git rev-parse --abbrev-ref --symbolic-full-name @{u}` to check upstream.
114
+ 2. If upstream exists, run `git log <upstream>..HEAD --oneline` for unpushed commits.
142
115
 
143
- 1. Run `git rev-parse --abbrev-ref --symbolic-full-name @{u}` to check whether an upstream is configured.
144
- 2. If the command succeeds, run `git log <upstream>..HEAD --oneline` using the upstream name from the previous command.
116
+ Decision tree:
145
117
 
146
- - If the current branch is `main`, `master`, or the resolved default branch from Step 1 and there is **no upstream** or there are **unpushed commits**, explain that pushing now would use the default branch directly. Ask whether to create a feature branch first. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply.
147
- - If the user agrees, derive a descriptive branch name from the change content, create it with `git checkout -b <branch-name>`, then continue from Step 5 (push).
148
- - If the user declines, report that this workflow cannot open a PR from the default branch directly and stop.
149
- - If there is **no upstream**, treat the branch as needing its first push. Skip Step 4 (commit) and continue from Step 5 (push).
150
- - If there are **unpushed commits**, skip Step 4 (commit) and continue from Step 5 (push).
151
- - If all commits are pushed but **no open PR exists** and the current branch is `main`, `master`, or the resolved default branch from Step 1, report that there is no feature branch work to open as a PR and stop.
152
- - If all commits are pushed but **no open PR exists**, skip Steps 4-5 and continue from Step 6 (write the PR description) and Step 7 (create the PR).
153
- - If all commits are pushed **and an open PR exists**, report that and stop -- there is nothing to do.
118
+ - **On default branch, unpushed commits or no upstream** -- ask whether to create a feature branch (pushing default directly is not supported). If yes, create and continue from Step 5. If no, stop.
119
+ - **On default branch, all pushed, no open PR** -- report no feature branch work. Stop.
120
+ - **Feature branch, no upstream** -- skip Step 4, continue from Step 5.
121
+ - **Feature branch, unpushed commits** -- skip Step 4, continue from Step 5.
122
+ - **Feature branch, all pushed, no open PR** -- skip Steps 4-5, continue from Step 6.
123
+ - **Feature branch, all pushed, open PR** -- report up to date. Stop.
154
124
 
155
125
  ### Step 2: Determine conventions
156
126
 
157
- Follow this priority order for commit messages *and* PR titles:
127
+ Priority order for commit messages and PR titles:
158
128
 
159
- 1. **Repo conventions already in context** -- If project instructions (AGENTS.md, AGENTS.md, or similar) are loaded and specify conventions, follow those. Do not re-read these files; they are loaded at session start.
160
- 2. **Recent commit history** -- If no explicit convention exists, match the pattern visible in the last 10 commits.
161
- 3. **Default: conventional commits** -- `type(scope): description` as the fallback.
129
+ 1. **Repo conventions in context** -- follow project instructions if they specify conventions. Do not re-read; they load at session start.
130
+ 2. **Recent commit history** -- match the pattern in the last 10 commits.
131
+ 3. **Default** -- `type(scope): description` (conventional commits).
162
132
 
163
133
  ### Step 3: Check for existing PR
164
134
 
165
- Use the current branch and existing PR check from the context above. If the current branch is empty, report that the workflow is in detached HEAD state and stop.
166
-
167
- Interpret the PR check result using the Reusable PR probe rules:
135
+ Use the current branch and existing PR check from context. If the branch is empty, report detached HEAD and stop.
168
136
 
169
- - If it **returns PR data with `state: OPEN`**, an open PR exists for the current branch. Note the URL and continue to Step 4 (commit) and Step 5 (push). Then skip to Step 7 (existing PR flow) instead of creating a new PR.
170
- - If it **returns PR data with a non-OPEN state** (CLOSED, MERGED), treat this the same as "no PR exists" -- the previous PR is done and a new one is needed. Continue to Step 4 through Step 8 as normal.
171
- - If it **exits non-zero and the output indicates that no pull request exists for the current branch**, no PR exists. Continue to Step 4 through Step 8 as normal.
172
- - If it **errors** (auth, network, repo config), report the error to the user and stop.
137
+ If the PR check returned `state: OPEN`, note the URL -- this is the existing-PR flow. Continue to Step 4 and 5 (commit any pending work and push), then go to Step 7 to ask whether to rewrite the description. Only run Step 6 (which generates a new description via `ce-pr-description`) if the user confirms the rewrite; Step 7's existing-PR sub-path consumes the `{title, body_file}` that Step 6 produces. Otherwise (no open PR), continue through Steps 6, 7, and 8 in order.
173
138
 
174
139
  ### Step 4: Branch, stage, and commit
175
140
 
176
- 1. If the current branch from the context above is `main`, `master`, or the resolved default branch from Step 1, create a descriptive feature branch first with `git checkout -b <branch-name>`. Derive the branch name from the change content.
177
- 2. Before staging everything together, scan the changed files for naturally distinct concerns. If modified files clearly group into separate logical changes (e.g., a refactor in one set of files and a new feature in another), create separate commits for each group. Keep this lightweight -- group at the **file level only** (no `git add -p`), split only when obvious, and aim for two or three logical commits at most. If it's ambiguous, one commit is fine.
178
- 3. For each commit group, stage and commit in a single call. Avoid `git add -A` or `git add .` to prevent accidentally including sensitive files. Follow the conventions from Step 2. Use a heredoc for the message:
141
+ 1. If on the default branch, create a feature branch first with `git checkout -b <branch-name>`.
142
+ 2. Scan changed files for naturally distinct concerns. If files clearly group into separate logical changes, create separate commits (2-3 max). Group at the file level only (no `git add -p`). When ambiguous, one commit is fine.
143
+ 3. Stage and commit each group in a single call. Avoid `git add -A` or `git add .`. Follow conventions from Step 2:
179
144
  ```bash
180
145
  git add file1 file2 file3 && git commit -m "$(cat <<'EOF'
181
146
  commit message here
@@ -189,231 +154,82 @@ Interpret the PR check result using the Reusable PR probe rules:
189
154
  git push -u origin HEAD
190
155
  ```
191
156
 
192
- ### Step 6: Write the PR description
157
+ ### Step 6: Generate the PR title and body
193
158
 
194
- Before writing, determine the **base branch** and gather the **full branch scope**. The working-tree diff from Step 1 only shows uncommitted changes at invocation time -- the PR description must cover **all commits** that will appear in the PR.
159
+ The working-tree diff from Step 1 only shows uncommitted changes at invocation time. The PR description must cover **all commits** in the PR.
195
160
 
196
- #### Detect the base branch and remote
161
+ **Detect the base branch and remote.** Resolve both the base branch and the remote (fork-based PRs may use a remote other than `origin`). Stop at the first that succeeds:
197
162
 
198
- Resolve the base branch **and** the remote that hosts it. In fork-based PRs the base repository may correspond to a remote other than `origin` (commonly `upstream`).
199
-
200
- Use this fallback chain. Stop at the first that succeeds:
201
-
202
- 1. **PR metadata** (if an existing PR was found in Step 3):
163
+ 1. **PR metadata** (if existing PR found in Step 3):
203
164
  ```bash
204
165
  gh pr view --json baseRefName,url
205
166
  ```
206
- Extract `baseRefName` as the base branch name. The PR URL contains the base repository (`https://github.com/<owner>/<repo>/pull/...`). Determine which local remote corresponds to that repository:
207
- ```bash
208
- git remote -v
209
- ```
210
- Match the `owner/repo` from the PR URL against the fetch URLs. Use the matching remote as the base remote. If no remote matches, fall back to `origin`.
211
- 2. **Remote default branch from context above:** If the remote default branch resolved (not `__DEFAULT_BRANCH_UNRESOLVED__`), strip the `origin/` prefix and use that. Use `origin` as the base remote.
212
- 3. **GitHub default branch metadata:**
167
+ Extract `baseRefName`. Match `owner/repo` from the PR URL against `git remote -v` fetch URLs to find the base remote. Fall back to `origin`.
168
+ 2. **Remote default branch from context** -- if resolved, strip `origin/` prefix. Use `origin`.
169
+ 3. **GitHub metadata:**
213
170
  ```bash
214
171
  gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
215
172
  ```
216
- Use `origin` as the base remote.
217
- 4. **Common branch names** -- check `main`, `master`, `develop`, `trunk` in order. Use the first that exists on the remote:
173
+ Use `origin`.
174
+ 4. **Common names** -- check `main`, `master`, `develop`, `trunk` in order:
218
175
  ```bash
219
176
  git rev-parse --verify origin/<candidate>
220
177
  ```
221
- Use `origin` as the base remote.
222
-
223
- If none resolve, ask the user to specify the target branch. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the options and wait for the user's reply.
178
+ Use `origin`.
224
179
 
225
- #### Gather the branch scope
226
-
227
- Once the base branch and remote are known, gather the full scope in as few calls as possible.
228
-
229
- First, verify the remote-tracking ref exists and fetch if needed:
230
-
231
- ```bash
232
- git rev-parse --verify <base-remote>/<base-branch> 2>/dev/null || git fetch --no-tags <base-remote> <base-branch>
233
- ```
180
+ If none resolve, ask the user to specify the target branch.
234
181
 
235
- Then gather the merge base, commit list, and full diff in a single call:
182
+ **Gather the full branch diff (before evidence decision).** The working-tree diff from Step 1 only reflects uncommitted changes at invocation time — on the common "feature branch, all pushed, open PR" path, Step 1 skips the commit/push steps and the working-tree diff is empty. The evidence decision below needs the real branch diff to judge whether behavior is observable, so compute it explicitly against the base resolved above. Only fetch when the local ref isn't available — if `<base-remote>/<base-branch>` already resolves locally, run the diff from local state so offline / restricted-network / expired-auth environments don't hard-fail:
236
183
 
237
184
  ```bash
238
- MERGE_BASE=$(git merge-base <base-remote>/<base-branch> HEAD) && echo "MERGE_BASE=$MERGE_BASE" && echo '=== COMMITS ===' && git log --oneline $MERGE_BASE..HEAD && echo '=== DIFF ===' && git diff $MERGE_BASE...HEAD
185
+ git rev-parse --verify <base-remote>/<base-branch> >/dev/null 2>&1 \
186
+ || git fetch --no-tags <base-remote> <base-branch>
187
+ git diff <base-remote>/<base-branch>...HEAD
239
188
  ```
240
189
 
241
- Use the full branch diff and commit list as the basis for the PR description -- not the working-tree diff from Step 1.
190
+ Use this branch diff (not the working-tree diff) for the evidence decision. If the branch diff is empty (e.g., HEAD is already merged into the base or the branch has no unique commits), skip the evidence prompt and continue to delegation.
242
191
 
243
- #### Classify commits before writing
192
+ **Evidence decision (before delegation).** If the branch diff changes observable behavior (UI, CLI output, API behavior with runnable code, generated artifacts, workflow output) and evidence is not otherwise blocked (unavailable credentials, paid services, deploy-only infrastructure, hardware), ask: "This PR has observable behavior. Capture evidence for the PR description?"
244
193
 
245
- Before writing the description, scan the commit list and classify each commit:
194
+ - **Capture now** -- load the `ce-demo-reel` skill with a target description inferred from the branch diff. ce-demo-reel returns `Tier`, `Description`, and `URL`. Note the captured evidence so it can be passed as free-text steering to `ce-pr-description` (e.g., "include the captured demo: <URL> as a `## Demo` section") or spliced into the returned body before apply. If capture returns `Tier: skipped` or `URL: "none"`, proceed with no evidence.
195
+ - **Use existing evidence** -- ask for the URL or markdown embed, then pass it as free-text steering to `ce-pr-description` or splice in before apply.
196
+ - **Skip** -- proceed with no evidence section.
246
197
 
247
- - **Feature commits** -- implement the purpose of the PR (new functionality, intentional refactors, design changes). These drive the description.
248
- - **Fix-up commits** -- work product of getting the branch ready: code review fixes, lint/type error fixes, test fixes, rebase conflict resolutions, style cleanups, typo corrections in the new code. These are invisible to the reader.
198
+ When evidence is not possible (docs-only, markdown-only, changelog-only, release metadata, CI/config-only, test-only, or pure internal refactors), skip without asking.
249
199
 
250
- Only feature commits inform the description. Fix-up commits are noise -- they describe the iteration process, not the end result. The full diff already includes whatever the fix-up commits changed, so their intent is captured without narrating them. When sizing and writing the description, mentally subtract fix-up commits: a branch with 12 commits but 9 fix-ups is a 3-commit PR in terms of description weight.
200
+ **Delegate title and body generation to `ce-pr-description`.** Load the `ce-pr-description` skill:
251
201
 
252
- This is the most important step. The description must be **adaptive** -- its depth should match the complexity of the change. A one-line bugfix does not need a table of performance results. A large architectural change should not be a bullet list.
202
+ - **For a new PR** (no existing PR found in Step 3): invoke with `base:<base-remote>/<base-branch>` using the already-resolved base from earlier in this step, so `ce-pr-description` describes the correct commit range even when the branch targets a non-default base (e.g., `develop`, `release/*`). Append any captured-evidence context or user focus as free-text steering (e.g., "include the captured demo: <URL> as a `## Demo` section").
203
+ - **For an existing PR** (found in Step 3): invoke with the full PR URL from the Step 3 context (e.g., `https://github.com/owner/repo/pull/123`). The URL preserves repo/PR identity even when invoked from a worktree or subdirectory; the skill reads the PR's own `baseRefName` so no `base:` override is needed. Append any focus steering as free text after the URL.
253
204
 
254
- #### Sizing the change
255
-
256
- Assess the PR along two axes before writing, based on the full branch diff:
257
-
258
- - **Size**: How many files changed? How large is the diff?
259
- - **Complexity**: Is this a straightforward change (rename, dependency bump, typo fix) or does it involve design decisions, trade-offs, new patterns, or cross-cutting concerns?
260
-
261
- Use this to select the right description depth:
262
-
263
- | Change profile | Description approach |
264
- |---|---|
265
- | Small + simple (typo, config, dep bump) | 1-2 sentences, no headers. Total body under ~300 characters. |
266
- | Small + non-trivial (targeted bugfix, behavioral change) | Short "Problem / Fix" narrative, ~3-5 sentences. Enough for a reviewer to understand *why* without reading the diff. No headers needed unless there are two distinct concerns. |
267
- | Medium feature or refactor | Summary paragraph, then a section explaining what changed and why. Call out design decisions. |
268
- | Large or architecturally significant | Full narrative: problem context, approach chosen (and why), key decisions, migration notes or rollback considerations if relevant. |
269
- | Performance improvement | Include before/after measurements if available. A markdown table is effective here. |
270
-
271
- **Brevity matters for small changes.** A 3-line bugfix with a 20-line PR description signals the author didn't calibrate. Match the weight of the description to the weight of the change. When in doubt, shorter is better -- reviewers can read the diff.
272
-
273
- #### Writing principles
274
-
275
- - **Lead with value**: The first sentence should tell the reviewer *why this PR exists*, not *what files changed*. "Fixes timeout errors during batch exports" beats "Updated export_handler.py and config.yaml".
276
- - **No orphaned opening paragraphs**: If the description uses `##` section headings anywhere, the opening summary must also be under a heading (e.g., `## Summary`). An untitled paragraph followed by titled sections looks like a missing heading. For short descriptions with no sections, a bare paragraph is fine.
277
- - **Describe the net result, not the journey**: The PR description is about the end state -- what changed and why. Do not include work-product details like bugs found and fixed during development, intermediate failures, debugging steps, iteration history, or refactoring done along the way. Those are part of getting the work done, not part of the result. If a bug fix happened during development, the fix is already in the diff -- mentioning it in the description implies it's a separate concern the reviewer should evaluate, when really it's just part of the final implementation. Exception: include process details only when they are critical for a reviewer to understand a design choice (e.g., "tried approach X first but it caused Y, so went with Z instead").
278
- - **When commits conflict, trust the final diff**: The commit list is supporting context, not the source of truth for the final PR description. If commit messages describe intermediate steps that were later revised or reverted (for example, "switch to gh pr list" followed by a later change back to `gh pr view`), describe the end state shown by the full branch diff. Do not narrate contradictory commit history as if all of it shipped.
279
- - **Explain the non-obvious**: If the diff is self-explanatory, don't narrate it. Spend description space on things the diff *doesn't* show: why this approach, what was considered and rejected, what the reviewer should pay attention to.
280
- - **Use structure when it earns its keep**: Headers, bullet lists, and tables are tools -- use them when they aid comprehension, not as mandatory template sections. An empty "## Breaking Changes" section adds noise.
281
- - **Markdown tables for data**: When there are before/after comparisons, performance numbers, or option trade-offs, a table communicates density well. Example:
282
-
283
- ```markdown
284
- | Metric | Before | After |
285
- |--------|--------|-------|
286
- | p95 latency | 340ms | 120ms |
287
- | Memory (peak) | 2.1GB | 1.4GB |
288
- ```
205
+ `ce-pr-description` returns a `{title, body_file}` block (body in an OS temp file). It applies the value-first writing principles, commit classification, sizing, narrative framing, writing voice, visual communication, numbering rules, and the Systematic badge footer internally. Use the returned values verbatim in Step 7; do not layer manual edits onto them unless a focused adjustment is required (e.g., splicing an evidence block captured in this step that was not passed as steering text — in that case, edit the body file directly before applying).
289
206
 
290
- - **No empty sections**: If a section (like "Breaking Changes" or "Migration Guide") doesn't apply, omit it entirely. Do not include it with "N/A" or "None".
291
- - **Test plan -- only when it adds value**: Include a test plan section when the testing approach is non-obvious: edge cases the reviewer might not think of, verification steps for behavior that's hard to see in the diff, or scenarios that require specific setup. Omit it for straightforward changes where the tests are self-explanatory or where "run the tests" is the only useful guidance. A test plan for "verify the typo is fixed" is noise.
292
-
293
- #### Visual communication
294
-
295
- Include a visual aid when the PR changes something structurally complex enough that a reviewer would struggle to reconstruct the mental model from prose alone. Visual aids are conditional on content patterns -- what the PR changes -- not on PR size. A small PR that restructures a complex workflow may warrant a diagram; a large mechanical refactor may not.
296
-
297
- The bar for including visual aids in PR descriptions is higher than in brainstorms or plans. Reviewers scan PR descriptions to orient before reading the diff -- visuals must earn their space quickly.
298
-
299
- **When to include:**
300
-
301
- | PR changes... | Visual aid | Placement |
302
- |---|---|---|
303
- | Architecture touching 3+ interacting components or services | Mermaid component or interaction diagram | Within the approach or changes section |
304
- | A multi-step workflow, pipeline, or data flow with non-obvious sequencing | Mermaid flow diagram | After the summary or within the changes section |
305
- | 3+ behavioral modes, states, or variants being introduced or changed | Markdown comparison table | Within the relevant section |
306
- | Before/after performance data, behavioral differences, or option trade-offs | Markdown table (see the "Markdown tables for data" writing principle above) | Inline with the data being discussed |
307
- | Data model changes with 3+ related entities or relationship changes | Mermaid ERD or relationship diagram | Within the changes section |
308
-
309
- **When to skip:**
310
- - The change is trivial -- if the sizing table routes to "1-2 sentences", skip visual aids
311
- - Prose already communicates the change clearly
312
- - The diagram would just restate the diff in visual form without adding comprehension value
313
- - The change is mechanical (renames, dependency bumps, config changes, formatting)
314
- - The PR description is already short enough that a diagram would be heavier than the prose around it
315
-
316
- **Format selection:**
317
- - **Mermaid** (default) for flow diagrams, interaction diagrams, and dependency graphs -- 5-10 nodes typical for a PR description, up to 15 only for genuinely complex changes. Use `TB` (top-to-bottom) direction so diagrams stay narrow in both rendered and source form. Source should be readable as fallback in diff views, email notifications, and Slack previews.
318
- - **ASCII/box-drawing diagrams** for annotated flows that need rich in-box content -- decision logic branches, file path layouts, step-by-step transformations with annotations. More expressive than mermaid when the diagram's value comes from annotations within steps. Follow 80-column max for code blocks, use vertical stacking.
319
- - **Markdown tables** for mode/variant comparisons, before/after data, and decision matrices.
320
- - Keep diagrams proportionate to the change. A PR touching a 5-component interaction gets 5-8 nodes. A larger architectural change may need 10-15 nodes -- that is fine if every node earns its place.
321
- - Place inline at the point of relevance within the description, not in a separate "Diagrams" section.
322
- - Prose is authoritative: when a visual aid and surrounding description prose disagree, the prose governs.
323
-
324
- After generating a visual aid, verify it accurately represents the change described in the PR -- correct components, no missing interactions, no merged steps. Diagrams derived from a diff (rather than from code analysis) carry higher inaccuracy risk.
325
-
326
- #### Numbering and references
327
-
328
- **Never prefix list items with `#`** in PR descriptions. GitHub interprets `#1`, `#2`, etc. as issue/PR references and auto-links them. Instead of:
329
-
330
- ```markdown
331
- ## Changes
332
- #1. Updated the parser
333
- #2. Fixed the validation
334
- ```
335
-
336
- Write:
337
-
338
- ```markdown
339
- ## Changes
340
- 1. Updated the parser
341
- 2. Fixed the validation
342
- ```
343
-
344
- When referencing actual GitHub issues or PRs, use the full format: `org/repo#123` or the full URL. Never use bare `#123` unless you have verified it refers to the correct issue in the current repository.
345
-
346
- #### Systematic badge
347
-
348
- Append a badge footer to the PR description, separated by a `---` rule. Do not add one if the description already contains a Systematic badge (e.g., added by another skill like ce-work).
349
-
350
- **Plugin version (pre-resolved):** !`jq -r .version "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json"`
351
-
352
- If the line above resolved to a semantic version (e.g., `2.42.0`), use it as `[VERSION]` in the versioned badge below. Otherwise (empty, a literal command string, or an error), use the versionless badge. Do not attempt to resolve the version at runtime.
353
-
354
- **Versioned badge** (when version resolved above):
355
-
356
- ```markdown
357
- ---
358
-
359
- [![Systematic v[VERSION]](https://img.shields.io/badge/Systematic-v[VERSION]-6366f1)](https://github.com/marcusrbrown/systematic)
360
- 🤖 Generated with [MODEL] ([CONTEXT] context, [THINKING]) via [HARNESS](HARNESS_URL)
361
- ```
362
-
363
- **Versionless badge** (when version is not available):
364
-
365
- ```markdown
366
- ---
367
-
368
- [![Systematic](https://img.shields.io/badge/Systematic-6366f1)](https://github.com/marcusrbrown/systematic)
369
- 🤖 Generated with [MODEL] ([CONTEXT] context, [THINKING]) via [HARNESS](HARNESS_URL)
370
- ```
371
-
372
- Fill in at PR creation time:
373
-
374
- | Placeholder | Value | Example |
375
- |-------------|-------|---------|
376
- | `[MODEL]` | Model name | Claude Opus 4.6, GPT-5.4 |
377
- | `[CONTEXT]` | Context window (if known) | 200K, 1M |
378
- | `[THINKING]` | Thinking level (if known) | extended thinking |
379
- | `[HARNESS]` | Tool running you | OpenCode, Codex, Gemini CLI |
380
- | `[HARNESS_URL]` | Link to that tool | `https://opencode.ai` |
207
+ If `ce-pr-description` returns a graceful-exit message instead of `{title, body_file}` (e.g., closed PR, no commits to describe, base ref unresolved), report the message and stop do not create or edit the PR.
381
208
 
382
209
  ### Step 7: Create or update the PR
383
210
 
384
211
  #### New PR (no existing PR from Step 3)
385
212
 
386
- ```bash
387
- gh pr create --title "the pr title" --body "$(cat <<'EOF'
388
- PR description here
213
+ Using the `{title, body_file}` returned by `ce-pr-description`:
389
214
 
390
- ---
391
-
392
- [BADGE LINE FROM BADGE SECTION ABOVE]
393
- 🤖 Generated with [MODEL] ([CONTEXT] context, [THINKING]) via [HARNESS](HARNESS_URL)
394
- EOF
395
- )"
215
+ ```bash
216
+ gh pr create --title "<returned title>" --body "$(cat "<returned body_file>")"
396
217
  ```
397
218
 
398
- Use the versioned or versionless badge line resolved in the Systematic badge section above.
399
-
400
- Keep the PR title under 72 characters. The title follows the same convention as commit messages (Step 2).
219
+ Keep the title under 72 characters; `ce-pr-description` already emits a conventional-commit title in that range.
401
220
 
402
221
  #### Existing PR (found in Step 3)
403
222
 
404
- The new commits are already on the PR from the push in Step 5. Report the PR URL, then ask the user whether they want the PR description updated to reflect the new changes. Use the platform's blocking question tool (`question` in OpenCode, `request_user_input` in Codex, `ask_user` in Gemini). If no question tool is available, present the option and wait for the user's reply before proceeding.
223
+ The new commits are already on the PR from Step 5. Report the PR URL, then ask whether to rewrite the description.
405
224
 
406
- - If **yes** -- write a new description following the same principles in Step 6 (size the full PR, not just the new commits). Classify commits per "Classify commits before writing" -- the new commits since the last push are often fix-up work (code review fixes, lint fixes) and should not appear as distinct items in the updated description. Describe the PR's net result as if writing it fresh. Include the Systematic badge unless one is already present in the existing description. Apply it:
225
+ - If **yes**, run Step 6 now to generate `{title, body_file}` via `ce-pr-description` (passing the existing PR URL as `pr:`), then apply the returned title and body file:
407
226
 
408
227
  ```bash
409
- gh pr edit --body "$(cat <<'EOF'
410
- Updated description here
411
- EOF
412
- )"
228
+ gh pr edit --title "<returned title>" --body "$(cat "<returned body_file>")"
413
229
  ```
414
230
 
415
- - If **no** -- done. The push was all that was needed.
231
+ - If **no** -- skip Step 6 entirely and finish. Do not run delegation or evidence capture when the user declined the rewrite.
416
232
 
417
233
  ### Step 8: Report
418
234
 
419
- Output the PR URL so the user can navigate to it directly.
235
+ Output the PR URL.