liteagents 2.21.0 → 2.22.0

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/CHANGELOG.md CHANGED
@@ -9,6 +9,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [2.22.0] - 2026-09-01
13
+
14
+ ### Fixed
15
+ - **`/branch-review` — dirty tree is now a hard stop, not a silent partial review.** The
16
+ staged/working-tree fallback only fired when the earlier step was empty, so a branch with
17
+ both committed and uncommitted changes reviewed the commits and silently skipped the
18
+ uncommitted lines. It now reports the resolved review target and re-checks
19
+ `git status --porcelain` at exit as well as at start, in all four kits.
20
+ - **`/release` — Phase 0 no longer commits a dirty tree for the user.** Committing on the
21
+ user's behalf produced a commit made *after* the review, which Phase 0.5 then had no way to
22
+ accept — a dirty tree is now a stop, with the fix pushed back to the user
23
+ (`git add`/`git commit`, re-run `/branch-review`, then `/release`), in all four kits.
24
+ - **`/release` Phase 0.5 compares SHAs mechanically instead of asking the orchestrator to
25
+ judge it.** The worker now runs `git rev-parse HEAD` itself and compares it against the
26
+ review's recorded SHA — no recorded SHA, or a mismatch, is a stop, never a "looks close
27
+ enough" pass.
28
+
29
+ ### Changed
30
+ - **`/branch-review` — test quality is a stage-1 item.** A test's ability to fail is proven by
31
+ reverting the *source* change outside the repo, not by reverting the test itself; commit
32
+ messages are treated as claims to re-verify, never as evidence on their own.
33
+ - **`/branch-review` — the review worker may not spawn sub-workers**, and the verdict line is
34
+ now printed at both the top and the bottom of the report.
35
+ - **`/release` — records local vs. published version in Phase 0**, and Phase 3 treats a gap
36
+ between them as the ask-if-ambiguous trigger for picking a version. The release commit made
37
+ in Phase 3 is documented as the one commit `/release` is permitted to make post-review.
38
+ Documents that `gh pr merge` requires an explicit merge-method flag (`--squash` /
39
+ `--merge` / `--rebase`) or it will not merge.
40
+ - **`/branch-review`, `/release`, `/stash` — tier guidance no longer self-contradicts.**
41
+ "Balanced default tier" plus "never hardcode a vendor name" resolved, in practice, to
42
+ whatever tier the parent session happened to be running at. All three now say: explicitly
43
+ select your tool's mid tier and state it on the spawn.
44
+
45
+ ## [2.21.1] - 2026-08-30
46
+
47
+ ### Changed
48
+ - **`AGENT_RULES.md` template points at `/branch-review`, in all four kits.** Three sites
49
+ still described the pre-2.21.0 topology: Operating Flow §2 and the Security invariants both
50
+ told the agent to run `/security` separately and lean on `/ship` as the security gate, and
51
+ the never-commit-to-`main` safeguard named `/code-review`. They now say: propose
52
+ `/branch-review` (general review plus a full `/security` audit, reports and never fixes),
53
+ then `/release` (which runs `/ship` as the mechanical pre-deploy gate).
54
+
12
55
  ## [2.21.0] - 2026-08-30
13
56
 
14
57
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "liteagents",
3
- "version": "2.21.0",
3
+ "version": "2.22.0",
4
4
  "description": "AI development toolkit with 11 specialized agents and 18 commands including live-canvas UI design with click-to-annotate feedback. Simple one-question installer for Claude, Opencode, Ampcode, and Droid.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -14,31 +14,61 @@ Run this **before** `/release`. `/release` will refuse to run without a review
14
14
  at the current HEAD SHA.
15
15
 
16
16
  ## Guardrails
17
- - **Spawn a worker on a mid-tier model, not hardcoded.** The review runs in a
18
- subagent on your tool's balanced default tier judgment-capable, cheaper and
19
- faster than your top reasoning tier. **Not the cheapest/fastest tier**: on
20
- judgment work it measurably degrades (misclassification rates several times
21
- higher). Never hardcode a vendor-specific model name. Fall back to running
22
- inline if your tool has no subagent mechanism.
17
+ - **Spawn a worker and explicitly select your tool's mid tier.** State the
18
+ tier on the spawn do not omit it and rely on a default. An omitted tier
19
+ inherits the *parent's* tier, which is not the same thing as the balanced
20
+ one. Pick the judgment-capable tier that is cheaper and faster than your top
21
+ reasoning tier. **Not the cheapest/fastest tier**: on judgment work it
22
+ measurably degrades (misclassification rates several times higher). Choose by
23
+ tier, not by a vendor model name copied from this file — names drift, and
24
+ this command ships to several tools. Fall back to running inline if your tool
25
+ has no subagent mechanism.
23
26
  - **Escalate, never assume.** Anything you cannot decide, cannot verify, or
