Skip to content

Commit 408f8f3

Browse files
authored
feat: various improvement for claude configuration (#297)
* feat: decompose claude md into skills * feat: add charon folder hook * fix: review comments * feat: add codex skills * fix: review comments * fix: check charon hook
1 parent feacf24 commit 408f8f3

File tree

11 files changed

+614
-216
lines changed

11 files changed

+614
-216
lines changed

.agents/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../.claude/skills
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# SessionStart hook to check for Charon folder existence
5+
# This reduces token usage by checking once at session start instead of repeatedly
6+
7+
# Read input (required for hook protocol, even if unused)
8+
input=$(cat)
9+
10+
# Get the project directory
11+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
12+
13+
# Check for Charon folder in common locations
14+
CHARON_PATHS=(
15+
"charon"
16+
"../charon"
17+
"../../charon"
18+
)
19+
20+
FOUND_PATH=""
21+
for path in "${CHARON_PATHS[@]}"; do
22+
if [ -d "$path" ]; then
23+
FOUND_PATH=$(eval echo "$(pwd)/$path")
24+
break
25+
fi
26+
done
27+
28+
# Build additional context
29+
if [ -n "$FOUND_PATH" ]; then
30+
# Charon folder found - add it to context
31+
MESSAGE="Charon Go source available at: $FOUND_PATH. Use this path to reference charon codebase when requested. Do not try to recheck this path. This path is static and will not change."
32+
else
33+
# Charon folder not found - provide guidance
34+
MESSAGE="Charon Go source not found. Clone from https://github.com/ObolNetwork/charon.git to enable reference during porting."
35+
fi
36+
37+
# Output JSON with additional context for Claude
38+
jq -n \
39+
--arg msg "$MESSAGE" \
40+
'{
41+
"hookSpecificOutput":{
42+
"hookEventName": "SessionStart",
43+
"additionalContext": $msg,
44+
}
45+
}'
46+
47+
exit 0

