@gobing-ai/spur 0.4.9 → 0.4.11
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/rules/README.md +1 -1
- package/config/rules/boundary/env-var-hygiene.yaml +0 -1
- package/config/rules/boundary/sp-script-placement.yaml +3 -3
- package/config/rules/docs/sourced-api-claims.yaml +23 -96
- package/config/workflows/feature-verification.yaml +1 -9
- package/config/workflows/pr-review.yaml +72 -224
- package/config/workflows/task-pipeline.yaml +2 -2
- package/package.json +1 -1
- package/plugins/sp/agents/expert-spur.md +0 -1
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-pr-review.md +27 -17
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/brainstorm/SKILL.md +12 -11
- package/plugins/sp/skills/brainstorm/agents/openai.yaml +1 -1
- package/plugins/sp/skills/brainstorm/examples/ideation-example.md +0 -4
- package/plugins/sp/skills/brainstorm/metadata.openclaw +1 -1
- package/plugins/sp/skills/brainstorm/references/workflows.md +4 -14
- package/plugins/sp/skills/code-verification/references/secu-review.md +7 -4
- package/plugins/sp/skills/history-anatomy/references/operations.md +3 -4
- package/plugins/sp/skills/history-anatomy/references/report-contract.md +2 -3
- package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
- package/plugins/sp/skills/parallel-execution/SKILL.md +1 -1
- package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +9 -10
- package/plugins/sp/skills/pr-reviewing/SKILL.md +157 -210
- package/plugins/sp/skills/reverse-engineering/SKILL.md +4 -6
- package/plugins/sp/skills/session-review/SKILL.md +10 -26
- package/plugins/sp/skills/source-driven-development/SKILL.md +35 -31
- package/plugins/sp/skills/spur-cli/SKILL.md +1 -1
- package/plugins/sp/skills/spur-cli/references/agent.md +5 -2
- package/plugins/sp/skills/spur-cli/references/builder.md +86 -13
- package/plugins/sp/skills/spur-cli/references/features.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +1 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +5 -6
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +1 -1
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +3 -2
- package/spur.js +1280 -417
- package/web/_astro/{BoardApp.CaNvQBD_.js → BoardApp.B5rTVNd_.js} +1 -1
- package/web/_astro/{BoardApp.C5jnkkKP.js → BoardApp.BMprmPRc.js} +141 -141
- package/web/_astro/{TaskDetail.DGKndhI8.js → TaskDetail.Ddsur8qd.js} +1 -1
- package/web/_astro/{arc.DHrwdg3G.js → arc.DLqVVBxP.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.pvKpK1s5.js → architectureDiagram-3BPJPVTR.C-Pk3uAi.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.BQmRcZsS.js → blockDiagram-GPEHLZMM.BRO1i_Nm.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.CCLjHeH1.js → c4Diagram-AAUBKEIU.BU_cWu6e.js} +1 -1
- package/web/_astro/channel.Bs3Illhy.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.DL6Yuoma.js → chunk-2J33WTMH.D2VXiQ2t.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.CzlyEI7l.js → chunk-4BX2VUAB.BcHT772J.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.B60EWxp1.js → chunk-55IACEB6.DhDtICmo.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.c7v_fRLo.js → chunk-727SXJPM.BoKHp7gV.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.8BxLWdDc.js → chunk-AQP2D5EJ.Chu4JRpE.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DmKuxGFT.js → chunk-FMBD7UC4.wHdwKPlq.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.1Zwd4mqV.js → chunk-ND2GUHAM.ffN-M1JB.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BvYLu-A1.js → chunk-QZHKN3VN.FRubwg4S.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.CEqRt0WU.js → classDiagram-4FO5ZUOK.c22tQsc_.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.CEqRt0WU.js → classDiagram-v2-Q7XG4LA2.c22tQsc_.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.C7JiUdj2.js → cose-bilkent-S5V4N54A.B9c6fiSj.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.B6mZ-1be.js → cynefin-OW5HDTMX.DrZsrUHl.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.BuryfDy6.js → dagre-BM42HDAG.DG1U4b3y.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.dao39YQM.js → diagram-2AECGRRQ.CH15b-K3.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.lnGZe4At.js → diagram-5GNKFQAL.BH1j7twR.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.uWfhzEfT.js → diagram-KO2AKTUF.q2zCkbAj.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.ppq8-198.js → diagram-LMA3HP47.BLaaZnHV.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.CKSCqDt5.js → diagram-OG6HWLK6.BcpRdQwI.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.sFSf2yBN.js → erDiagram-TEJ5UH35.D7KBlqfM.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.BJQjKLbz.js → flowDiagram-I6XJVG4X.D_gmuRqg.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DAHKNj2N.js → ganttDiagram-6RSMTGT7.DzgWYniD.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.BlmzcW_O.js → gitGraphDiagram-PVQCEYII.576i3hm3.js} +1 -1
- package/web/_astro/index.DiC1a6lh.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.DGhjaqsi.js → infoDiagram-5YYISTIA.DMCclBiz.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.gKIpgt6F.js → ishikawaDiagram-YF4QCWOH.9Kyca4SH.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.DG3tmP0R.js → journeyDiagram-JHISSGLW.chbdG-8q.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.CgHDSxkR.js → kanban-definition-UN3LZRKU.Bds54-e0.js} +1 -1
- package/web/_astro/{linear.BuGEpcuM.js → linear.D5ND9GN_.js} +1 -1
- package/web/_astro/{mermaid.core.DBVqkWBp.js → mermaid.core.D9N_PGbj.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.D-kOcji9.js → mindmap-definition-RKZ34NQL.t0xop5vp.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.BvGPwtZt.js → pieDiagram-4H26LBE5.DqgKh6hM.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.BKb_9FV6.js → quadrantDiagram-W4KKPZXB.DeuHVi2t.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.Cx0fvD8v.js → requirementDiagram-4Y6WPE33.BdYFSG4W.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.fatULi0W.js → sankeyDiagram-5OEKKPKP.k1LPPETJ.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.ChHyKqco.js → sequenceDiagram-3UESZ5HK.DdyfpzoG.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BdUpKWyj.js → stateDiagram-AJRCARHV.DSEI8il0.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.fmJxqIm5.js → stateDiagram-v2-BHNVJYJU.CoMnQRKo.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BayDn5-V.js → timeline-definition-PNZ67QCA.DM1AHNm-.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.Bm2Aggwa.js → vennDiagram-CIIHVFJN.C-cJmVtl.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DI75O-uG.js → wardleyDiagram-YWT4CUSO.D0xMzKPb.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DL90E7Q7.js → xychartDiagram-2RQKCTM6.BH5xJcEq.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/channel.C7wG9RxA.js +0 -1
- package/web/_astro/index.BCY1JJHd.css +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pr-reviewing
|
|
3
|
-
description: "
|
|
3
|
+
description: "Local-first PR review — status, a local /sp:dev-review of the branch diff, and validated fixes; `--codex` opts into the GitHub Codex review spine. Backs /sp:dev-pr-review. Triggers: PR review, codex review, @codex review, review my PR, dev-pr-review."
|
|
4
4
|
license: Apache-2.0
|
|
5
|
-
version:
|
|
5
|
+
version: 2.0.0
|
|
6
6
|
metadata:
|
|
7
7
|
author: spur
|
|
8
8
|
platforms: "claude-code,codex,openclaw,opencode,antigravity,pi"
|
|
@@ -11,12 +11,12 @@ metadata:
|
|
|
11
11
|
- workflow
|
|
12
12
|
- review
|
|
13
13
|
pipeline_steps:
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- collect
|
|
14
|
+
- status
|
|
15
|
+
- check
|
|
16
|
+
- review
|
|
17
|
+
- open
|
|
19
18
|
- triage
|
|
19
|
+
- fix
|
|
20
20
|
see_also:
|
|
21
21
|
- sp:code-verification
|
|
22
22
|
- sp:functional-review
|
|
@@ -24,11 +24,12 @@ see_also:
|
|
|
24
24
|
- sp:spur-dev
|
|
25
25
|
---
|
|
26
26
|
|
|
27
|
-
# sp:pr-reviewing —
|
|
27
|
+
# sp:pr-reviewing — Local-First PR Review
|
|
28
28
|
|
|
29
|
-
Backend for `/sp:dev-pr-review`.
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
Backend for `/sp:dev-pr-review`. Local-first by default: `status` is a read-only snapshot and
|
|
30
|
+
`review` reviews the branch diff locally with `/sp:dev-review`. `review --codex` opts into the
|
|
31
|
+
GitHub Codex review on the pull request; `fix` triages and fixes findings from either reviewer. The
|
|
32
|
+
invoking coding agent is the local orchestrator and implementer.
|
|
32
33
|
|
|
33
34
|
## Architecture
|
|
34
35
|
|
|
@@ -36,193 +37,155 @@ that review effort happens on the PR, through Codex — not in the local session
|
|
|
36
37
|
/sp:dev-pr-review (thin command)
|
|
37
38
|
│ Skill(skill="sp:pr-reviewing", args=...)
|
|
38
39
|
▼
|
|
39
|
-
sp:pr-reviewing (this skill — mode routing, triage, fix
|
|
40
|
-
│
|
|
41
|
-
|
|
42
|
-
pr-review.yaml ← workflow SSOT (seeded by spur init; project-tunable)
|
|
43
|
-
│ every deterministic action shells out to:
|
|
40
|
+
sp:pr-reviewing (this skill — mode routing, local-review dispatch, triage, fix)
|
|
41
|
+
│ local route: pr-check --scan-only → git diff --name-only → /sp:dev-review
|
|
42
|
+
│ Codex route: pr-review.yaml (check → precheck → open → review)
|
|
44
43
|
▼
|
|
45
|
-
`spur builder pr
|
|
44
|
+
`spur builder pr-<verb>` + `spur builder show-branches` ← tested git/gh core
|
|
46
45
|
```
|
|
47
46
|
|
|
48
|
-
- **State order and guards** are defined once, in
|
|
49
|
-
prose; when the YAML and this file disagree, the YAML wins and this file gets
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
the workflow `mode` variable.
|
|
57
|
-
|
|
58
|
-
## Non-negotiable Codex routing
|
|
59
|
-
|
|
60
|
-
The external review MUST go through the GitHub pull request and an `@codex review` request.
|
|
61
|
-
Never substitute a local Codex review mechanism — no Codex CLI `/review`, no `codex review`, no
|
|
62
|
-
vendor-specific local review commands. If GitHub Codex Code Review is unavailable, stop and report
|
|
63
|
-
the setup/access problem; never silently fall back to a local review.
|
|
64
|
-
|
|
65
|
-
Never claim a request consumed a specific billing/quota bucket unless the platform exposes that
|
|
66
|
-
fact. The guarantee of this workflow is the route: GitHub Codex Code Review on the PR.
|
|
47
|
+
- **State order and guards** for the Codex route are defined once, in `pr-review.yaml`. Do not
|
|
48
|
+
re-derive them in prose; when the YAML and this file disagree, the YAML wins and this file gets
|
|
49
|
+
fixed.
|
|
50
|
+
- **Deterministic work** (every git/gh call) goes through the four flat `spur builder pr-<verb>`
|
|
51
|
+
commands and `spur builder show-branches` — never hand-rolled `gh` invocations that drift from
|
|
52
|
+
the tested core.
|
|
53
|
+
- **Model-bearing work** (the local review dispatch, finding triage, `fix` edits) is this skill's
|
|
54
|
+
job and never enters the workflow machine.
|
|
67
55
|
|
|
68
56
|
## Modes and routing
|
|
69
57
|
|
|
70
|
-
Parse the first positional argument as the mode; default `
|
|
58
|
+
Parse the first positional argument as the mode; default `status`.
|
|
71
59
|
|
|
72
60
|
| Mode | Route | Behavior |
|
|
73
61
|
| --- | --- | --- |
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
62
|
+
| `status` | direct CLI | `spur builder show-branches --base <b> --pr --format markdown`, with the report filtered to the current branch and its base, plus `spur builder pr-status --json` (PR number, CI, local changes, latest current-head review in `.review`). Read-only. |
|
|
63
|
+
| `review` | local stack | `spur builder pr-check --base <b> --scan-only --json`; `BLOCK` stops, `WARN` is reported. Then `git diff --name-only <b>...HEAD` → `/sp:dev-review --scope <comma-joined paths> --focus <focus>`. An empty diff ends with "nothing to review". Posts nothing to GitHub. |
|
|
64
|
+
| `review --codex` | `pr-review.yaml` | Run the spine with `mode=full`; `--force` → `mode=rerun`; `--no-wait` → `mode=submit`; `focus`/`baseBranch` passed as vars. States: check → precheck → open → review. `pending` is reported as pending, never failure. |
|
|
65
|
+
| `fix` | direct verb + model work | Findings from the latest local review verdict, or from `spur builder pr-status --json` `.review` when the last review was Codex. Validate each finding against the code before editing; rejected findings are listed with a reason. Fix the legitimate ones, run the project gate, make one focused commit and push without force (`spur builder pr-open` handles a first push). |
|
|
66
|
+
|
|
67
|
+
Retired modes print one notice line and run their replacement: `full` → `review --codex`;
|
|
68
|
+
`submit` → `review --codex --no-wait`; `rerun` → `review --codex --force`; `collect` → `status`.
|
|
69
|
+
`rules` prints a notice that `AGENTS.md` review-rule authoring belongs to `cc:cc-magents` (in the
|
|
70
|
+
`cc` plugin, not `sp`) and exits.
|
|
81
71
|
|
|
82
72
|
## Arguments
|
|
83
73
|
|
|
84
|
-
- `--
|
|
85
|
-
- `--
|
|
74
|
+
- `--codex` — run `review` through the GitHub Codex spine instead of the local stack.
|
|
75
|
+
- `--force` — with `--codex`, request a fresh review of the current HEAD even when it was already
|
|
76
|
+
reviewed.
|
|
77
|
+
- `--no-wait` — with `--codex`, post the request and return pending instead of polling.
|
|
78
|
+
- `--base <branch>` — base for the branch report, the `pr-check` diff and a newly created PR.
|
|
79
|
+
Default: the existing PR's base, else the repo default.
|
|
86
80
|
- `--agent <inline|auto|name>` — names **who performs model-bearing work**, per the
|
|
87
81
|
[inline-default execution-surface contract](../spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
from child args; that child owns model work. Current-agent selection stays inline.
|
|
92
|
-
Headless surfaces substitute tier resolution for `inline` with a warning (task 0687), never refusing.
|
|
93
|
-
- `--agent` describes the model owner only; it is independent of the deterministic git/GitHub spine
|
|
94
|
-
and the workflow/direct route. Run the selected route in that resolved skill context. A separate
|
|
95
|
-
workflow subprocess belongs to the caller's execution surface or an objective trigger (for example,
|
|
96
|
-
a required durable run record), not to `--agent auto` or a name by itself.
|
|
97
|
-
- Remaining free text — extra review focus, appended to the Codex request without weakening
|
|
98
|
-
repository-defined rules (e.g. `security and authorization boundaries`, `migration safety`).
|
|
99
|
-
|
|
100
|
-
## Safety rules
|
|
82
|
+
`--agent` describes the model owner only; it is independent of the deterministic git/GitHub spine.
|
|
83
|
+
- Remaining free text — extra review focus, passed to the local review and appended to the Codex
|
|
84
|
+
request without weakening repository-defined rules (e.g. `security and authorization boundaries`).
|
|
101
85
|
|
|
102
|
-
|
|
103
|
-
`git clean`, rewriting published history, merging the PR, deleting branches, discarding unrelated
|
|
104
|
-
user changes.
|
|
86
|
+
## Status mode
|
|
105
87
|
|
|
106
|
-
|
|
107
|
-
inspect the tree, separate relevant from unrelated, never `git add .` blindly, and ask the user
|
|
108
|
-
before creating any commit outside `fix` mode. If safe separation is ambiguous, stop and explain.
|
|
109
|
-
In `fix` mode the user pre-authorized one focused fix commit for verified findings — still stop if
|
|
110
|
-
unrelated uncommitted changes make safe editing or committing ambiguous.
|
|
88
|
+
Read-only; no source edits, PR creation, pushes, or review requests.
|
|
111
89
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
review was being fetched, or between polls, fails the wait (exit 2) instead of accepting an old-head
|
|
118
|
-
result. The pinned identity is the PR number AND the expected head, so a different PR appearing on
|
|
119
|
-
the branch is also a failure, never a silent retarget. Reject uncorrelated issue/conversation
|
|
120
|
-
comments rather than using them to manufacture a current-HEAD result. In `fix` mode, discard the old
|
|
121
|
-
result after the fix commit and judge only the forced re-review for the new pushed HEAD.
|
|
90
|
+
1. Resolve the base: `--base`, else the existing PR's base, else the repo default.
|
|
91
|
+
2. `spur builder show-branches --base "$base" --pr --format markdown` — keep only the rows for the
|
|
92
|
+
current branch and its base (the full report is long) plus the current branch's graph line.
|
|
93
|
+
3. `spur builder pr-status --json` for the composite repository/branch/PR/base/local/CI status and
|
|
94
|
+
`.review` (the current-HEAD Codex record). With no PR, report `PR: none` rather than failing.
|
|
122
95
|
|
|
123
|
-
|
|
124
|
-
may lead to a code change: inspect the referenced code, verify reachability and intended behavior,
|
|
125
|
-
inspect callers/callees where needed, check existing tests, classify, reject false positives, fix
|
|
126
|
-
root causes rather than wording, prefer the smallest coherent patch, avoid drive-by refactors.
|
|
96
|
+
Report:
|
|
127
97
|
|
|
128
|
-
|
|
98
|
+
```text
|
|
99
|
+
PR: <number + URL | none>
|
|
100
|
+
Branch: <branch>
|
|
101
|
+
HEAD: <short SHA>
|
|
102
|
+
Base: <base>
|
|
103
|
+
Ahead/Behind: <n>/<n> vs <base>
|
|
104
|
+
CI: <status | unavailable>
|
|
105
|
+
Codex: clean | findings | pending | not requested | unavailable
|
|
106
|
+
```
|
|
129
107
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
108
|
+
## Review mode (local)
|
|
109
|
+
|
|
110
|
+
1. **Submission scan.** `spur builder pr-check --base "$base" --scan-only --json`. Three outcomes:
|
|
111
|
+
- `PASS`/`WARN` — continue. A `WARN` (debug residue) is reported and rides into the review.
|
|
112
|
+
- `BLOCK` (secrets, `.env`, conflict markers, private keys) — stop; never review a tainted diff,
|
|
113
|
+
and name the blocking files.
|
|
114
|
+
- hard failure (exit 2, e.g. `gh` missing or unauthenticated, no GitHub remote, not a
|
|
115
|
+
repository) — stop and report the tool's message plus the one-line remedy (`gh auth login`
|
|
116
|
+
and a GitHub `origin` remote). A hard failure is **not** a `BLOCK`; hygiene did not run.
|
|
117
|
+
`--scan-only` skips the preflight sub-op so a dirty tree is expected, but hygiene itself still
|
|
118
|
+
resolves the repository through `gh` — the scan needs `gh` authenticated with a GitHub remote.
|
|
119
|
+
2. **Diff scope.** `git diff --name-only "$base"...HEAD`. An empty list ends the mode with
|
|
120
|
+
"nothing to review". `/sp:dev-review` takes `--scope` paths, not a diff range, so pass the
|
|
121
|
+
comma-joined file list.
|
|
122
|
+
3. **Local review.** `/sp:dev-review --scope <comma-joined paths> --focus "<focus>"`. It owns the
|
|
123
|
+
review dimensions — do not re-implement them here. Report findings by severity with `file:line`.
|
|
124
|
+
Post nothing to GitHub.
|
|
125
|
+
|
|
126
|
+
## Review mode (--codex)
|
|
127
|
+
|
|
128
|
+
Run `pr-review.yaml` as the single source of truth for the Codex spine — check → precheck → open →
|
|
129
|
+
review. Never call `spur builder pr-review` in a way that bypasses the workflow's state order and
|
|
130
|
+
guards.
|
|
133
131
|
|
|
134
132
|
```sh
|
|
135
|
-
spur
|
|
133
|
+
spur workflow run pr-review.yaml --vars '{"mode":"full","baseBranch":"<base>","focus":"<focus>"}'
|
|
136
134
|
```
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
dirty tree, triage with the user (commit/stash/exclude) before continuing — the
|
|
145
|
-
workflow refuses to guess.
|
|
146
|
-
2. **Hygiene** — `spur builder pr hygiene --base "$base" --json`. `BLOCK` (secrets, `.env`, conflict markers,
|
|
147
|
-
private keys) stops the run — never submit a tainted diff. `WARN` (debug residue) rides along
|
|
148
|
-
into the report. This is a submission sanity check, not a second local review.
|
|
149
|
-
3. **Precheck** — if the workflow YAML's `preReviewCmd` var is set, run it; a red check stops the
|
|
150
|
-
run (do not spend a review request on code that fails its own gate). When unset, report that
|
|
151
|
-
pre-review verification was not configured rather than inventing project commands.
|
|
152
|
-
4. **Push** — `spur builder pr push --json`. Normal push only; sets upstream when missing.
|
|
153
|
-
5. **Ensure PR** — `spur builder pr ensure-pr --base "$base" --json`. Reuses the branch's PR; creates with
|
|
154
|
-
`gh pr create --fill` only when absent. Never a duplicate PR.
|
|
155
|
-
6. **Request** — `spur builder pr request --focus "<focus>" --json` (`--force` in `rerun` mode). Dedupes when
|
|
156
|
-
Codex already reviewed the exact pushed HEAD (`ALREADY_REVIEWED` → skip to collect) or a marked
|
|
157
|
-
request by the current GitHub user is still in flight (`ALREADY_REQUESTED` → pending). The
|
|
158
|
-
request body is concise when the repo has `## Code Review Rules`, else carries the default
|
|
159
|
-
actionable-issues focus. Records PR, URL, HEAD, and request time.
|
|
160
|
-
7. **Wait** (full/rerun unless `--no-wait`; submit stops before it) —
|
|
161
|
-
`spur builder pr wait --since "$requestedAt" --head "$requestHead" --json`, using the request result so
|
|
162
|
-
a fast response is not missed, `rerun` cannot reuse the prior review, and a moved HEAD fails loud.
|
|
163
|
-
Polls every ~30s for up to
|
|
164
|
-
~10 minutes across the current HEAD's PR review and inline comments. Uncorrelated conversation
|
|
165
|
-
comments are ignored. A current-HEAD clean review is a completed `CLEAN` outcome; findings are
|
|
166
|
-
`FOUND`; timeout or no current-HEAD result is **pending, not failed** — collect later.
|
|
167
|
-
8. **Collect** — `spur builder pr collect --since "$requestedAt" --head "$requestHead" --json`. Normalize
|
|
168
|
-
only the requested HEAD and request window; then invoke `status` with the same bounds for
|
|
169
|
-
PR/base/CI/local state. Never turn an absent, stale, or moved-HEAD result into `clean`.
|
|
170
|
-
`--head` is mandatory on wait/collect/status (0771): an empty or missing pin fails loud
|
|
171
|
-
instead of silently reviewing whatever HEAD is current.
|
|
136
|
+
- `mode=full` by default; `--force` → `mode=rerun`; `--no-wait` → `mode=submit`.
|
|
137
|
+
- The workflow's `pending` terminal state is **pending, not failed**: report the requested or
|
|
138
|
+
in-flight state and collect later with `status`.
|
|
139
|
+
- When `--codex` is passed, the external review goes through the GitHub PR and an `@codex review`
|
|
140
|
+
request only — never a local Codex CLI review. If GitHub Codex Code Review is unavailable, stop
|
|
141
|
+
and report the setup/access problem; never silently fall back to a local review.
|
|
172
142
|
|
|
173
143
|
## Fix mode
|
|
174
144
|
|
|
175
145
|
Only in `fix` mode:
|
|
176
146
|
|
|
177
|
-
1. **Collect before editing.**
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
Show the diff, summarize the meaningful rules added, and do not commit or push.
|
|
147
|
+
1. **Collect findings before editing.** Use the latest local review verdict when the last `review`
|
|
148
|
+
was local. When the last review was Codex, invoke `spur builder pr-status --json` and read
|
|
149
|
+
`.review` — the current-HEAD Codex record. Treat the PR's pushed `headRefOid` as the review
|
|
150
|
+
identity: a result for an older commit is stale, and a result absent for the current HEAD is
|
|
151
|
+
pending, not clean. If the record is pending, stale, or unavailable, report it and stop without
|
|
152
|
+
source edits.
|
|
153
|
+
2. **Validate each finding.** Open the referenced code; trace callers/callees; verify the problem is
|
|
154
|
+
reachable; check intended behavior and existing tests. Classify: `Confirmed`, `Likely valid`,
|
|
155
|
+
`Needs investigation`, `Likely false positive`. List every rejected finding with its reason;
|
|
156
|
+
never edit for a likely false positive.
|
|
157
|
+
3. **Fix legitimate issues** with the smallest coherent change. No unrelated refactoring; add or
|
|
158
|
+
update tests when they materially demonstrate the fix; follow repository conventions. Inspect
|
|
159
|
+
`git diff` — the patch must contain only intended review fixes.
|
|
160
|
+
4. **Verify** with repository-defined targeted checks. Never claim a check passed unless it ran
|
|
161
|
+
successfully.
|
|
162
|
+
5. **Commit** one focused review-fix commit describing the actual defect (`fix: prevent duplicate
|
|
163
|
+
transaction retry`), never `fix codex comments`. No unrelated files.
|
|
164
|
+
6. **Push** normally (never force) and report the new HEAD. `spur builder pr-open` handles a first
|
|
165
|
+
push.
|
|
166
|
+
|
|
167
|
+
## Safety rules
|
|
168
|
+
|
|
169
|
+
**Git history — never:** force-push (`--force`/`--force-with-lease`), destructive `git reset`, `git
|
|
170
|
+
clean`, rewriting published history, closing or integrating the PR, deleting branches, or discarding
|
|
171
|
+
unrelated user changes.
|
|
172
|
+
|
|
173
|
+
**Local changes.** A GitHub PR only reviews pushed commits. `review` without `--codex` makes no
|
|
174
|
+
GitHub writes. `fix` pre-authorizes one focused fix commit for verified findings — still stop if
|
|
175
|
+
unrelated uncommitted changes make safe editing or committing ambiguous.
|
|
176
|
+
|
|
177
|
+
**Reviewer authority.** A remote reviewer is an independent reviewer, not an authority. For every
|
|
178
|
+
finding that may lead to a code change: inspect the referenced code, verify reachability and
|
|
179
|
+
intended behavior, inspect callers/callees, check existing tests, classify, reject false positives,
|
|
180
|
+
fix root causes rather than wording, prefer the smallest coherent patch, avoid drive-by refactors.
|
|
212
181
|
|
|
213
182
|
## Reporting
|
|
214
183
|
|
|
215
184
|
Findings report:
|
|
216
185
|
|
|
217
186
|
```text
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
HEAD
|
|
222
|
-
<short SHA>
|
|
223
|
-
|
|
224
|
-
Codex review
|
|
225
|
-
Clean | Findings | Pending | Unavailable
|
|
187
|
+
Reviewer
|
|
188
|
+
local (/sp:dev-review) | GitHub Codex
|
|
226
189
|
|
|
227
190
|
Findings
|
|
228
191
|
|
|
@@ -232,62 +195,46 @@ Findings
|
|
|
232
195
|
Why it matters:
|
|
233
196
|
Evidence:
|
|
234
197
|
Recommended next action:
|
|
235
|
-
|
|
236
|
-
CI
|
|
237
|
-
<status summary>
|
|
238
198
|
```
|
|
239
199
|
|
|
240
|
-
Preserve filenames, line references, severity, and the important technical reasoning. Do not
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
`wait` and `collect` must distinguish an explicit current-HEAD clean result from pending, stale, or
|
|
245
|
-
unavailable data. `collect` and `fix` reports also include the composite PR/base/branch/HEAD/local/CI
|
|
246
|
-
status; an unavailable CI signal remains `unavailable`, never an inferred pass.
|
|
247
|
-
|
|
248
|
-
Always end with the compact summary:
|
|
249
|
-
|
|
250
|
-
```text
|
|
251
|
-
PR: <number + URL | none>
|
|
252
|
-
Branch: <branch>
|
|
253
|
-
HEAD: <short SHA>
|
|
254
|
-
Base: <base>
|
|
255
|
-
CI: <status>
|
|
256
|
-
Codex: clean | findings | pending | not requested | unavailable
|
|
257
|
-
Findings: <count>
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
`fix` mode appends: `Fixed: <n>`, `Rejected: <n>`, `New HEAD: <sha>`,
|
|
261
|
-
`Re-review: clean | findings | pending | unavailable`. If findings remain, state the recommended
|
|
262
|
-
next action.
|
|
263
|
-
|
|
264
|
-
`status` mode prints the same summary block and nothing else — no file edits, PR creation, pushes,
|
|
265
|
-
or review requests.
|
|
200
|
+
Preserve filenames, line references, severity, and the important technical reasoning. Do not inflate
|
|
201
|
+
suggestions into confirmed bugs. If a review completed without actionable findings, say so clearly.
|
|
202
|
+
`fix` appends: `Fixed: <n>`, `Rejected: <n>`, `New HEAD: <sha>`. `status` prints its summary block
|
|
203
|
+
and nothing else.
|
|
266
204
|
|
|
267
205
|
## Failure handling
|
|
268
206
|
|
|
269
|
-
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
-
|
|
276
|
-
|
|
207
|
+
- **No PR for the branch** — `pr-status --json` returns `pr: null` and `review: null`; `status`
|
|
208
|
+
reports `PR: none` and the branch report still prints.
|
|
209
|
+
- **`gh` missing, unauthenticated, or no GitHub remote** — `show-branches --pr` degrades with a
|
|
210
|
+
warning; `pr-status` and `pr-check` exit non-zero with an error object (their hygiene step shares
|
|
211
|
+
the gh-backed repository resolution). Report the branch report plus `PR: unavailable`, and stop
|
|
212
|
+
the Codex path. The review's own diff scope and `/sp:dev-review` need no `gh`.
|
|
213
|
+
- **`pr-check` BLOCK** — stop before any review; report the blocking files and never review a
|
|
214
|
+
tainted diff.
|
|
215
|
+
- **Empty diff** — "nothing to review"; stop.
|
|
216
|
+
- **Codex pending or wait timeout** — report `pending`, never failure; collect later.
|
|
217
|
+
- **A finding that refers to a stale head** — discard it, never fix against it.
|
|
218
|
+
- **A retired mode passed** — one notice line, then the replacement.
|
|
277
219
|
|
|
278
220
|
## Platform notes
|
|
279
221
|
|
|
280
|
-
- The skill, command
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
-
|
|
284
|
-
|
|
222
|
+
- The skill, command and workflow YAML are platform-neutral; per-platform emission is owned by
|
|
223
|
+
superskill. On platforms without a Skill tool, read this file and follow the protocol manually.
|
|
224
|
+
- Prerequisites: `git` for every path. `gh` authenticated with a GitHub remote wherever PR state is
|
|
225
|
+
touched: `status` (its `pr-status` half — the `show-branches` topology runs on `git` alone, and
|
|
226
|
+
its `--pr` enrichment only degrades with a warning), `review` (step 1's `pr-check --scan-only`),
|
|
227
|
+
`review --codex` (the workflow's check/open/review states), and `fix` when it reads a Codex
|
|
228
|
+
verdict or pushes through `pr-open`. The `git diff --name-only` scope, `/sp:dev-review`, and
|
|
229
|
+
`fix`'s local-verdict edit/commit path need only `git`. The `--codex` path additionally needs
|
|
230
|
+
GitHub Codex Code Review enabled for the repository.
|
|
285
231
|
|
|
286
232
|
## Additional Resources
|
|
287
233
|
|
|
288
|
-
- **Workflow SSOT:** `pr-review.yaml` (seeded by `spur init`; tune per project —
|
|
289
|
-
|
|
290
|
-
- **
|
|
234
|
+
- **Workflow SSOT (Codex path):** `pr-review.yaml` (seeded by `spur init`; tune per project — wait
|
|
235
|
+
budget, `preReviewCmd`, dedupe policy)
|
|
236
|
+
- **Command source:** the four flat verbs `pr-status` / `pr-check` / `pr-open` / `pr-review` plus the
|
|
237
|
+
read-only `show-branches` report — see `sp:spur-cli` `references/builder.md`
|
|
238
|
+
- **Local review:** `/sp:dev-review` — its dimensions live in `sp:code-verification` and
|
|
239
|
+
`sp:functional-review`, never re-implemented here
|
|
291
240
|
- **Tests:** `packages/app/tests/services/pr-review/pr-review.test.ts` — stubbed git/gh suites
|
|
292
|
-
- **Related skills:** `sp:code-verification` (local SECUA review), `sp:functional-review`
|
|
293
|
-
(requirements traceability) — complements, never substitutes, the independent Codex review
|
|
@@ -201,7 +201,6 @@ Audit categories:
|
|
|
201
201
|
| Analysis Date | YYYY-MM-DD |
|
|
202
202
|
| Target | `path` |
|
|
203
203
|
| Mode / Focus / Format | `briefing` / `[focus]` / `markdown` |
|
|
204
|
-
| Confidence | High / Medium / Low |
|
|
205
204
|
|
|
206
205
|
## Purpose Hypothesis
|
|
207
206
|
|
|
@@ -209,8 +208,8 @@ Audit categories:
|
|
|
209
208
|
|
|
210
209
|
## Tech Stack
|
|
211
210
|
|
|
212
|
-
| Layer | Technology | Evidence |
|
|
213
|
-
|
|
211
|
+
| Layer | Technology | Evidence |
|
|
212
|
+
|---|---|---|
|
|
214
213
|
|
|
215
214
|
## Entry Points
|
|
216
215
|
|
|
@@ -282,7 +281,6 @@ Use this shape for `--format json` or `--format both`. Omit fields only when the
|
|
|
282
281
|
"analysisDate": "YYYY-MM-DD",
|
|
283
282
|
"mode": "architecture",
|
|
284
283
|
"focus": "all",
|
|
285
|
-
"confidence": "high|medium|low",
|
|
286
284
|
"stack": [],
|
|
287
285
|
"entryPoints": [],
|
|
288
286
|
"components": [],
|
|
@@ -301,7 +299,7 @@ Use this shape for `--format json` or `--format both`. Omit fields only when the
|
|
|
301
299
|
- Cite `file/path:line` for claims derived from source files.
|
|
302
300
|
- Cite manifest paths for stack and package manager claims.
|
|
303
301
|
- Cite multiple files for architectural boundary claims when possible.
|
|
304
|
-
- Mark inferred claims
|
|
302
|
+
- Mark inferred claims `Inferred:` and name the evidence that would confirm them; no confidence label (ADR-138).
|
|
305
303
|
- Never invent services, databases, tables, endpoints, actors, diagrams, or business flows that are not supported by evidence.
|
|
306
304
|
- If line numbers are unavailable from a tool, cite the file path and state that line numbers were not available.
|
|
307
305
|
|
|
@@ -339,7 +337,7 @@ The indexed-context layer is optional and opportunistic.
|
|
|
339
337
|
|---|---|
|
|
340
338
|
| Empty/minimal codebase | Return `briefing` with "insufficient evidence", list missing artifacts, suggest next files needed. |
|
|
341
339
|
| Monorepo | Identify packages/apps; ask for scope unless `--auto` or requested mode can safely summarize all packages. |
|
|
342
|
-
| No clear entry point | List candidates with
|
|
340
|
+
| No clear entry point | List candidates with their evidence; do not choose one as definitive. |
|
|
343
341
|
| Binary-heavy repo | Focus on manifests, scripts, config, docs, and visible source. |
|
|
344
342
|
| Generated/vendor-heavy repo | Exclude generated/vendor paths from architecture conclusions unless directly relevant. |
|
|
345
343
|
| Framework convention over configuration | State inferred convention and cite framework-specific file patterns. |
|
|
@@ -149,39 +149,23 @@ step 4 excludes. Use `n/a` for any value not supported by the measurement.
|
|
|
149
149
|
|
|
150
150
|
### Resolved issues
|
|
151
151
|
|
|
152
|
-
| Issue | Root cause | Resolution | Evidence |
|
|
153
|
-
| --- | --- | --- | --- |
|
|
152
|
+
| Issue | Root cause | Resolution | Evidence |
|
|
153
|
+
| --- | --- | --- | --- |
|
|
154
154
|
|
|
155
155
|
Evidence names the tool result, verification command, or concrete repository state visible in the
|
|
156
156
|
session. Do not list ordinary implementation steps as issues.
|
|
157
157
|
|
|
158
|
-
**
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
| Level | Verifies when | Not this |
|
|
165
|
-
| --- | --- | --- |
|
|
166
|
-
| `HIGH` | An executed check in this session produced the result and its raw output is reachable (command + exit code, test counts, query row, gate log). Re-runnable now. | The code or change "looks correct"; a claim asserted only in prose. |
|
|
167
|
-
| `MEDIUM` | The claim is inferred from observed facts, rests on prior-session or delegated evidence, or names state that moved after the check (stale by construction). Name which of the three. | Presenting an inference as an observation. |
|
|
168
|
-
| `LOW` | No executable check was run. Name the missing evidence **and** the command that would ground it. | Dropping the row instead of marking it. |
|
|
169
|
-
|
|
170
|
-
Two guards against level inflation:
|
|
171
|
-
|
|
172
|
-
- Evidence that cannot be re-run, or that is only the agent's own summary, **caps the row at
|
|
173
|
-
`MEDIUM`** — a re-run is what promotes it.
|
|
174
|
-
- An all-`HIGH` multi-finding review is a signal the ladder was not applied, not a clean session.
|
|
175
|
-
Where every row genuinely is `HIGH`, the cells show distinct check results rather than repeated
|
|
176
|
-
phrasing.
|
|
177
|
-
|
|
178
|
-
Any API/library statement in a row cites the installed source as `path:line` or a URL, and a claim
|
|
179
|
-
the session could not ground is written `LOW` with the missing evidence named.
|
|
158
|
+
**Evidence is the check, not a grade** (ADR-138). A row resolved by an executed check this session
|
|
159
|
+
names the command and its result (e.g. `gate exit 0, /tmp/g0.log`). A row resting on inference,
|
|
160
|
+
prior-session or delegated evidence says so. A row with no check run names the missing evidence
|
|
161
|
+
**and** the command that would ground it — never drop the row instead. No HIGH/MEDIUM/LOW label:
|
|
162
|
+
a self-assigned level is as easy to write as the claim. Any API/library statement in a row cites
|
|
163
|
+
the installed source as `path:line` or a URL.
|
|
180
164
|
|
|
181
165
|
### Open issues and risks
|
|
182
166
|
|
|
183
|
-
| Issue or risk | State | Evidence or confirmation needed |
|
|
184
|
-
| --- | --- | --- |
|
|
167
|
+
| Issue or risk | State | Evidence or confirmation needed |
|
|
168
|
+
| --- | --- | --- |
|
|
185
169
|
|
|
186
170
|
### Process and environment improvements
|
|
187
171
|
|