24
27
  that this spec does not cover → **stop and report it to the orchestrator**
25
28
  (the main session). Never improvise, never widen scope, never fix a side
26
29
  issue you noticed along the way.
30
+ - **The worker does the work itself — no delegation.** The review subagent
31
+ must **not** spawn subagents of its own. Everything it reports has to be
32
+ something it read, ran, or grepped with its own tool calls: a relayed "I
33
+ executed X" from a sub-worker is hearsay, and replacing hearsay with evidence
34
+ is the entire point of this command. A review that delegates its work is a
35
+ review of a report. (Same rule `/security` carries inside stage 2.)
27
36
  - **No edits.** You have no authorization to change code, even for a finding
28
- you are certain about. Report it.
29
-
30
- ## Target interpret `$ARGUMENTS` in this order
37
+ you are certain about. Report it. Re-run `git status --porcelain` before you
38
+ report and confirm it is still empty — if it is not, say what changed. That
39
+ turns "it never edits" from a claim into a checked fact.
40
+
41
+ ## Target — check the tree first, then interpret `$ARGUMENTS`
42
+
43
+ **Before resolving anything, run `git status --porcelain`.** If it prints any
44
+ line — modified, staged, or untracked — **stop and report it**. Say all three
45
+ things, not just the first: (a) the tree is dirty, listing the uncommitted
46
+ paths; (b) `/branch-review` reviews commits, not the working tree; (c) **commit
47
+ the work to the branch, then re-run `/branch-review`.** A stop that names the
48
+ problem without the remedy invites the orchestrator to stash the changes or
49
+ hand-review the working tree instead. Do not review a subset and do not fall
50
+ back to the staged diff or the working tree. A dirty
51
+ tree is an **error**, never a silent partial review — the most expensive
52
+ failure this command can have is reviewing 800 committed lines while 200
53
+ uncommitted lines of today's actual work go unread.
54
+
55
+ This is forced by the design, not a preference: `/release`'s precondition is a
56
+ review at the current HEAD SHA, and any commit made after the review makes it
57
+ stale. **The only correct order is commit → review → release.**
58
+
59
+ With a clean tree, interpret `$ARGUMENTS` in this order:
31
60
  1. **Empty** → the current branch vs its merge-base with `main`
32
- (`git diff $(git merge-base main HEAD)..HEAD`). If that is empty, the
33
- staged diff; if that is empty too, the working tree.
61
+ (`git diff $(git merge-base main HEAD)..HEAD`). If that is empty there is
62
+ nothing committed to review say so and stop.
34
63
  2. **A range** like `main..HEAD` or `origin/main...HEAD` → `git diff <range>`.
35
64
  3. **A single ref** (branch / tag / SHA — confirm with `git rev-parse
36
65
  --verify`) → that ref's merge-base against `HEAD`.
37
66
  4. **A file or directory path** → that target.
38
67
  5. Otherwise → ask.
39
68
 
40
- Record the **HEAD SHA** you reviewed. `/release` checks it, and any commit
41
- made after the review makes the review stale.
69
+ Record the **HEAD SHA** you reviewed, and **report the target you resolved**
70
+ (the literal range or path) in your output, so the orchestrator can see what
71
+ was actually read rather than assuming.
42
72
 
43
73
  ## Effort level
44
74
  `low | medium | high | max` — default **medium** if not given. The level
@@ -57,6 +87,13 @@ hunk-only read cannot see that a caller further down the same file is now
57
87
  wrong. For multi-commit ranges, skim `git log <range>` for intent before
58
88
  judging.
59
89
 
90
+ **Commit messages are claims, not evidence.** A message saying a fix was
91
+ "proven red→green", a bug reproduced, or a test added is something to re-test,
92
+ not a fact to accept. Branches are commonly AI-authored now — including the
93
+ fixes to the fixes — so a review that trusts the message is reviewing prose.
94
+ Run the test suite and the typecheck/build yourself and cite the command and
95
+ its exit code.
96
+
60
97
  - **Bugs needing a fix.** Logic errors, off-by-one, null/undefined paths,
61
98
  races, wrong defaults, broken edge cases.
62
99
  - **Dead code.** Unreferenced functions / vars / imports / params, unreachable
@@ -69,6 +106,16 @@ judging.
69
106
  broken invariants.
70
107
  - **Performance.** N+1, blocking calls in hot paths, unbounded loops, indexes
71
108
  the diff actually touches.