.claude/hooks/check-formatting.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Read hook input (though we don't need it for this check)
5+
input=$(cat)
6+
7+
# Check if we're in the project root
8+
if [ ! -f "Cargo.toml" ]; then
9+
echo '{"continue": true, "systemMessage": "Not in Cargo workspace root, skipping format check"}'
10+
exit 0
11+
fi
12+
13+
# Run cargo +nightly fmt --all --check
14+
if cargo +nightly fmt --all --check 2>&1; then
15+
# Formatting is correct
16+
echo '{"continue": true, "systemMessage": "✓ Code formatting verified with cargo +nightly fmt"}'
17+
exit 0
18+
else
19+
# Auto-fix formatting
20+
cargo +nightly fmt --all 2>&1
21+
22+
echo '{"continue": true, "systemMessage": "✓ Formatting applied with cargo +nightly fmt --all."}'
23+
exit 0
24+
fi

.claude/settings.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"hooks": {
3+
"SessionStart": [
4+
{
5+
"matcher": "*",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "bash .claude/hooks/check-charon-folder.sh",
10+
"timeout": 10
11+
}
12+
]
13+
}
14+
],
15+
"Stop": [
16+
{
17+
"matcher": "*",
18+
"hooks": [
19+
{
20+
"type": "command",
21+
"command": "bash .claude/hooks/check-formatting.sh",
22+
"timeout": 60
23+
}
24+
]
25+
}
26+
]
27+
}
28+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
---
2+
name: charon-guide
3+
description: Use when porting Charon components to understand Go codebase architecture, workflow, design patterns, or component responsibilities
4+
---
5+
6+
# Charon Architecture Guide
7+
8+
Reference for understanding the Charon Go codebase when porting to Pluto (Rust).
9+
10+
## What is Charon?
11+
12+
Distributed validator middleware for Ethereum staking. Enables running a single validator across multiple independent nodes using threshold BLS signatures. Each validator duty flows through a multi-stage workflow with consensus and signature aggregation.
13+
14+
## Knowledge Base
15+
16+
When you need deeper understanding:
17+
18+
| Topic | Location |
19+
|-------|----------|
20+
| High-level overview | `charon/README.md` |
21+
| Detailed architecture | `charon/docs/architecture.md` |
22+
| Go coding guidelines | `charon/docs/goguidelines.md` |
23+
| Configuration options | `charon/docs/configuration.md` |
24+
| DKG details | `charon/docs/dkg.md` |
25+
| Consensus (QBFT) | `charon/docs/consensus.md`, `charon/core/qbft/README.md` |
26+
| Metrics | `charon/docs/metrics.md` |
27+
| Error reason codes | `charon/docs/reasons.md` |
28+
| Package structure | `charon/docs/structure.md` |
29+
| Product docs | https://docs.obol.org/next |
30+
31+
## Core Workflow
32+
33+
Every validator duty (attestation, block proposal, etc.) flows through these components in order:
34+
35+
```
36+
Scheduler → Fetcher → Consensus → DutyDB → ValidatorAPI → ParSigDB → ParSigEx → SigAgg → AggSigDB → Bcast
37+
```
38+
39+
| Component | Responsibility | Go Package |
40+
|-----------|---------------|------------|
41+
| **Scheduler** | Triggers duties at optimal times based on beacon chain state | `core/scheduler/` |
42+
| **Fetcher** | Fetches unsigned duty data from beacon node | `core/fetcher/` |
43+
| **Consensus** | QBFT consensus to agree on duty data across all nodes | `core/consensus/`, `core/qbft/` |
44+
| **DutyDB** | Persists unsigned data, slashing protection | `core/dutydb/` |
45+
| **ValidatorAPI** | Serves data to validator clients, receives partial signatures | `core/validatorapi/` |
46+
| **ParSigDB** | Stores partial threshold BLS signatures from local/remote VCs | `core/parsigdb/` |
47+
| **ParSigEx** | Exchanges partial signatures with peers via p2p | `core/parsigex/` |
48+
| **SigAgg** | Aggregates partial signatures when threshold reached | `core/sigagg/` |
49+
| **AggSigDB** | Persists aggregated signatures | `core/aggsigdb/` |
50+
| **Bcast** | Broadcasts final signatures to beacon node | `core/bcast/` |
51+
52+
**Porting note:** When porting a component, trace its inputs and outputs through this pipeline.
53+
54+
## Key Abstractions
55+
56+
| Concept | Definition | Go Type |
57+
|---------|------------|---------|
58+
| **Duty** | Unit of work (slot + duty type). Cluster-level, not per-validator. | `core.Duty` |
59+
| **PubKey** | DV root public key, validator identifier in workflow | `core.PubKey` |
60+
| **UnsignedData** | Abstract type for attestation data, blocks, etc. | `core.UnsignedData` (interface) |
61+
| **SignedData** | Fully signed duty data | `core.SignedData` (interface) |
62+
| **ParSignedData** | Partially signed data from single threshold BLS share | `core.ParSignedData` (struct) |
63+
64+
**Type encoding:** Abstract types are encoded/decoded via `core/encode.go`. Always check this file when porting type serialization.
65+
66+
## Design Patterns
67+
68+
| Pattern | Description | Porting Impact |
69+
|---------|-------------|----------------|
70+
| **Immutable values** | Components consume and produce immutable values (actor-like) | Always `.Clone()` before sharing/caching in Rust |
71+
| **Callback subscriptions** | Components decoupled via subscriptions, not direct calls | Use channels or callbacks in Rust |
72+
| **Type-safe encoding** | Abstract types use custom encoding/decoding | Port `core/encode.go` logic carefully |
73+
74+
## Consensus (QBFT)
75+
76+
Charon uses **QBFT** (Istanbul BFT) for consensus. Each duty requires consensus to ensure all nodes sign identical data (required for BLS threshold signatures and slashing protection).
77+
78+
**Key files:**
79+
- `core/qbft/` - QBFT implementation
80+
- `core/consensus/` - Consensus component integration
81+
- `charon/docs/consensus.md` - Design documentation
82+
83+
**Porting note:** QBFT is complex. Port incrementally and verify against Go test vectors.
84+
85+
## Package Structure
86+
87+
| Go Package | Purpose | Rust Equivalent |
88+
|------------|---------|-----------------|
89+
| `app/` | Application entrypoint, wiring, infrastructure (log, errors, tracer, lifecycle) | `pluto/crates/app/` |
90+
| `cluster/` | Cluster config, lock files, DKG artifacts | `pluto/crates/cluster/` |
91+
| `cmd/` | CLI commands (run, dkg, create, test, etc.) | `pluto/crates/cli/` |
92+
| `core/` | Core workflow business logic and components | `pluto/crates/core/` |
93+
| `dkg/` | Distributed Key Generation logic | `pluto/crates/dkg/` |
94+
| `eth2util/` | ETH2 utilities (signing, deposits, keystores) | `pluto/crates/eth2util/` |
95+
| `p2p/` | libp2p networking and discv5 peer discovery | `pluto/crates/p2p/` |
96+
| `tbls/` | Threshold BLS signature scheme | `pluto/crates/crypto/` |
97+
| `testutil/` | Test utilities, mocks, golden files | `pluto/crates/testutil/` |
98+
99+
## Common Porting Scenarios
100+
101+
### Porting a Workflow Component
102+
103+
1. Read `charon/docs/architecture.md` for component interfaces
104+
2. Identify inputs (what triggers this component?)
105+
3. Identify outputs (what does it produce? who consumes it?)
106+
4. Check `core/<component>/` for implementation
107+
5. Check subscriptions in `app/app.go` (wiring/stitching logic)
108+
6. Port logic, preserving immutability and callback patterns
109+
110+
### Adding New Duty Types
111+
112+
When porting code that adds duty types:
113+
114+
1. Add to `core/types.go` (duty type constants)
115+
2. Add to `core/encode.go` (encoding/decoding logic)
116+
3. Update Scheduler, Fetcher, and relevant components
117+
118+
### Understanding Error Handling
119+
120+
Go style:
121+
- Just return errors, don't log and return
122+
- Wrap external errors: `errors.Wrap(err, "do something")`
123+
- Use `app/errors` for structured errors with fields
124+
125+
Rust style: See `rust-style` skill and AGENTS.md.
126+
127+
### Working with Cluster Lock Files
128+
129+
- `cluster-definition.json`: Intended cluster config (operators, validators)
130+
- `cluster-lock.json`: Extends definition with DV public keys and shares (DKG output)
131+
- See `cluster/` package for parsing/validation
132+
133+
## Dependency Notes
134+
135+
Charon uses forked dependencies:
136+
- `github.com/ObolNetwork/kryptology` (security fixes)
137+
- `github.com/ObolNetwork/go-eth2-client` (kept up to date)
138+
139+
When porting code using these, check if Rust equivalents exist or if porting is needed.
140+
141+
## Version Compatibility
142+
143+
Important for protocol compatibility:
144+
145+
- **Compatible:** Same MAJOR version, different MINOR/PATCH
146+
- **Incompatible:** Different MAJOR version
147+
- **DKG:** Requires matching MAJOR and MINOR versions (PATCH can differ)
148+
149+
## Quick Reference Commands
150+
151+
When exploring Charon codebase:
152+
153+
```bash
154+
# Find a function
155+
grep -r "func FunctionName" charon/
156+
157+
# See package structure
158+
ls -la charon/<directory>/
159+
160+
# Check imports
161+
grep "^import" charon/path/to/file.go
162+
163+
# Run specific Go test (to understand behavior)
164+
cd charon && go test -run TestFunctionName ./path/to/package
165+
```
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
name: pluto-review
3+
description: Pluto-specific code review guidelines. Use as a general guideline when asked to conduct a code review.
4+
---
5+
6+
Principles:
7+
8+
- Functional equivalence first; document and justify deviations.
9+
- Evidence-based: prefer tests, outputs, and file/line references over guesses.
10+
- Minimal change bias; avoid scope creep.
11+
- No time estimates in review output.
12+
13+
When producing a review, include:
14+
15+
1. Summary (1–3 sentences)
16+
2. Findings (ordered by severity)
17+
3. Parity matrix (if applicable)
18+
4. Tests (run or not run)
19+
5. Open questions/assumptions
20+
21+
Severity model:
22+
23+
- Critical: breaks contract, security issue, incompatible output/protocol.
24+
- High: user-visible regression or parity gap with operational impact.
25+
- Medium: behavioral difference with limited impact or edge cases.
26+
- Low: minor inconsistency or optional improvement.
27+
28+
Findings format (use `path:line` references, 1-based):
29+
30+
```text
31+
- [Severity] Title
32+
Impact: ...
33+
Evidence: pluto/crates/foo/src/lib.rs:123
34+
Go reference: charon/cmd/foo.go:456
35+
Recommendation: ...
36+
```
37+
38+
Parity matrix template:
39+
40+
| Component | Go | Rust | Match | Notes |
41+
| --- | --- | --- | --- | --- |
42+
| CLI flag --foo | present | present | yes | |
43+
| Error string for missing key | "..." | "..." | no | mismatch in punctuation |
44+
| Wire format | pbio | pbio | yes | |

0 commit comments

Comments
 (0)