Skip to content

Commit 95c05e3

Browse files
committed
Merge branch 'main' of github.com:NethermindEth/pluto into createdkg
2 parents a48d280 + 4d3b110 commit 95c05e3

File tree

16 files changed

+2217
-153
lines changed

16 files changed

+2217
-153
lines changed

.claude/skills/review-pr/SKILL.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
name: review-pr
3+
description: >
4+
Full multi-agent code review for a Pluto PR. Spawns parallel agents covering
5+
functional correctness, security, Rust style, and code quality, then posts
6+
all findings as isolated GitHub review comments and submits a final
7+
approve/request-changes verdict. Invoke as `/review-pr <PR-number>` or
8+
`/review-pr <GitHub-PR-URL>`.
9+
---
10+
11+
# Review PR
12+
13+
You are orchestrating a thorough code review for a Pluto pull request.
14+
15+
## Input
16+
17+
The argument is either a PR number (e.g. `311`) or a full GitHub PR URL. The
18+
repository is always `NethermindEth/pluto`.
19+
20+
Resolve the PR number if a URL was given:
21+
```bash
22+
# From URL like https://github.com/NethermindEth/pluto/pull/311
23+
PR=311
24+
```
25+
26+
## Step 1 — Gather context
27+
28+
Run these in parallel:
29+
```bash
30+
gh pr view $PR --repo NethermindEth/pluto \
31+
--json title,body,files,additions,deletions,headRefName,commits
32+
gh pr diff $PR --repo NethermindEth/pluto
33+
```
34+
35+
Read every changed file from disk (the branch may already be checked out).
36+
If a file is not available locally, use the raw diff.
37+
38+
Also note the head commit SHA — you will need it for the review API call.
39+
40+
## Step 2 — Parallel agent review
41+
42+
Spawn **four agents in a single message** so they run concurrently. Give each
43+
agent the full diff and relevant file contents in its prompt.
44+
45+
| Agent | Skill | Focus |
46+
|---|---|---|
47+
| **pluto-review** | `/pluto-review` | Functional equivalence with Charon Go; parity matrix; test coverage gaps |
48+
| **security-review** || Auth bypass, resource exhaustion, key-material handling, DoS vectors |
49+
| **rust-style** | `/rust-style` | Idiomatic Rust; memory orderings; error handling patterns; naming |
50+
| **code-quality** || Concurrency correctness; state-machine completeness; resource lifecycle |
51+
52+
Each agent must return findings as JSON objects:
53+
```json
54+
{
55+
"file": "crates/foo/src/bar.rs",
56+
"line": 42,
57+
"severity": "bug|major|minor|nit",
58+
"title": "short title",
59+
"body": "detailed explanation with code snippets if helpful"
60+
}
61+
```
62+
63+
## Step 3 — Deduplicate and assess
64+
65+
Merge the four finding lists. For each finding:
66+
67+
- If the same issue is raised by multiple agents, merge into one finding
68+
(use the most detailed body).
69+
- Assign a final severity: `bug``major``minor``nit`.
70+
- Prefix the comment body with **`nit:`** if severity is `nit`.
71+
- Verify every `file` path and `line` number against the actual diff before
72+
posting — do not guess.
73+
74+
## Step 4 — Post inline comments via GitHub review API
75+
76+
Build a single JSON payload and post it in **one** API call:
77+
78+
```bash
79+
gh api repos/NethermindEth/pluto/pulls/$PR/reviews \
80+
--method POST \
81+
--input /tmp/review_payload.json \
82+
--jq '{id:.id, state:.state, url:.html_url}'
83+
```
84+
85+
Payload shape:
86+
```json
87+
{
88+
"commit_id": "<head-sha>",
89+
"body": "<overall-assessment — see Step 5>",
90+
"event": "APPROVE | REQUEST_CHANGES | COMMENT",
91+
"comments": [
92+
{
93+
"path": "crates/foo/src/bar.rs",
94+
"line": 42,
95+
"side": "RIGHT",
96+
"body": "comment text"
97+
}
98+
]
99+
}
100+
```
101+
102+
Rules for comments:
103+
- One comment per finding. Do not batch multiple issues into one comment.
104+
- Use `line` + `side: "RIGHT"` for new/modified lines (additions).
105+
- Use `side: "LEFT"` only for deleted lines.
106+
- If `line` is unavailable or ambiguous, omit it — the comment lands at the
107+
file level, which is still useful.
108+
- nit-level findings must start with **`nit:`** in the comment body.
109+
110+
## Step 5 — Overall assessment
111+
112+
Write a 3–5 sentence overall body for the review covering:
113+
1. What the PR does and overall quality signal.
114+
2. A numbered list of **bugs** (must-fix before merge).
115+
3. Summary of major/minor findings.
116+
4. Verdict rationale.
117+
118+
**Verdict rules:**
119+
120+
| Condition | Event |
121+
|---|---|
122+
| Any `bug` severity finding | `REQUEST_CHANGES` |
123+
| Any `major` severity finding | `REQUEST_CHANGES` |
124+
| Only `minor` / `nit` findings | `COMMENT` (leave open for author discretion) |
125+
| No findings or only `nit` | `APPROVE` |
126+
127+
## Output
128+
129+
After the API call succeeds, print:
130+
```
131+
Review posted: <html_url>
132+
Verdict: <APPROVE|REQUEST_CHANGES|COMMENT>
133+
Findings: <N bugs, M major, P minor, Q nits>
134+
```