109
+ - **Test quality, not just test presence.** For every test the diff adds or
110
+ changes, establish that it **can actually fail**. Reasoning about
111
+ falsifiability does not work; executing it does. **Revert the source, not the
112
+ test:** take the pre-change version of the file under test with `git show
113
+ <base-sha>:<path>`, run the test against that copy, and watch it go red. Do
114
+ this **without dirtying the branch** — write the old version to a temp
115
+ location outside the repo; the tree must still be clean at exit. A test that
116
+ passes against both the buggy and the fixed source is a tautology and proves
117
+ nothing. Flag every one you find, and say so explicitly when the tests are
118
+ the branch's only evidence for its claims.
72
119
  - **Maintainability.** Complexity, naming, duplication — only when material.
73
120
 
74
121
  ## Stage 2 — Security (always full)
@@ -102,7 +149,12 @@ cannot write that sentence, the finding is not ready — drop it or mark it
102
149
  uncertain. No vibes.
103
150
 
104
151
  ## Report — then escalate
105
- Order findings most severe first.
152
+ **Open with the one-line verdict**, before any section: **Ready to merge? Yes /
153
+ No / Not until these are fixed.** A report that opens with "Critical: none
154
+ found" reads as a pass at a glance even when the verdict is not one — state the
155
+ verdict first, then repeat it at the end.
156
+
157
+ Then the findings, ordered most severe first.
106
158
 
107
159
  ### 🚨 Critical (blocks merge)
108
160
  ### ⚠️ Warnings (should fix)
@@ -117,7 +169,8 @@ with its evidence. A stage you did not actually run is a **✗**, never an
117
169
  assumed pass.
118
170
 
119
171
  End with:
120
- - **Reviewed at HEAD `<sha>` on `<branch>`.**
172
+ - **Reviewed at HEAD `<sha>` on `<branch>`, target `<resolved range or path>`,
173
+ tree clean at start and at exit.**
121
174
  - One-line verdict: **Ready to merge? Yes / No / Not until these are fixed.**
122
175
  - **Escalate to the orchestrator** with the findings. It decides what gets
123
176
  fixed and by whom. Say plainly what you could not verify.
@@ -13,12 +13,15 @@ It does not re-implement checks, and it does not review code. Review is a
13
13
  separate command that must have run first.
14
14
 
15
15
  ## Guardrails
16
- - **Spawn a worker on a mid-tier model, not hardcoded.** The run happens in a
17
- subagent on your tool's balanced default tier judgment-capable, cheaper and
18
- faster than your top reasoning tier. **Not the cheapest/fastest tier**: on
19
- judgment work it measurably degrades (misclassification rates several times
20
- higher). Never hardcode a vendor-specific model name. Fall back to running
21
- inline if your tool has no subagent mechanism.
16
+ - **Spawn a worker and explicitly select your tool's mid tier.** State the
17
+ tier on the spawn do not omit it and rely on a default. An omitted tier
18
+ inherits the *parent's* tier, which is not the same thing as the balanced
19
+ one. Pick the judgment-capable tier that is cheaper and faster than your top
20
+ reasoning tier. **Not the cheapest/fastest tier**: on judgment work it
21
+ measurably degrades (misclassification rates several times higher). Choose by
22
+ tier, not by a vendor model name copied from this file — names drift, and
23
+ this command ships to several tools. Fall back to running inline if your tool
24
+ has no subagent mechanism.
22
25
  - **Escalate, never assume.** Anything you cannot decide, cannot verify, or
23
26
  that this spec does not cover → **stop and report it to the orchestrator**
24
27
  (the main session). Never improvise, never widen scope, never fix a finding
@@ -31,24 +34,45 @@ separate command that must have run first.
31
34
  - **Release the branch you are on.** No branch argument, no branch creation.
32
35
  - **On `main` → stop and ask** what should be released. `main` is only ever
33
36
  the merge target; never release it, never commit to it.
34
- - If the working tree still has uncommitted feature changes, commit them to
35
- the branch now the gate must see a real diff, not a dirty tree.
37
+ - **The tree must be clean do not commit for the user.** Run `git status
38
+ --porcelain`. Any line at all modified, staged, or untracked is a
39
+ **stop**: list the paths and say "commit this to the branch, re-run
40
+ `/branch-review`, then re-run `/release`." Committing here would create a
41
+ commit *after* the review and so fail Phase 0.5 by its own rule on the very
42
+ next step; a phase that guarantees the next phase fails is not a phase.
36
43
  - `git fetch origin`; the release diff is `origin/main...HEAD`. Empty →
37
44
  **stop**, nothing to release.
