@jagreehal/shepherd 0.0.0-stage → 0.2.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/AGENTS.md +158 -0
- package/LICENSE +21 -0
- package/README.md +445 -2
- package/THIRD_PARTY_NOTICES.md +41 -0
- package/commands/shepherd.md +18 -0
- package/examples/local-demo/baseline/src/config.ts +2 -0
- package/examples/local-demo/baseline/src/db.ts +5 -0
- package/examples/local-demo/baseline/src/notes.ts +15 -0
- package/examples/local-demo/baseline/src/users.ts +8 -0
- package/examples/local-demo/expected.json +12 -0
- package/examples/local-demo/planted/src/config.ts +2 -0
- package/examples/local-demo/planted/src/notes.ts +15 -0
- package/examples/local-demo/planted/src/search.ts +8 -0
- package/examples/local-demo/planted/src/users.ts +8 -0
- package/lenses/observability/SKILL.md +26 -0
- package/package.json +46 -4
- package/skills/ci-repair/SKILL.md +178 -0
- package/skills/code-review/SKILL.md +89 -0
- package/skills/code-review/agents/openai.yaml +3 -0
- package/skills/diagnosing-bugs/SKILL.md +138 -0
- package/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +44 -0
- package/skills/garden/SKILL.md +144 -0
- package/skills/incident/SKILL.md +261 -0
- package/skills/pair/SKILL.md +111 -0
- package/skills/pr/CREDITS.md +3 -0
- package/skills/pr/SKILL.md +170 -0
- package/skills/pr/agents/openai.yaml +3 -0
- package/skills/retro/SKILL.md +44 -0
- package/skills/retro/agents/openai.yaml +5 -0
- package/skills/review-correctness/SKILL.md +80 -0
- package/skills/review-maintainability/SKILL.md +86 -0
- package/skills/review-security/SKILL.md +75 -0
- package/skills/review-simplicity/SKILL.md +87 -0
- package/skills/review-slop/SKILL.md +94 -0
- package/skills/review-spec/SKILL.md +57 -0
- package/skills/shepherd/SKILL.md +407 -0
- package/skills/shepherd/references/degradation.md +21 -0
- package/skills/shepherd/references/dispatch.md +117 -0
- package/skills/shepherd/references/formats.md +46 -0
- package/skills/shepherd/references/models.md +88 -0
- package/skills/shepherd/references/policy.md +110 -0
- package/skills/swarm/SKILL.md +521 -0
- package/skills/swarm/references/custom-lenses.md +129 -0
- package/skills/swarm/references/formats.md +91 -0
- package/skills/triage/SKILL.md +388 -0
- package/skills/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/skills/writing-for-agents/SKILL.md +81 -0
- package/skills/writing-for-agents/agents/openai.yaml +3 -0
- package/src/acceptance.ts +111 -0
- package/src/cli.ts +379 -0
- package/src/config.ts +439 -0
- package/src/doctor.ts +153 -0
- package/src/garden.ts +198 -0
- package/src/install.ts +86 -0
- package/src/lens.ts +178 -0
- package/src/local.ts +393 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pr
|
|
3
|
+
description: "Use when writing a PR body."
|
|
4
|
+
metadata:
|
|
5
|
+
credits:
|
|
6
|
+
skill: show-me
|
|
7
|
+
author: Dex Horthy
|
|
8
|
+
organisation: Humanlayer
|
|
9
|
+
url: "https://github.com/humanlayer/skills/blob/main/plugins/show-me/skills/show-me/SKILL.md"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Use this template for writing the PR body:
|
|
13
|
+
|
|
14
|
+
```markdown
|
|
15
|
+
## Summary
|
|
16
|
+
|
|
17
|
+
<diagram, diff-sketch, or tree>
|
|
18
|
+
|
|
19
|
+
## Evidence
|
|
20
|
+
|
|
21
|
+
- **Before:** <screenshot/output/failing test run>
|
|
22
|
+
**After:** <screenshot/output/passing test run>
|
|
23
|
+
|
|
24
|
+
## Merge Danger
|
|
25
|
+
|
|
26
|
+
**Door:** <one-way or two-way>
|
|
27
|
+
|
|
28
|
+
<optional: description>
|
|
29
|
+
|
|
30
|
+
**Blast Radius:** <one-word description>
|
|
31
|
+
|
|
32
|
+
<optional: potential ramifications of merge>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Sections
|
|
36
|
+
|
|
37
|
+
Skip all preambles and keep prose brief. Use the user's domain language from `GLOSSARY.md`.
|
|
38
|
+
|
|
39
|
+
### Summary
|
|
40
|
+
|
|
41
|
+
Pick the smallest view that makes the key point clear.
|
|
42
|
+
|
|
43
|
+
- Show logic or an algorithm as pseudocode:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
on(save)
|
|
47
|
+
if content is unchanged
|
|
48
|
+
return cached result
|
|
49
|
+
write new content
|
|
50
|
+
return fresh result
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- Show runtime control flow as a call tree:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
submitForm
|
|
57
|
+
createSession
|
|
58
|
+
persistPrompt
|
|
59
|
+
launchAgent
|
|
60
|
+
navigateToSession
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- Show UI structure as a component tree, including state and module boundaries that matter:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
<SessionPage> (apps/example/src/routes/session.tsx)
|
|
67
|
+
useSessionEvents()
|
|
68
|
+
<SessionToolbar>
|
|
69
|
+
<RunSkillButton> (packages/ui)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- Show file responsibility or a broad refactor as a shallow file tree:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
src/
|
|
76
|
+
├── commands/ # parses user actions
|
|
77
|
+
├── sessions/ # owns session state
|
|
78
|
+
└── transport/ # sends API requests
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- Show component interaction, control flow, or data flow with Mermaid:
|
|
82
|
+
|
|
83
|
+
```mermaid
|
|
84
|
+
sequenceDiagram
|
|
85
|
+
participant User
|
|
86
|
+
participant UI
|
|
87
|
+
participant Daemon
|
|
88
|
+
User->>UI: choose command
|
|
89
|
+
UI->>Daemon: send expanded prompt
|
|
90
|
+
Daemon-->>UI: stream result
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- Use `diff` when the point is what changes and the surrounding shape already exists. Match the diff shape to the topic.
|
|
94
|
+
|
|
95
|
+
For a component change:
|
|
96
|
+
|
|
97
|
+
```diff
|
|
98
|
+
<SessionPage>
|
|
99
|
+
useSessionEvents()
|
|
100
|
+
<SessionToolbar>
|
|
101
|
+
+ <RunSkillButton />
|
|
102
|
+
<SessionTimeline>
|
|
103
|
+
+ <SkillResultCard />
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For a file-layout change:
|
|
107
|
+
|
|
108
|
+
```diff
|
|
109
|
+
src/
|
|
110
|
+
├── commands/
|
|
111
|
+
+│ └── show-me.ts # expands the slash command
|
|
112
|
+
├── sessions/
|
|
113
|
+
-└── transport.ts
|
|
114
|
+
+└── transport/
|
|
115
|
+
+ ├── client.ts
|
|
116
|
+
+ └── stream.ts
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
For a call-tree or call-stack change:
|
|
120
|
+
|
|
121
|
+
```diff
|
|
122
|
+
submitForm
|
|
123
|
+
createSession
|
|
124
|
+
persistPrompt
|
|
125
|
+
+ expandSkillMention
|
|
126
|
+
launchAgent
|
|
127
|
+
- navigateToSession
|
|
128
|
+
+ navigateToSession
|
|
129
|
+
+ subscribeToEvents
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
For a state or control-flow change:
|
|
133
|
+
|
|
134
|
+
```diff
|
|
135
|
+
on(save)
|
|
136
|
+
- write content
|
|
137
|
+
+ if content is unchanged
|
|
138
|
+
+ return cached result
|
|
139
|
+
+ write new content
|
|
140
|
+
+ invalidate cache
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- Show the whole block when most of it is new, when omitted context would hide ownership or order, or when the user needs a copyable target shape:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
function expandSkill(command: string): string {
|
|
147
|
+
const skillName = command.slice(1);
|
|
148
|
+
return `use the ${skillName} skill`;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### Guidance
|
|
153
|
+
|
|
154
|
+
Place each visual next to the short text it supports. Keep only the calls, files, props, states, and boundaries needed to answer the user's current question or the options to resolve the current discussion point.
|
|
155
|
+
|
|
156
|
+
You may use one of these, you may use several, it is unlikely you will use all of them. Use your judgement and don't overwhelm the user.
|
|
157
|
+
|
|
158
|
+
### Evidence
|
|
159
|
+
|
|
160
|
+
Concrete evidence that the change works. Show a before and after.
|
|
161
|
+
|
|
162
|
+
Screenshots are S-tier - when the environment is set up for it and the change is visual.
|
|
163
|
+
|
|
164
|
+
Execution-based evidence is A-tier. Test results, console output. Show the exact test that now fails and passes, using pseudocode.
|
|
165
|
+
|
|
166
|
+
### Merge Danger
|
|
167
|
+
|
|
168
|
+
Describe whether it's a one-way or two-way door. You can walk back through two-way doors, but not one-way doors. A PR that is cheap to roll back is lower risk. Changes that involve destructive actions or hard-to-reverse decisions are one-way doors.
|
|
169
|
+
|
|
170
|
+
The blast radius is the potential impact or scope of the changes introduced by this PR. Consider all possibilities. Examples are layout shift, breakages for consumers, mobile responsiveness, etc.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: retro
|
|
3
|
+
description: "Conduct a retrospective on a coding session."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
The user has asked for a **retrospective**. You are suggesting improvements to the coding agent's **environment** to improve future runs.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
1. Call the Skill tool with `writing-for-agents` for the writing style guide.
|
|
12
|
+
|
|
13
|
+
2. Read the primary sources for the session the user specifies. This may mean searching through session logs on this machine. If the user doesn't specify a session, default to the current one.
|
|
14
|
+
|
|
15
|
+
3. Look for candidates for improvement in these categories.
|
|
16
|
+
|
|
17
|
+
- **Navigation**: how easy was it for the agent to find the right files? Are there hidden dependencies between files? Would a **navigation pointer** make it easier? _Use when_ the session took a long time to find a piece of information.
|
|
18
|
+
- **Automated checks**: are there automated checks that could catch errors the agent made? Linting, typing, tests, filesystem linters? Read the repo's own check command first (its `package.json`/build-tool `lint`/`check` scripts, its CI workflow), so a check that already exists but sits unwired or silently broken is the finding, not a reinvention. A repo with no **guardrail** (no pre-commit hook and no CI job running its lint/typecheck/test command) is itself a finding: an un-linted repo is a standing missed opportunity, not a neutral default. _Use when_ the agent made a mistake an automated check could have caught, or the repo has no guardrail at all.
|
|
19
|
+
- **Coding standards**: should the **reviewer agent** be given a new rule to enforce? Should an existing rule be removed or clarified? Classify the violation first: a **mechanical** one (a fixed syntactic pattern, a banned API, an import shape, a file-location rule) gets a deterministic check, full stop: a custom rule in the repo's own linter, a new pre-commit hook, or a new CI job, whichever the repo's language and existing guardrail make cheapest. Default to building the check over writing the rule. Reserve `CODING_STANDARDS.md` for genuine **judgement calls** (cross-file consistency, "matches the surrounding style," anything no guardrail could ever substitute for). _Use when_ the reviewer agent failed to catch a mistake.
|
|
20
|
+
- **Global AGENTS.md**: are there any steering instructions that should be moved to coding standards (or automated checks) instead? _Use when_ the AGENTS.md file is particularly large - in the repo OR the user's global scope.
|
|
21
|
+
- **Tool economy**: did the agent make expensive tool calls that could be streamlined? Is there any custom tooling (CLI's, MCP's) that is particularly token-inefficient? _Use when_ the agent made an expensive tool call.
|
|
22
|
+
- **No-ops**: look for instructions in steering files that don't modify the agent's behavior. _Use when_ the steering files are large and unwieldy.
|
|
23
|
+
- **Information access**: look for opportunities to increase the agent's access to information. Teeing dev server logs, readonly access to third-party services. _Use when_ a crucial piece of information was not available to the agent.
|
|
24
|
+
|
|
25
|
+
4. Present these candidates to the user, in order of severity.
|
|
26
|
+
|
|
27
|
+
## Reference
|
|
28
|
+
|
|
29
|
+
### Implementation vs Review
|
|
30
|
+
|
|
31
|
+
Remember that all work goes through two stages: implementation and review. The implementation agent has the most **context pressure**. They are responsible for exploration, writing code, and debugging failures.
|
|
32
|
+
|
|
33
|
+
The review agent has the least context pressure - it receives a diff, so no exploration needed. It often does not need to write code or debug.
|
|
34
|
+
|
|
35
|
+
This means that the review agent should be responsible for imposing coding standards, not the implementation agent.
|
|
36
|
+
|
|
37
|
+
### Files
|
|
38
|
+
|
|
39
|
+
You have access to several files in the repo:
|
|
40
|
+
|
|
41
|
+
- `CLAUDE.md`/`AGENTS.md`: these files are pushed to the context window of any agent working in this repo. They should be used incredibly sparingly, usually only for **navigation pointers** to other files.
|
|
42
|
+
- `CODING_STANDARDS.md`: this file is read during review, not implementation. Add **navigation pointers** to docs folders if the standards file gets more than 1,000 lines long.
|
|
43
|
+
- Docs: use docs as references files, pointed to by other files. Look for existing docs before writing new ones.
|
|
44
|
+
- Skills: use skills for docs (since their description goes into the agent's context window), or for user-invoked commands. Follow the advice in the `writing-for-agents` skill.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-correctness
|
|
3
|
+
description: >
|
|
4
|
+
Correctness lens: finds bugs a change introduces, walking the diff as a set of
|
|
5
|
+
specialists (data, concurrency, performance, API contracts, frontend state,
|
|
6
|
+
tests) against a catalogue of incident patterns. Used by swarm; run it
|
|
7
|
+
standalone with "/review-correctness" or "check this diff for bugs".
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Correctness lens
|
|
11
|
+
|
|
12
|
+
You find the bugs this change introduces. Not style, not taste: behaviour that
|
|
13
|
+
will be wrong in production, or tests that will not catch it when it is.
|
|
14
|
+
|
|
15
|
+
## How to read the diff
|
|
16
|
+
|
|
17
|
+
1. Read the whole diff once for its intent. The PR title and body say what the
|
|
18
|
+
author meant; the diff says what they did. Gaps between the two are findings.
|
|
19
|
+
2. Sort the changed files into the specialist areas below. Most diffs touch two
|
|
20
|
+
or three.
|
|
21
|
+
3. For each area, read each hunk with at least 50 lines of context, then trace
|
|
22
|
+
one caller and one callee. Many bugs live at the boundary the diff changed.
|
|
23
|
+
4. Check the incident patterns for every area you touched.
|
|
24
|
+
5. Before you report a finding, find the line that proves it. "Could be null"
|
|
25
|
+
needs the path where it is null.
|
|
26
|
+
|
|
27
|
+
## Specialists
|
|
28
|
+
|
|
29
|
+
- **Data.** Queries, ORMs, migrations, serialisation. Missing index on a new
|
|
30
|
+
filter, unbounded query, N+1 in a loop, a migration that locks a big table or
|
|
31
|
+
is not reversible, a column added as NOT NULL without a default, JSON shape
|
|
32
|
+
drift between writer and reader.
|
|
33
|
+
- **Concurrency.** Shared state, async, queues, caches. Check-then-act races,
|
|
34
|
+
missing `await`, a retry around a call that is not idempotent, a lock held
|
|
35
|
+
across I/O, cache writes without invalidation, ordering assumptions on a queue.
|
|
36
|
+
- **Performance.** Work inside a hot loop, sync I/O on a request path, a
|
|
37
|
+
regex that backtracks, whole-collection loads where a page would do, memory
|
|
38
|
+
that grows per request.
|
|
39
|
+
- **API contracts.** A changed response shape, a renamed field, a new required
|
|
40
|
+
parameter, a status code change, an error type change. Anything a caller
|
|
41
|
+
outside this diff depends on.
|
|
42
|
+
- **Frontend state.** Effects with missing dependencies, stale closures,
|
|
43
|
+
listeners or timers never cleaned up, detached DOM nodes held in state, keys
|
|
44
|
+
that are array indices on a reorderable list, optimistic updates that never
|
|
45
|
+
roll back.
|
|
46
|
+
- **Tests.** A test that passes whatever the code does (asserts nothing, mocks
|
|
47
|
+
the unit under test, catches the error it should surface), a skipped or
|
|
48
|
+
`.only` test, an assertion loosened to make a change pass, a new branch with
|
|
49
|
+
no test at all.
|
|
50
|
+
|
|
51
|
+
## Incident patterns
|
|
52
|
+
|
|
53
|
+
Check each one that fits the diff:
|
|
54
|
+
|
|
55
|
+
- off-by-one on ranges, pagination cursors, and slice bounds
|
|
56
|
+
- timezone and DST: naive datetimes, `now()` in the wrong zone, date-only math
|
|
57
|
+
- money in floats; rounding applied twice
|
|
58
|
+
- `null`/`undefined`/empty treated alike when they mean different things
|
|
59
|
+
- errors swallowed by a broad `catch`, or logged and then ignored
|
|
60
|
+
- partial failure: a loop that writes some rows, fails, and leaves no marker
|
|
61
|
+
- resource leaks: files, connections, subscriptions, event listeners
|
|
62
|
+
- feature flags whose default is the new behaviour
|
|
63
|
+
- config read at import time that a test or deploy overrides later
|
|
64
|
+
- string comparison on things that need normalising (case, Unicode, trailing slash)
|
|
65
|
+
- a boolean parameter whose meaning flipped with a rename
|
|
66
|
+
|
|
67
|
+
## Severity
|
|
68
|
+
|
|
69
|
+
- **CRITICAL** — data loss, corruption, or an outage on a normal path.
|
|
70
|
+
- **HIGH** — wrong behaviour users will hit, or a test gap over risky logic.
|
|
71
|
+
- **MEDIUM** — wrong on an edge case, or a performance cliff at plausible scale.
|
|
72
|
+
- **LOW** — wrong only in an unlikely case; a cheap fix.
|
|
73
|
+
- **NIT** — correctness-adjacent tidying.
|
|
74
|
+
|
|
75
|
+
## Output
|
|
76
|
+
|
|
77
|
+
End with `STRUCTURED_FINDINGS` and `OVERALL_SUMMARY` in the swarm format
|
|
78
|
+
(`../swarm/references/formats.md`), tags like `correctness/concurrency`. Each
|
|
79
|
+
body says what goes wrong, on which input, and the concrete fix. Standalone,
|
|
80
|
+
print the same list, highest severity first.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-maintainability
|
|
3
|
+
description: >
|
|
4
|
+
Maintainability lens: reads a diff the way a senior teammate would, for
|
|
5
|
+
coupling, fragile mechanisms, naming, observability, rollout safety, and the
|
|
6
|
+
repo's own written rules. Asks more than it demands and picks the few things
|
|
7
|
+
that matter. Used by swarm; run it standalone with "/review-maintainability"
|
|
8
|
+
or "review this like a teammate would".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Maintainability lens
|
|
12
|
+
|
|
13
|
+
You are the teammate who will own this code next quarter. You care whether it
|
|
14
|
+
is easy to change, easy to see in production, and safe to roll out. You trust
|
|
15
|
+
the author, ask when you are unsure, and block only for real risk.
|
|
16
|
+
|
|
17
|
+
## House rules first
|
|
18
|
+
|
|
19
|
+
Read the repo's written conventions from the **default branch**, not the PR
|
|
20
|
+
head, so a PR cannot relax the rules it is judged by:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git fetch -q origin <default>
|
|
24
|
+
git show origin/<default>:AGENTS.md # also CLAUDE.md, CONTRIBUTING.md, docs/adr/
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
A change that breaks a written rule is a finding, and the body quotes the rule.
|
|
28
|
+
That makes it actionable for `triage`, which never resolves a rule-citing
|
|
29
|
+
thread without acting on it.
|
|
30
|
+
|
|
31
|
+
## What you look for, most important first
|
|
32
|
+
|
|
33
|
+
1. **Coupling and fragility.**
|
|
34
|
+
- Two arrays that only work because they share an order. Key a map by the
|
|
35
|
+
real identifier.
|
|
36
|
+
- Components reaching into each other through DOM selectors, string event
|
|
37
|
+
names, or global state instead of an explicit interface.
|
|
38
|
+
- New circular imports.
|
|
39
|
+
- Tests whose mocks have drifted from the real thing. A mock that passes
|
|
40
|
+
while production breaks is worse than no test.
|
|
41
|
+
- A change that needs edits in many unrelated files (shotgun surgery) points
|
|
42
|
+
at a missing seam.
|
|
43
|
+
2. **Observability and rollout.**
|
|
44
|
+
- How will anyone know this works in production? Look for the log, metric,
|
|
45
|
+
event, or trace that would show it. Silent data drops need a count.
|
|
46
|
+
- Risky or disruptive behaviour belongs behind a flag with a safe default.
|
|
47
|
+
A change meant to move a metric wants an experiment so the effect is
|
|
48
|
+
measurable. A refactor or bug fix needs neither. Treat this as judgement,
|
|
49
|
+
not a rule.
|
|
50
|
+
- Can it roll back? Watch for one-way doors: data rewritten in place, a
|
|
51
|
+
removed field clients still send.
|
|
52
|
+
3. **Naming and readability.**
|
|
53
|
+
- Booleans named for the opposite of what they hold, names left over from
|
|
54
|
+
before a rename, abbreviations only the author knows, user-facing copy that
|
|
55
|
+
reads badly.
|
|
56
|
+
- Mixed abstraction levels in one function. Suggest the specific extraction.
|
|
57
|
+
4. **Types over constants.** A string-literal union or enum the compiler checks
|
|
58
|
+
beats an exported constant and a runtime check.
|
|
59
|
+
5. **API empathy.** Would a caller outside this diff find the new interface
|
|
60
|
+
obvious? Required parameters in a sensible order, errors that say what to do.
|
|
61
|
+
6. **Dead weight.** Selectors, styles, flags, or endpoints the diff made unused.
|
|
62
|
+
7. **Tests.** Several near-identical tests want one parameterised test.
|
|
63
|
+
|
|
64
|
+
## How you write
|
|
65
|
+
|
|
66
|
+
- Short. A question is often enough: "what happens to the old rows here?"
|
|
67
|
+
- Say how sure you are. "i might be missing context, but..." is fine.
|
|
68
|
+
- Mark preferences as preferences: "not blocking" or "feel free to disagree".
|
|
69
|
+
- Praise what is good in one line when it earns it.
|
|
70
|
+
- Pick the three to five things that matter most. Do not dump twenty comments.
|
|
71
|
+
- No closing summary paragraph restating the comments.
|
|
72
|
+
|
|
73
|
+
## Severity
|
|
74
|
+
|
|
75
|
+
- **HIGH** — a coupling or rollout risk that will likely cause an incident, or a broken written house rule on a risky path.
|
|
76
|
+
- **MEDIUM** — a fragile mechanism, a missing way to observe a risky change, a broken house rule.
|
|
77
|
+
- **LOW** — naming, readability, API polish.
|
|
78
|
+
- **NIT** — pure preference.
|
|
79
|
+
|
|
80
|
+
## Output
|
|
81
|
+
|
|
82
|
+
End with `STRUCTURED_FINDINGS` and `OVERALL_SUMMARY` in the swarm format
|
|
83
|
+
(`../swarm/references/formats.md`), tags `maintainability/coupling`,
|
|
84
|
+
`maintainability/rollout`, `maintainability/naming`, `maintainability/house-rule`,
|
|
85
|
+
`maintainability/api`. Standalone, write the comments as you would leave them
|
|
86
|
+
on the PR.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-security
|
|
3
|
+
description: >
|
|
4
|
+
Security lens: traces untrusted input from where it enters to where it lands
|
|
5
|
+
and reports exploitable paths the diff opens (injection, authz gaps, SSRF,
|
|
6
|
+
secrets, prompt injection, supply chain), each with its data flow and fix.
|
|
7
|
+
Used by swarm; run it standalone with "/review-security" or "security review
|
|
8
|
+
this diff".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Security lens
|
|
12
|
+
|
|
13
|
+
You report the exploitable paths this change opens. A finding names who
|
|
14
|
+
controls the input, the path it takes, where it lands, and what they gain.
|
|
15
|
+
Without that chain it is a hunch; mark it LOW or leave it out.
|
|
16
|
+
|
|
17
|
+
## Method
|
|
18
|
+
|
|
19
|
+
1. List the **sources** the diff touches: request params, headers, cookies,
|
|
20
|
+
uploaded files, webhooks, queue messages, environment the user sets, database
|
|
21
|
+
rows users wrote, third-party API responses, LLM output, and PR or issue text
|
|
22
|
+
that reaches automation.
|
|
23
|
+
2. List the **sinks**: shell, SQL, templates, HTML, file paths, URLs fetched
|
|
24
|
+
server-side, deserialisers, `eval`, redirects, log lines, model prompts and
|
|
25
|
+
tool calls, and anything that grants access.
|
|
26
|
+
3. For each source-to-sink pair the diff creates or changes, trace the path and
|
|
27
|
+
the checks along it. Read the whole function, not only the hunk.
|
|
28
|
+
4. Check authorisation separately from authentication. "Logged in" is not "may
|
|
29
|
+
touch this tenant's row".
|
|
30
|
+
|
|
31
|
+
Do not ask clarifying questions. If reachability or tenancy is unclear from the
|
|
32
|
+
code, state the assumption in the finding's `Confidence` line and carry on.
|
|
33
|
+
|
|
34
|
+
## Categories
|
|
35
|
+
|
|
36
|
+
`injection` (SQL, shell, template, LDAP, header), `xss`, `idor` / broken
|
|
37
|
+
authz, `authn` (session, token, password, MFA handling), `ssrf`, `path-traversal`,
|
|
38
|
+
`deserialisation`, `secrets` (committed keys, keys in logs, keys sent to a third
|
|
39
|
+
party), `crypto` (home-made crypto, weak randomness for tokens, missing constant-time
|
|
40
|
+
compare), `csrf` / `cors`, `open-redirect`, `dos` (unbounded input, regex
|
|
41
|
+
backtracking, zip bombs), `supply-chain` (new dependency, install scripts,
|
|
42
|
+
unpinned actions, `curl | sh`), `ci` (`pull_request_target` with a checkout of
|
|
43
|
+
PR code, secrets exposed to forks, workflow write permissions), and
|
|
44
|
+
`prompt-injection` (untrusted text reaching a model that holds tools or secrets,
|
|
45
|
+
or model output reaching a sink unchecked).
|
|
46
|
+
|
|
47
|
+
## Severity
|
|
48
|
+
|
|
49
|
+
- **CRITICAL** — remote exploit with no preconditions: RCE, auth bypass, cross-tenant data read or write, a live secret committed.
|
|
50
|
+
- **HIGH** — exploitable with a normal account, or needing one plausible precondition.
|
|
51
|
+
- **MEDIUM** — needs an unusual precondition, or the impact is contained.
|
|
52
|
+
- **LOW** — defence in depth; hardening with no exploit shown.
|
|
53
|
+
|
|
54
|
+
This lens has no NIT tier.
|
|
55
|
+
|
|
56
|
+
## Finding body
|
|
57
|
+
|
|
58
|
+
Keep these labels, in this order, so the shape survives into the PR comment:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
Description: <one sentence>
|
|
62
|
+
Data flow: <source> -> <step> -> <sink>
|
|
63
|
+
Exploit: <what an attacker sends and what they get>
|
|
64
|
+
Fix: <the concrete change>
|
|
65
|
+
Confidence: <high|medium|low>, <assumption if any>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Do not write reproducer tests and do not offer to fix. Your output becomes
|
|
69
|
+
review comments.
|
|
70
|
+
|
|
71
|
+
## Output
|
|
72
|
+
|
|
73
|
+
End with `STRUCTURED_FINDINGS` and `OVERALL_SUMMARY` in the swarm format
|
|
74
|
+
(`../swarm/references/formats.md`), tags like `security/idor`. Standalone, print
|
|
75
|
+
the same list, most severe first.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-simplicity
|
|
3
|
+
description: >
|
|
4
|
+
Simplicity lens: reviews a diff against the four rules of simple design and
|
|
5
|
+
hunts what can be deleted: speculative features, one-implementation
|
|
6
|
+
abstractions, reinvented standard library, wrong abstractions. Suggests the
|
|
7
|
+
refactoring, not only the smell. Used by swarm; run it standalone with
|
|
8
|
+
"/review-simplicity", "is this over-engineered", or "what can we delete".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Simplicity lens
|
|
12
|
+
|
|
13
|
+
You help the code get simpler. The best outcome of your review is a shorter
|
|
14
|
+
diff that does the same job.
|
|
15
|
+
|
|
16
|
+
## The four rules of simple design
|
|
17
|
+
|
|
18
|
+
In priority order:
|
|
19
|
+
|
|
20
|
+
1. **Passes the tests.** Is it tested, and do the tests prove the behaviour?
|
|
21
|
+
2. **Expresses every idea it needs to.** Can the next person see the intent?
|
|
22
|
+
3. **Says everything once and only once.** Is a concept duplicated?
|
|
23
|
+
4. **Has no superfluous parts.** Is there code nobody needs yet?
|
|
24
|
+
|
|
25
|
+
The rules conflict. Clear duplication can beat a forced abstraction (rule 2
|
|
26
|
+
over rule 3). Balance them for whoever maintains this next year.
|
|
27
|
+
|
|
28
|
+
## What to look for
|
|
29
|
+
|
|
30
|
+
**Delete first:**
|
|
31
|
+
|
|
32
|
+
- **YAGNI.** Options nobody sets, config for a value that never changes, hooks
|
|
33
|
+
"for later", a parameter every caller passes the same way.
|
|
34
|
+
- **One-implementation abstractions.** An interface, factory, base class, or
|
|
35
|
+
strategy with a single concrete user. Inline it until a second one exists.
|
|
36
|
+
- **Reinvented platform.** Hand-rolled code for what the standard library, the
|
|
37
|
+
language, the framework, or an already-installed dependency does. Name the
|
|
38
|
+
function that replaces it.
|
|
39
|
+
- **Dead code.** Unused exports, unreachable branches, a flag that is always on.
|
|
40
|
+
|
|
41
|
+
**Then reshape:**
|
|
42
|
+
|
|
43
|
+
- **Wrong abstraction.** A shared helper that grew a boolean or mode parameter to
|
|
44
|
+
serve two callers. Inline it back and let the callers diverge. A little
|
|
45
|
+
duplication beats the wrong abstraction.
|
|
46
|
+
- **Long method.** A method whose sections need comments wants ComposedMethod:
|
|
47
|
+
extract until each method works at one level of abstraction.
|
|
48
|
+
- **Feature envy.** A method that mostly uses another object's data belongs there.
|
|
49
|
+
- **Primitive obsession.** Strings and numbers doing a type's job. A small type
|
|
50
|
+
or a literal union makes bad states unrepresentable.
|
|
51
|
+
- **Comments that restate code.** Ask whether a rename or an extract-method
|
|
52
|
+
would remove the need.
|
|
53
|
+
- **The smell baseline.** Also match the diff against the smell baseline in
|
|
54
|
+
`../code-review/SKILL.md` (Matt Pocock's `code-review`, its step 3): data
|
|
55
|
+
clumps, repeated switches, message chains, middle man, divergent change and
|
|
56
|
+
the rest. Its two rules bind you: the repo's documented standards override a
|
|
57
|
+
smell, and each smell is a judgement call ("possible Middle Man"), never a
|
|
58
|
+
hard violation. Tag them `simplicity/smell`.
|
|
59
|
+
|
|
60
|
+
## Judgement
|
|
61
|
+
|
|
62
|
+
- **Three strikes.** Duplicate once without guilt. Refactor on the third copy,
|
|
63
|
+
when the real pattern is visible.
|
|
64
|
+
- **Say "this is fine."** Clear, working code that a reviewer could make
|
|
65
|
+
cleverer is fine. YAGNI applies to refactoring too.
|
|
66
|
+
- **Improve what the diff touches.** Do not ask the author to rework untouched code.
|
|
67
|
+
- **Say why.** Name the smell, the refactoring, and what it buys:
|
|
68
|
+
"fetch, transform, and persist in one method; extract the transform and it
|
|
69
|
+
can be tested alone."
|
|
70
|
+
- **Say when you are unsure.** "I might be wrong, but..." is a fine opener.
|
|
71
|
+
|
|
72
|
+
## Severity
|
|
73
|
+
|
|
74
|
+
This lens reports MEDIUM at most. Complexity costs later, not today.
|
|
75
|
+
|
|
76
|
+
- **MEDIUM** — a wrong abstraction, or a speculative layer that will spread.
|
|
77
|
+
- **LOW** — a concrete deletion or stdlib swap.
|
|
78
|
+
- **NIT** — a naming or tidying suggestion.
|
|
79
|
+
|
|
80
|
+
## Output
|
|
81
|
+
|
|
82
|
+
End with `STRUCTURED_FINDINGS` and `OVERALL_SUMMARY` in the swarm format
|
|
83
|
+
(`../swarm/references/formats.md`), tags `simplicity/yagni`,
|
|
84
|
+
`simplicity/stdlib`, `simplicity/abstraction`, `simplicity/duplication`,
|
|
85
|
+
`simplicity/expression`. Each body names what to cut and what replaces it,
|
|
86
|
+
showing the shorter form when it fits in two lines. Standalone, end with
|
|
87
|
+
`net: -<N> lines possible`.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-slop
|
|
3
|
+
description: >
|
|
4
|
+
Slop lens: flags low-signal code and prose that coding agents tend to produce:
|
|
5
|
+
types widened then asserted back, defensive checks the types already rule out,
|
|
6
|
+
comments that narrate code, tests that prove nothing, and PR text padded with
|
|
7
|
+
filler. Used by swarm; run it standalone with "/review-slop" or "check this
|
|
8
|
+
diff for AI slop".
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Slop lens
|
|
12
|
+
|
|
13
|
+
Slop is code or text that looks finished but carries little evidence: it
|
|
14
|
+
compiles, it reads smoothly, and it hides what it does or whether it works.
|
|
15
|
+
Agents produce it fast, so it needs its own lens.
|
|
16
|
+
|
|
17
|
+
If the repo runs a lint rule that already catches a pattern (for example
|
|
18
|
+
Oxlint's anti-slop plugin), swarm's check step has reported it. Do not repeat
|
|
19
|
+
those. This lens covers what lint cannot see, and every language lint does not
|
|
20
|
+
cover.
|
|
21
|
+
|
|
22
|
+
## Code
|
|
23
|
+
|
|
24
|
+
**Type evidence thrown away**
|
|
25
|
+
|
|
26
|
+
- A value widened to `any`, `unknown`, `object`, or a base type, then asserted
|
|
27
|
+
back to the specific type a few lines later.
|
|
28
|
+
- Chained assertions (`x as unknown as T`) and assertions with no comment naming
|
|
29
|
+
the invariant that makes them safe.
|
|
30
|
+
- `unknown` parameters or return types on internal functions where the real
|
|
31
|
+
type is known.
|
|
32
|
+
- Runtime `typeof` checks on values the static types already pin down.
|
|
33
|
+
- `Record<string, T>` or index signatures used where a fixed set of keys exists.
|
|
34
|
+
|
|
35
|
+
**Defensive noise**
|
|
36
|
+
|
|
37
|
+
- `try/catch` that logs and continues, or rethrows the same error unchanged.
|
|
38
|
+
- Null checks and fallbacks for states the code cannot reach.
|
|
39
|
+
- Guard clauses duplicated at every layer instead of at the boundary.
|
|
40
|
+
- Retries, timeouts, or caches added with no failure they answer.
|
|
41
|
+
|
|
42
|
+
**Shape without substance**
|
|
43
|
+
|
|
44
|
+
- Names that describe the data's shape instead of its meaning (`dataObj`,
|
|
45
|
+
`resultArray`, `mapOfItems`).
|
|
46
|
+
- A single-use options object where plain parameters read better, or a
|
|
47
|
+
parameter bag passed through five layers untouched.
|
|
48
|
+
- `filter().map()` chains and `reduce` with a copied accumulator where one loop
|
|
49
|
+
or one `flatMap` reads cleaner.
|
|
50
|
+
- Helpers, wrappers, or files created for one caller.
|
|
51
|
+
- Conditional empty spreads (`...(x ? {a} : {})`) built up into a config object.
|
|
52
|
+
|
|
53
|
+
**Tests that prove nothing**
|
|
54
|
+
|
|
55
|
+
- Assertions that cannot fail: `expect(x).toBeDefined()` after assigning `x`,
|
|
56
|
+
snapshot tests of mocks, `>= 0` on a count.
|
|
57
|
+
- Module mocking that replaces the unit under test.
|
|
58
|
+
- Test names that describe the implementation instead of the behaviour.
|
|
59
|
+
|
|
60
|
+
**Comments**
|
|
61
|
+
|
|
62
|
+
- Comments that narrate the next line, restate a function name, or describe a
|
|
63
|
+
change history ("now uses X instead of Y").
|
|
64
|
+
- Apology or hedge comments ("this is a workaround", "not ideal") with no
|
|
65
|
+
ticket and no reason.
|
|
66
|
+
|
|
67
|
+
## Prose
|
|
68
|
+
|
|
69
|
+
Read the PR title and body, new docs, and commit messages in the diff. Flag:
|
|
70
|
+
|
|
71
|
+
- filler openers and closers ("This PR...", "In summary", "Let's dive in")
|
|
72
|
+
- adverbs doing no work ("significantly", "seamlessly", "robustly")
|
|
73
|
+
- binary contrasts ("not just X, but Y") and rhetorical setups
|
|
74
|
+
- vague claims with no specifics ("improves performance") where a number or a
|
|
75
|
+
named behaviour belongs
|
|
76
|
+
- em-dash chains and triplet lists used for rhythm
|
|
77
|
+
- claims the diff does not back: a body that says "adds tests" on a diff with
|
|
78
|
+
none is a HIGH finding, because reviewers and `stamp` trust the body
|
|
79
|
+
|
|
80
|
+
## Severity
|
|
81
|
+
|
|
82
|
+
- **HIGH** — slop that hides a bug or misleads a reviewer: an assertion that
|
|
83
|
+
makes an unsafe cast compile, a test that cannot fail on a risky path, a PR
|
|
84
|
+
body claiming work the diff does not contain.
|
|
85
|
+
- **MEDIUM** — thrown-away type evidence or defensive noise on a real code path.
|
|
86
|
+
- **LOW** — naming, comment, and structure slop.
|
|
87
|
+
- **NIT** — prose style.
|
|
88
|
+
|
|
89
|
+
## Output
|
|
90
|
+
|
|
91
|
+
End with `STRUCTURED_FINDINGS` and `OVERALL_SUMMARY` in the swarm format
|
|
92
|
+
(`../swarm/references/formats.md`), tags `slop/types`, `slop/defensive`,
|
|
93
|
+
`slop/shape`, `slop/tests`, `slop/comments`, `slop/prose`. Each body quotes the
|
|
94
|
+
line and shows the plain version.
|