.claude/skills/rust-style/SKILL.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,25 @@ let x = a.checked_add(b).ok_or(Error::Overflow)?;
6161

6262
## Casts
6363

64-
No lossy or unchecked casts — use fallible conversions:
64+
**Never use `as` for numeric type conversions** — use fallible conversions with `try_from`:
6565

6666
```rust
67-
// Bad
67+
// Bad - will cause clippy errors
6868
let x = value as u32;
69+
let y = some_usize as u64;
6970

70-
// Good
71+
// Good - use try_from with proper error handling
7172
let x = u32::try_from(value)?;
73+
let y = u64::try_from(some_usize).expect("message explaining why this is safe");
7274
```
7375

76+
Rules:
77+
78+
- Always use `TryFrom`/`try_from` for numeric conversions between different types
79+
- Handle conversion failures explicitly (either with `?` or `expect` with justification)
80+
- The only acceptable use of `expect` is when the conversion is guaranteed to succeed (e.g., `usize` to `u64` on 64-bit platforms)
81+
- Clippy will error on unchecked `as` casts: `cast_possible_truncation`, `cast_possible_wrap`, `cast_sign_loss`
82+
7483
---
7584

7685
## Async / Tokio
@@ -158,3 +167,22 @@ mod tests {
158167
```
159168

160169
- For hashing/serialization parity, generate Go-derived test vectors and hardcode them as Rust fixtures.
170+
171+
---
172+
173+
## Pluto-Specific Checklist
174+
175+
Apply when reviewing or porting code:
176+
177+
- [ ] `Ordering::SeqCst` is justified; prefer `Relaxed`/`AcqRel` for
178+
standalone flags.
179+
- [ ] `Error::Io` wraps `std::io::Error` (not `String`) to preserve
180+
`ErrorKind`.
181+
- [ ] New public functions accept `impl AsRef<[u8]>` / `impl AsRef<str>`
182+
rather than concrete slice refs where appropriate.
183+
- [ ] No `unwrap()` / `expect()` / `panic!()` outside test code.
184+
- [ ] All arithmetic uses checked ops (`checked_add`, `checked_mul`, …).
185+
- [ ] Tests mirror the Go test names and shapes where applicable.
186+
- [ ] `use` declarations appear before all other items in each file.
187+
- [ ] No dead payload in error variants (every captured field appears in the
188+
`#[error("...")]` string).

.github/workflows/claude-code-review.yml

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
name: Claude Code Review
22

33
on:
4-
pull_request:
5-
types: [review_requested]
6-
# Optional: Only run on specific file changes
7-
# paths:
8-
# - "src/**/*.ts"
9-
# - "src/**/*.tsx"
10-
# - "src/**/*.js"
11-
# - "src/**/*.jsx"
4+
issue_comment:
5+
types: [created]
126

137
jobs:
148
claude-review:
15-
# Only run when a specific reviewer is requested (e.g., "claude-code" or specific team)
169
if: |
17-
contains(github.event.pull_request.requested_reviewers.*.login, 'claude-code') ||
18-
contains(github.event.pull_request.requested_teams.*.slug, 'claude-code')
10+
github.event.issue.pull_request != null &&
11+
contains(github.event.comment.body, '/claude-review')
1912
2013
runs-on: ubuntu-latest
2114
permissions:
2215
contents: read
23-
pull-requests: read
24-
issues: read
16+
pull-requests: write
17+
issues: write
2518
id-token: write
2619

2720
steps:
@@ -49,9 +42,6 @@ jobs:
4942
uses: anthropics/claude-code-action@v1
5043
with:
5144
anthropic_api_key: ${{ secrets.CLAUDE_CODE_API_KEY }}
45+
github_token: ${{ secrets.GITHUB_TOKEN }}
5246
track_progress: true
53-
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
54-
plugins: 'code-review@claude-code-plugins'
55-
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
56-
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
57-
# or https://code.claude.com/docs/en/cli-reference for available options
47+
prompt: '/review-pr ${{ github.event.pull_request.number || github.event.issue.number }}'

0 commit comments

Comments
 (0)