38
- - Print a one-line plan: branch · commit count · files changed · HEAD SHA.
45
+ - **Record both version numbers.** Read the **local** version (`package.json`
46
+ or this project's equivalent) and, if the project has a publish path, the
47
+ **published** one (`npm view <pkg> version`, or the registry equivalent).
48
+ Report them side by side. Local *ahead* of published means a version was cut
49
+ on a branch and never published — Phase 3 cannot see that gap unless you
50
+ record it here, and a worker that cannot see it will re-cut a number that
51
+ already exists.
52
+ - Print a one-line plan: branch · commit count · files changed · HEAD SHA ·
53
+ local version → published version.
39
54
 
40
55
  ## Phase 0.5 — Review precondition (do not skip)
41
- Ask the orchestrator: **has `/branch-review` or `/code-review` run on this
42
- branch at the current HEAD SHA?**
43
-
44
- - **No review** **stop**: "No review at `<sha>`. Run `/branch-review medium`
45
- (or `/code-review medium`) first."
46
- - **Stale** the review ran at an earlier SHA, i.e. commits landed after it
47
- (including fix commits) **stop** and ask for a re-review. This is what
48
- makes "all findings fixed" checkable instead of promised.
56
+ A review must have run on this branch **at the current HEAD SHA**.
57
+
58
+ **Compare the SHAs yourself; do not settle for an answer.** Run `git rev-parse
59
+ HEAD` and compare it against the SHA the review recorded `/branch-review`
60
+ ends with `Reviewed at HEAD <sha>`. Asking the orchestrator "did a review run?"
61
+ puts the question to the one party with an incentive to say yes, so its word is
62
+ not evidence: obtain the review's own recorded SHA and match the two strings.
63
+ **No recorded SHA to compare = no review**, never a pass.
64
+
65
+ - **No review**, or no recorded SHA obtainable → **stop**: "No review at
66
+ `<sha>`. Run `/branch-review medium` (or `/code-review medium`) first."
67
+ - **Stale** — recorded SHA ≠ `git rev-parse HEAD`, i.e. commits landed after
68
+ the review (including fix commits) → **stop** and ask for a re-review. This
69
+ is what makes "all findings fixed" checkable instead of promised.
49
70
  - **Reviewed at this SHA with findings outstanding** → **stop**. Findings are
50
71
  resolved before a release is cut.
51
72
 
73
+ Report the comparison you actually ran: recorded `<sha>` vs HEAD `<sha>`,
74
+ match yes/no.
75
+
52
76
  This is the only thing guaranteeing the branch was reviewed *and* security
53
77
  scanned, so treat a missing answer as a **stop**, never as a pass.
54
78
 
@@ -90,7 +114,11 @@ If a doc needs no change, **say so** rather than editing it for its own sake.
90
114
 
91
115
  ## Phase 3 — Cut (local only)
92
116
  1. **Version bump** — pick the semver level from the change (patch / minor /
93
- major; **ask if ambiguous**) and update `package.json`. The bump must land
117
+ major; **ask if ambiguous**) and update `package.json`. The local-vs-
118
+ published gap you recorded in Phase 0 **is** an ambiguity: if local is ahead
119
+ of published, a version was cut and never published, so ask whether to
120
+ publish that number or bump past it. Never silently re-cut a version that
121
+ already exists locally. The bump must land
94
122
  on the branch, before any merge — a version committed to `main` directly,
95
123
  or added after the merge, breaks the tag/package match.
96
124
  2. **Commit** — `release: vX.Y.Z — <summary>`, including the docs and the
@@ -98,6 +126,12 @@ If a doc needs no change, **say so** rather than editing it for its own sake.
98
126
 
99
127
  Then **stop.** Nothing else.
100
128
 
129
+ This release commit is the **one** commit allowed to land after the review, and
130
+ only because it contains docs and a version number — no code, so it cannot
131
+ invalidate a finding. It does move HEAD past the reviewed SHA, which is why
132
+ `/release` must not be run twice on the same branch without a re-review: the
133
+ second run will correctly stop as stale.
134
+
101
135
  ## Report — the sequence, for a human to authorize
102
136
  Print the evidence, then hand back the exact remaining steps so the
103
137
  orchestrator can run them on the user's named go:
@@ -108,7 +142,9 @@ orchestrator can run them on the user's named go:
108
142
  > 1. `git push -u origin <branch>`
109
143
  > 2. `gh pr create` into `main`
110
144
  > 3. `gh pr merge --admin --squash --delete-branch` (main is PR-protected;
111
- > owner-authorized admin merge on a solo repo)
145
+ > owner-authorized admin merge on a solo repo). **Keep `--squash`** — `gh`
146
+ > requires an explicit merge-method flag (`--squash` / `--merge` /
147
+ > `--rebase`); drop it and the command will not squash-merge.
112
148
  > 4. `git tag vX.Y.Z` on `main` and push the tag
113
149
  > 5. Publish **if this project has a publish path** (e.g.
114
150
  > `gh workflow run publish.yml`) — manual by design
@@ -27,7 +27,7 @@ Every task runs through three layers. Do not skip ahead to code.
27
27
  - **Open questions** — unknowns that don't block; never silently assumed
28
28
 
29
29
  Every POC result updates the PRD; one that flips the go/no-go or a module's assumption is a spec change, not a footnote.
30
- 2. **Verify — define "good" up front, then prove it.** Write down what success looks like *before* changing code. Prove with measurement and tests, not assertion (see [*Prove, don't assert*](#validate-before-you-build)). Gate security-sensitive work with `/security` and pre-deploy with `/ship`. When the work is done, propose `/code-review` and then `/release` you never merge or release on your own (see [Required Safeguards](#required-safeguards-always--ask--never)). External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
30
+ 2. **Verify — define "good" up front, then prove it.** Write down what success looks like *before* changing code. Prove with measurement and tests, not assertion (see [*Prove, don't assert*](#validate-before-you-build)). When the work is done, propose `/branch-review` a general review plus a full `/security` audit, which reports findings and never fixes them — and then `/release`, which runs `/ship` as the mechanical pre-deploy gate. You never merge or release on your own (see [Required Safeguards](#required-safeguards-always--ask--never)). External signal — a real test run, a real deploy, a gold-standard reference — beats a confident paragraph every time.
31
31
  3. **Environment — the standing context.** This file primes every session. Critical-path protections (secrets, auth, schema, CI) are stated as **Always / Ask / Never** below and bind you as written. Where your tool offers a permission allow/ask/deny list, mirror them there so they are enforced and not merely requested.
32
32
 
33
33
  **Execution order — work the way a program runs, in this order, nothing skipped:**
@@ -61,7 +61,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
61
61
  - **Always** identify affected files before making changes, and explain what will change and why
62
62
  - **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.amp/settings.json`
63
63
  - **Never** write secrets into the tree (`.env`/`*.env`, keys, credentials). They load from the environment at runtime; only a value-less `.env.example` is committed
64
- - **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/code-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
64
+ - **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/branch-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
65
65
 
66
66
  ---
67
67
 
@@ -229,7 +229,7 @@ Also hold the line on: input validation at every trust boundary (untrusted uploa
229
229
 
230
230
  **Verify at two moments, not one.**
231
231
  - **While building** — this list shapes the code as it's written.
232
- - **Before deploy/merge** — run **`/security`** on security-sensitive changes and **`/ship`** as the pre-deploy gate. A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run them whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
232
+ - **Before deploy/merge** — run **`/branch-review`**, whose second stage runs **`/security`** in full; `/release` then runs **`/ship`** as the mechanical pre-deploy gate. A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run them whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
233
233
 
234
234
  ---
235
235
 
@@ -15,11 +15,12 @@ Save session context for compaction recovery or handoffs.
15
15
  - **Escalate, never assume.** Anything the subagent cannot do, cannot verify, or that this
16
16
  spec does not cover → report it back to the orchestrator (the main session) rather than
17
17
  improvising. Never widen scope beyond writing the file and counting the backlog.
18
- - **Mid-tier model, not hardcoded.** Run the worker on your tool's balanced default tier
19
- judgment-capable, cheaper and faster than your top reasoning tier. **Not the
20
- cheapest/fastest tier**: on judgment work it measurably degrades (misclassification rates
21
- several times higher). Never hardcode a vendor-specific model name; use whatever your tool
22
- designates as that default.
18
+ - **Explicitly select your tool's mid tier.** State the tier on the spawn do not omit it
19
+ and rely on a default. An omitted tier inherits the *parent's* tier, which is not the same
20
+ thing as the balanced one. Pick the judgment-capable tier that is cheaper and faster than
21
+ your top reasoning tier. **Not the cheapest/fastest tier**: on judgment work it measurably
22
+ degrades (misclassification rates several times higher). Choose by tier, not by a vendor
23
+ model name copied from this file — names drift, and this command ships to several tools.
23
24
  - **Background dispatch where supported.** Run the write-up subagent in the background
24
25
  (non-blocking) so the session isn't held up waiting on formatting/file I/O. Fall back to
25
26
  writing inline (today's behavior) if your tool has no subagent or background-dispatch
@@ -14,31 +14,61 @@ Run this **before** `/release`. `/release` will refuse to run without a review
14
14
  at the current HEAD SHA.
15
15
 
16
16
  ## Guardrails
17
- - **Spawn a worker on a mid-tier model, not hardcoded.** The review runs in a
18
- subagent on your tool's balanced default tier judgment-capable, cheaper and
19
- faster than your top reasoning tier. **Not the cheapest/fastest tier**: on
20
- judgment work it measurably degrades (misclassification rates several times
21
- higher). Never hardcode a vendor-specific model name. Fall back to running
22
- inline if your tool has no subagent mechanism.
17
+ - **Spawn a worker and explicitly select your tool's mid tier.** State the
18
+ tier on the spawn do not omit it and rely on a default. An omitted tier
19
+ inherits the *parent's* tier, which is not the same thing as the balanced
20
+ one. Pick the judgment-capable tier that is cheaper and faster than your top
21
+ reasoning tier. **Not the cheapest/fastest tier**: on judgment work it
22
+ measurably degrades (misclassification rates several times higher). Choose by
23
+ tier, not by a vendor model name copied from this file — names drift, and
24
+ this command ships to several tools. Fall back to running inline if your tool
25
+ has no subagent mechanism.
23
26
  - **Escalate, never assume.** Anything you cannot decide, cannot verify, or
24
27
  that this spec does not cover → **stop and report it to the orchestrator**
25
28
  (the main session). Never improvise, never widen scope, never fix a side
26
29
  issue you noticed along the way.
30
+ - **The worker does the work itself — no delegation.** The review subagent
31
+ must **not** spawn subagents of its own. Everything it reports has to be
32
+ something it read, ran, or grepped with its own tool calls: a relayed "I
33
+ executed X" from a sub-worker is hearsay, and replacing hearsay with evidence
34
+ is the entire point of this command. A review that delegates its work is a
35
+ review of a report. (Same rule `/security` carries inside stage 2.)
27
36
  - **No edits.** You have no authorization to change code, even for a finding
28
- you are certain about. Report it.
29
-
30
- ## Target interpret `$ARGUMENTS` in this order
37
+ you are certain about. Report it. Re-run `git status --porcelain` before you
38
+ report and confirm it is still empty — if it is not, say what changed. That
39
+ turns "it never edits" from a claim into a checked fact.
40
+
41
+ ## Target — check the tree first, then interpret `$ARGUMENTS`
42
+
43
+ **Before resolving anything, run `git status --porcelain`.** If it prints any
44
+ line — modified, staged, or untracked — **stop and report it**. Say all three
45
+ things, not just the first: (a) the tree is dirty, listing the uncommitted
46
+ paths; (b) `/branch-review` reviews commits, not the working tree; (c) **commit
47
+ the work to the branch, then re-run `/branch-review`.** A stop that names the
48
+ problem without the remedy invites the orchestrator to stash the changes or
49
+ hand-review the working tree instead. Do not review a subset and do not fall
50
+ back to the staged diff or the working tree. A dirty
51
+ tree is an **error**, never a silent partial review — the most expensive
52
+ failure this command can have is reviewing 800 committed lines while 200
53
+ uncommitted lines of today's actual work go unread.
54
+
55
+ This is forced by the design, not a preference: `/release`'s precondition is a
56
+ review at the current HEAD SHA, and any commit made after the review makes it
57
+ stale. **The only correct order is commit → review → release.**
58
+
59
+ With a clean tree, interpret `$ARGUMENTS` in this order:
31
60
  1. **Empty** → the current branch vs its merge-base with `main`
32
- (`git diff $(git merge-base main HEAD)..HEAD`). If that is empty, the
33
- staged diff; if that is empty too, the working tree.
61
+ (`git diff $(git merge-base main HEAD)..HEAD`). If that is empty there is
62
+ nothing committed to review say so and stop.
34
63
  2. **A range** like `main..HEAD` or `origin/main...HEAD` → `git diff <range>`.
35
64
  3. **A single ref** (branch / tag / SHA — confirm with `git rev-parse
36
65
  --verify`) → that ref's merge-base against `HEAD`.
37
66
  4. **A file or directory path** → that target.
38
67
  5. Otherwise → ask.
39
68
 
40
- Record the **HEAD SHA** you reviewed. `/release` checks it, and any commit
41
- made after the review makes the review stale.
69
+ Record the **HEAD SHA** you reviewed, and **report the target you resolved**
70
+ (the literal range or path) in your output, so the orchestrator can see what
71
+ was actually read rather than assuming.
42
72
 
43
73
  ## Effort level
44
74
  `low | medium | high | max` — default **medium** if not given. The level
@@ -57,6 +87,13 @@ hunk-only read cannot see that a caller further down the same file is now
57
87
  wrong. For multi-commit ranges, skim `git log <range>` for intent before
58
88
  judging.
59
89
 
90
+ **Commit messages are claims, not evidence.** A message saying a fix was
91
+ "proven red→green", a bug reproduced, or a test added is something to re-test,
92
+ not a fact to accept. Branches are commonly AI-authored now — including the
93
+ fixes to the fixes — so a review that trusts the message is reviewing prose.
94
+ Run the test suite and the typecheck/build yourself and cite the command and
95
+ its exit code.
96
+
60
97
  - **Bugs needing a fix.** Logic errors, off-by-one, null/undefined paths,
61
98
  races, wrong defaults, broken edge cases.
62
99
  - **Dead code.** Unreferenced functions / vars / imports / params, unreachable
@@ -69,6 +106,16 @@ judging.
69
106
  broken invariants.
70
107
  - **Performance.** N+1, blocking calls in hot paths, unbounded loops, indexes
71
108
  the diff actually touches.
109
+ - **Test quality, not just test presence.** For every test the diff adds or
110
+ changes, establish that it **can actually fail**. Reasoning about
111
+ falsifiability does not work; executing it does. **Revert the source, not the
112
+ test:** take the pre-change version of the file under test with `git show
113
+ <base-sha>:<path>`, run the test against that copy, and watch it go red. Do
114
+ this **without dirtying the branch** — write the old version to a temp
115
+ location outside the repo; the tree must still be clean at exit. A test that
116
+ passes against both the buggy and the fixed source is a tautology and proves
117
+ nothing. Flag every one you find, and say so explicitly when the tests are
118
+ the branch's only evidence for its claims.
72
119
  - **Maintainability.** Complexity, naming, duplication — only when material.
73
120
 
74
121
  ## Stage 2 — Security (always full)
@@ -102,7 +149,12 @@ cannot write that sentence, the finding is not ready — drop it or mark it
102
149
  uncertain. No vibes.
103
150
 
104
151
  ## Report — then escalate
105
- Order findings most severe first.
152
+ **Open with the one-line verdict**, before any section: **Ready to merge? Yes /
153
+ No / Not until these are fixed.** A report that opens with "Critical: none
154
+ found" reads as a pass at a glance even when the verdict is not one — state the
155
+ verdict first, then repeat it at the end.
156
+
157
+ Then the findings, ordered most severe first.
106
158
 
107
159
  ### 🚨 Critical (blocks merge)
108
160
  ### ⚠️ Warnings (should fix)
@@ -117,7 +169,8 @@ with its evidence. A stage you did not actually run is a **✗**, never an
117
169
  assumed pass.
118
170
 
119
171
  End with:
120
- - **Reviewed at HEAD `<sha>` on `<branch>`.**
172
+ - **Reviewed at HEAD `<sha>` on `<branch>`, target `<resolved range or path>`,
173
+ tree clean at start and at exit.**
121
174
  - One-line verdict: **Ready to merge? Yes / No / Not until these are fixed.**
122
175
  - **Escalate to the orchestrator** with the findings. It decides what gets
123
176
  fixed and by whom. Say plainly what you could not verify.
@@ -13,12 +13,15 @@ It does not re-implement checks, and it does not review code. Review is a
13
13
  separate command that must have run first.
14
14
 
15
15
  ## Guardrails
16
- - **Spawn a worker on a mid-tier model, not hardcoded.** The run happens in a
17
- subagent on your tool's balanced default tier judgment-capable, cheaper and
18
- faster than your top reasoning tier. **Not the cheapest/fastest tier**: on
19
- judgment work it measurably degrades (misclassification rates several times
20
- higher). Never hardcode a vendor-specific model name. Fall back to running
21
- inline if your tool has no subagent mechanism.
16
+ - **Spawn a worker and explicitly select your tool's mid tier.** State the
17
+ tier on the spawn do not omit it and rely on a default. An omitted tier
18
+ inherits the *parent's* tier, which is not the same thing as the balanced
19
+ one. Pick the judgment-capable tier that is cheaper and faster than your top
20
+ reasoning tier. **Not the cheapest/fastest tier**: on judgment work it
21
+ measurably degrades (misclassification rates several times higher). Choose by
22
+ tier, not by a vendor model name copied from this file — names drift, and
23
+ this command ships to several tools. Fall back to running inline if your tool
24
+ has no subagent mechanism.
22
25
  - **Escalate, never assume.** Anything you cannot decide, cannot verify, or
23
26
  that this spec does not cover → **stop and report it to the orchestrator**
24
27
  (the main session). Never improvise, never widen scope, never fix a finding
@@ -31,24 +34,45 @@ separate command that must have run first.
31
34
  - **Release the branch you are on.** No branch argument, no branch creation.
32
35
  - **On `main` → stop and ask** what should be released. `main` is only ever
33
36
  the merge target; never release it, never commit to it.
34
- - If the working tree still has uncommitted feature changes, commit them to
35
- the branch now the gate must see a real diff, not a dirty tree.
37
+ - **The tree must be clean do not commit for the user.** Run `git status
38
+ --porcelain`. Any line at all modified, staged, or untracked is a
39
+ **stop**: list the paths and say "commit this to the branch, re-run
40
+ `/branch-review`, then re-run `/release`." Committing here would create a
41
+ commit *after* the review and so fail Phase 0.5 by its own rule on the very
42
+ next step; a phase that guarantees the next phase fails is not a phase.
36
43
  - `git fetch origin`; the release diff is `origin/main...HEAD`. Empty →
37
44
  **stop**, nothing to release.
38
- - Print a one-line plan: branch · commit count · files changed · HEAD SHA.
45
+ - **Record both version numbers.** Read the **local** version (`package.json`
46
+ or this project's equivalent) and, if the project has a publish path, the
47
+ **published** one (`npm view <pkg> version`, or the registry equivalent).
48
+ Report them side by side. Local *ahead* of published means a version was cut
49
+ on a branch and never published — Phase 3 cannot see that gap unless you
50
+ record it here, and a worker that cannot see it will re-cut a number that
51
+ already exists.
52
+ - Print a one-line plan: branch · commit count · files changed · HEAD SHA ·
53
+ local version → published version.
39
54
 
40
55
  ## Phase 0.5 — Review precondition (do not skip)
41
- Ask the orchestrator: **has `/branch-review` or `/code-review` run on this
42
- branch at the current HEAD SHA?**
43
-
44
- - **No review** **stop**: "No review at `<sha>`. Run `/branch-review medium`
45
- (or `/code-review medium`) first."
46
- - **Stale** the review ran at an earlier SHA, i.e. commits landed after it
47
- (including fix commits) **stop** and ask for a re-review. This is what
48
- makes "all findings fixed" checkable instead of promised.
56
+ A review must have run on this branch **at the current HEAD SHA**.
57
+
58
+ **Compare the SHAs yourself; do not settle for an answer.** Run `git rev-parse
59
+ HEAD` and compare it against the SHA the review recorded `/branch-review`
60
+ ends with `Reviewed at HEAD <sha>`. Asking the orchestrator "did a review run?"
61
+ puts the question to the one party with an incentive to say yes, so its word is
62
+ not evidence: obtain the review's own recorded SHA and match the two strings.
63
+ **No recorded SHA to compare = no review**, never a pass.
64
+
65
+ - **No review**, or no recorded SHA obtainable → **stop**: "No review at
66
+ `<sha>`. Run `/branch-review medium` (or `/code-review medium`) first."
67
+ - **Stale** — recorded SHA ≠ `git rev-parse HEAD`, i.e. commits landed after
68
+ the review (including fix commits) → **stop** and ask for a re-review. This
69
+ is what makes "all findings fixed" checkable instead of promised.
49
70
  - **Reviewed at this SHA with findings outstanding** → **stop**. Findings are
50
71
  resolved before a release is cut.
51
72
 
73
+ Report the comparison you actually ran: recorded `<sha>` vs HEAD `<sha>`,
74
+ match yes/no.
75
+
52
76
  This is the only thing guaranteeing the branch was reviewed *and* security
53
77
  scanned, so treat a missing answer as a **stop**, never as a pass.
54
78
 
@@ -90,7 +114,11 @@ If a doc needs no change, **say so** rather than editing it for its own sake.
90
114
 
91
115
  ## Phase 3 — Cut (local only)
92
116
  1. **Version bump** — pick the semver level from the change (patch / minor /
93
- major; **ask if ambiguous**) and update `package.json`. The bump must land
117
+ major; **ask if ambiguous**) and update `package.json`. The local-vs-
118
+ published gap you recorded in Phase 0 **is** an ambiguity: if local is ahead
119
+ of published, a version was cut and never published, so ask whether to
120
+ publish that number or bump past it. Never silently re-cut a version that
121
+ already exists locally. The bump must land
94
122
  on the branch, before any merge — a version committed to `main` directly,
95
123
  or added after the merge, breaks the tag/package match.
96
124
  2. **Commit** — `release: vX.Y.Z — <summary>`, including the docs and the
@@ -98,6 +126,12 @@ If a doc needs no change, **say so** rather than editing it for its own sake.
98
126
 
99
127
  Then **stop.** Nothing else.
100
128
 
129
+ This release commit is the **one** commit allowed to land after the review, and
130
+ only because it contains docs and a version number — no code, so it cannot
131
+ invalidate a finding. It does move HEAD past the reviewed SHA, which is why
132
+ `/release` must not be run twice on the same branch without a re-review: the
133
+ second run will correctly stop as stale.
134
+
101
135
  ## Report — the sequence, for a human to authorize
102
136
  Print the evidence, then hand back the exact remaining steps so the
103
137
  orchestrator can run them on the user's named go:
@@ -108,7 +142,9 @@ orchestrator can run them on the user's named go:
108
142
  > 1. `git push -u origin <branch>`
109
143
  > 2. `gh pr create` into `main`
110
144
  > 3. `gh pr merge --admin --squash --delete-branch` (main is PR-protected;
111
- > owner-authorized admin merge on a solo repo)
145
+ > owner-authorized admin merge on a solo repo). **Keep `--squash`** — `gh`
146
+ > requires an explicit merge-method flag (`--squash` / `--merge` /
147
+ > `--rebase`); drop it and the command will not squash-merge.
112
148
  > 4. `git tag vX.Y.Z` on `main` and push the tag
113
149
  > 5. Publish **if this project has a publish path** (e.g.
114
150
  > `gh workflow run publish.yml`) — manual by design