From 9fc6302176867eeccdd344117f55f8f6d207fea9 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Wed, 15 Apr 2026 12:59:24 +0200 Subject: [PATCH 01/11] docs: add Agents.md for AI coding assistant guidance --- AGENTS.md | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..782ce2491da --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,239 @@ +# CLAUDE.md + +This file provides guidance to AI coding assistants (Claude Code, Cursor, GitHub Copilot, Codex) when working with code in this repository. + +## Project overview + +Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication protocols: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game). + +**Module**: `github.com/ethersphere/bee/v2` +**Go version**: 1.26 (see `go.mod`) +**License**: BSD 3-clause (see `LICENSE`) +**Default branch**: `master` + +## Build and test commands + +```bash +make binary # build dist/bee (CGO_ENABLED=0, version ldflags injected) +make build # compile all packages +make test # unit tests (-failfast) +make test-race # unit tests with race detector +make test-integration # integration tests (requires -tags=integration) +make lint # golangci-lint v2.11.3 (see .golangci.yml) +make vet # go vet +make format # gofumpt + gci +make protobuf # regenerate protobuf files (requires protoc + gogofaster) +make clean # remove dist/ and go clean +make docker-build # build Docker image via Dockerfile.dev +``` + +CI-specific targets (skip tests with names ending in `FLAKY`): +- `make test-ci` / `make test-ci-race` — exclude flaky tests +- `make test-ci-flaky` — run only flaky tests + +Beekeeper integration testing: +- `make beekeeper` — install beekeeper tool +- `make beelocal` — start local k3s cluster +- `make deploylocal` — deploy bee cluster +- `make testlocal` — run integration checks (pingpong, connectivity, pushsync, retrieval, etc.) + +## Architecture + +### Entry point and CLI + +Binary built from `cmd/bee/main.go`. CLI uses Cobra + Viper: +- `bee start` — full or light node (`cmd/bee/cmd/start.go`) +- `bee init` — initialize data directory +- `bee deploy` — deploy smart contracts +- `bee db` — database management +- `bee version` — print version info + +Configuration: option constants defined in `cmd/bee/cmd/cmd.go`. Viper reads from CLI flags, env vars (`BEE_` prefix), and YAML config. + +### Node bootstrap + +`pkg/node/node.go` is the main orchestrator. `NewBee()` wires all subsystems via dependency injection — no global mutable state. The `Bee` struct holds references to every service and provides `Shutdown()` for clean teardown. + +### HTTP API + +- Router: `gorilla/mux` in `pkg/api/router.go` +- Three route groups in `Mount()`: + - `mountTechnicalDebug()` — `/node`, `/addresses`, `/health`, `/readiness`, `/metrics`, `/loggers`, pprof + - `mountBusinessDebug()` — topology, accounting, settlements, stamps management + - `mountAPI()` — `/bytes`, `/chunks`, `/bzz`, `/feeds`, `/soc`, `/stamps`, `/tags`, `/pins`, `/pss`, `/grantee` +- Route gating: `checkRouteAvailability` blocks endpoints during sync +- OpenAPI spec: `openapi/Swarm.yaml` (follows SemVer independently from the bee version) +- Endpoints available at both root (`/bytes`) and versioned (`/v1/bytes`) + +### P2P networking + +- Transport: libp2p (`pkg/p2p/libp2p/`) +- Protocols use protobuf (gogo/protobuf with `--gogofaster_out`) — each protocol package has a `pb/` subdirectory with `.proto` and `doc.go` containing the `go:generate` directive +- Key protocols: + - `pushsync` — push chunks to their neighborhood + - `pullsync` — pull chunks from peers during syncing + - `retrieval` — retrieve chunks by address + - `pingpong` — liveness checking + - `hive` — peer discovery and address broadcasting + - `pricing` — price announcements between peers + +### Storage + +- Chunk types: Content-Addressed Chunks (`pkg/cac/`) and Single Owner Chunks (`pkg/soc/`) +- Core interfaces: `Putter`, `Getter`, `Hasser`, `Deleter` in `pkg/storage/` +- Storer: `pkg/storer/` manages local store (reserve, cache, upload store, pinning) +- Sharky: `pkg/sharky/` — blob storage engine (fixed-size slots) +- BMT: `pkg/bmt/` — Binary Merkle Tree hasher for chunk integrity +- State store: `pkg/statestore/` — LevelDB-backed key-value store +- Shed: `pkg/shed/` — typed LevelDB abstraction layer + +### Postage stamps + +- `pkg/postage/` — batch store, batch service, stamp types +- `pkg/postage/listener/` — listens to on-chain stamp events +- `pkg/postage/postagecontract/` — interacts with the postage stamp smart contract +- Stamps have batch ID, depth (log2 capacity), and amount (per-chunk value) + +### Storage incentives + +- `pkg/storageincentives/` — redistribution game agent +- Nodes in the correct neighborhood prove they store chunks and earn rewards + +## Key domain concepts + +- **Address** — 32-byte hash (`pkg/swarm/`). Used for both chunk and node overlay addresses. Proximity measured by XOR distance. +- **Chunk** — fundamental storage unit. Data is 4096 bytes (`ChunkSize = SectionSize * Branches = 32 * 128`), with an 8-byte span prefix (`SpanSize`), making `ChunkWithSpanSize = 4104`. +- **CAC** — Content Address Chunk. Address = BMT hash of data. +- **SOC** — Single Owner Chunk. Address derived from owner + identifier, signed by the owner. +- **Proximity order (PO)** — number of leading bits two addresses share. `MaxPO = 31`, `ExtendedPO = 36`. +- **Neighborhood** — addresses sharing a common prefix. Determines which chunks a node is responsible for. +- **Kademlia** — XOR-distance routing overlay. Peers organized in bins by PO. +- **Postage stamp** — proof of payment attached to chunks. Batch has depth (capacity) and amount (value per chunk). +- **Push sync** — forwards newly uploaded chunks to their neighborhood. +- **Pull sync** — syncs chunks between peers in overlapping neighborhoods. +- **Redistribution** — storage incentive game: prove storage, earn rewards. + +## Coding conventions + +Refer to `CODING.md` and `CODINGSTYLE.md` for the full rules. Summary of the most important ones: + +### Copyright header (enforced by goheader linter) + +Every `.go` file must start with: +```go +// Copyright The Swarm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +``` + +### Error handling + +- Propagate errors up; never log and return the same error +- Wrap with `fmt.Errorf("context: %w", err)` — produces stack-trace-like messages +- Avoid "failed to" prefixes: `"new store: %w"` not `"failed to create new store: %w"` +- Sentinel errors: `var ErrFoo = errors.New("package: description")` + +### Testing + +- Separate test packages preferred: `package foo_test`, not `package foo` +- Use `export_test.go` (in the real package) to expose internals for tests only +- Run tests in parallel (`t.Parallel()`) where possible +- Compact test names; use godoc for scenario description +- Avoid "fail" in test names (conflicts with test runner output) +- Flaky tests: suffix name with `FLAKY` so CI can separate them +- Integration tests: use `-tags=integration` build tag +- Use `t.Fatal`/`t.FailNow`, not `panic` + +### Concurrency + +- Every goroutine must have a defined termination path +- Channels: size 0 (unbuffered) or 1 — anything else needs justification +- Channels have an owning goroutine; prefer directional types + +### Style + +- American English (marshaling, not marshalling; canceled, not cancelled) +- Avoid `init()` functions +- Start enums at `iota + 1` +- Use `time.Duration` and `time.Time`, not raw integers +- Verify interface compliance: `var _ Interface = (*Impl)(nil)` +- No mutable globals — use dependency injection +- Exit only in `main()` + +### Commit messages + +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format. Allowed types: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test`. Header max 100 chars, footer max 72 chars. Imperative mood. Enforced by commitlint (see `commitlint.config.js`). + +### Logging + +- Levels: `Error`, `Warning`, `Info`, `Debug` (with V-levels) +- `Error`/`Warning` for node operators — no internal implementation details +- `Debug` for developers — include technical details +- Keys: `lower_snake_case`, specific (`peer_address` not `address`) +- Loggers are runtime-configurable via the `/loggers` API endpoint + +## Linting + +golangci-lint v2 with `.golangci.yml`. Notable enabled linters: +- `goheader` — enforces copyright header +- `paralleltest` — detects missing `t.Parallel()` +- `misspell` — catches British spellings +- `errorlint` — ensures proper error wrapping +- `gochecknoinits` — flags `init()` functions +- `prealloc` — suggests pre-allocating slices +- `forbidigo` — restricts `fmt.Print` usage (allowed only in `cmd/bee/cmd/`) +- `govet` with `enable-all: true` (disables `fieldalignment`, `shadow`) + +Run `make lint` to check. Run `make format` to auto-format. + +## Directory structure + +``` +cmd/bee/ CLI entry point and Cobra commands +openapi/ OpenAPI 3.0 specs (Swarm.yaml, SwarmCommon.yaml) +packaging/ system packaging (deb, rpm, homebrew, scoop, docker, systemd) +pkg/ + api/ HTTP API handlers and router + node/ node bootstrap and dependency wiring + swarm/ core types (Address, Chunk, constants) + p2p/ P2P transport (libp2p) + topology/ Kademlia routing table + storage/ storage interfaces + storer/ local store (reserve, cache, upload, pinning) + sharky/ blob storage engine + postage/ postage stamp system + storageincentives/ redistribution game + pushsync/ push sync protocol + pullsync/ pull sync protocol + retrieval/ chunk retrieval protocol + feeds/ mutable feed references + pss/ Postal Service over Swarm + soc/ Single Owner Chunks + cac/ Content Address Chunks + bmt/ Binary Merkle Tree hasher + accesscontrol/ ACT encryption + redundancy/ erasure coding (Reed-Solomon) + replicas/ dispersed replicas + manifest/ trie-based directory structures (Mantaray) + settlement/ payment channels (SWAP chequebook + pseudosettle) + accounting/ per-peer bandwidth accounting + crypto/ signing and key management + keystore/ encrypted key storage + log/ structured logging with V-levels + metrics/ Prometheus metrics + tracing/ OpenTracing / Jaeger + ... ~60 packages total +``` + +## Common pitfalls + +- `ChunkSize` is 4096 bytes (data only). `ChunkWithSpanSize` is 4104 (data + 8-byte span). Don't confuse them. +- Addresses are XOR-distance based — "closer" means more shared prefix bits, not numerically smaller. +- Don't log and return the same error — pick one. Errors propagate up, logging happens at handlers. +- Tests go in `package foo_test`, not `package foo`. Use `export_test.go` for internal access. +- Every goroutine needs a shutdown path — typically via context cancellation or a quit channel. +- Full node vs light node — reserve, storage incentives are only available on full nodes. +- Stamps can be unusable (expired, depleted, unsynced batch). Always check usability. +- The main bee version does NOT follow strict SemVer. The API version in `openapi/Swarm.yaml` does. +- Generated protobuf files (`*.pb.go`) are committed to the repo. Regenerate with `make protobuf`. +- Default branch is `master`, not `main`. From 4b7465035b195880455e4b0cda71acf455ca1d0c Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Wed, 15 Apr 2026 12:59:34 +0200 Subject: [PATCH 02/11] docs: add CLAUDE.md for AI coding assistant guidance --- CLAUDE.md | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..782ce2491da --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,239 @@ +# CLAUDE.md + +This file provides guidance to AI coding assistants (Claude Code, Cursor, GitHub Copilot, Codex) when working with code in this repository. + +## Project overview + +Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication protocols: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game). + +**Module**: `github.com/ethersphere/bee/v2` +**Go version**: 1.26 (see `go.mod`) +**License**: BSD 3-clause (see `LICENSE`) +**Default branch**: `master` + +## Build and test commands + +```bash +make binary # build dist/bee (CGO_ENABLED=0, version ldflags injected) +make build # compile all packages +make test # unit tests (-failfast) +make test-race # unit tests with race detector +make test-integration # integration tests (requires -tags=integration) +make lint # golangci-lint v2.11.3 (see .golangci.yml) +make vet # go vet +make format # gofumpt + gci +make protobuf # regenerate protobuf files (requires protoc + gogofaster) +make clean # remove dist/ and go clean +make docker-build # build Docker image via Dockerfile.dev +``` + +CI-specific targets (skip tests with names ending in `FLAKY`): +- `make test-ci` / `make test-ci-race` — exclude flaky tests +- `make test-ci-flaky` — run only flaky tests + +Beekeeper integration testing: +- `make beekeeper` — install beekeeper tool +- `make beelocal` — start local k3s cluster +- `make deploylocal` — deploy bee cluster +- `make testlocal` — run integration checks (pingpong, connectivity, pushsync, retrieval, etc.) + +## Architecture + +### Entry point and CLI + +Binary built from `cmd/bee/main.go`. CLI uses Cobra + Viper: +- `bee start` — full or light node (`cmd/bee/cmd/start.go`) +- `bee init` — initialize data directory +- `bee deploy` — deploy smart contracts +- `bee db` — database management +- `bee version` — print version info + +Configuration: option constants defined in `cmd/bee/cmd/cmd.go`. Viper reads from CLI flags, env vars (`BEE_` prefix), and YAML config. + +### Node bootstrap + +`pkg/node/node.go` is the main orchestrator. `NewBee()` wires all subsystems via dependency injection — no global mutable state. The `Bee` struct holds references to every service and provides `Shutdown()` for clean teardown. + +### HTTP API + +- Router: `gorilla/mux` in `pkg/api/router.go` +- Three route groups in `Mount()`: + - `mountTechnicalDebug()` — `/node`, `/addresses`, `/health`, `/readiness`, `/metrics`, `/loggers`, pprof + - `mountBusinessDebug()` — topology, accounting, settlements, stamps management + - `mountAPI()` — `/bytes`, `/chunks`, `/bzz`, `/feeds`, `/soc`, `/stamps`, `/tags`, `/pins`, `/pss`, `/grantee` +- Route gating: `checkRouteAvailability` blocks endpoints during sync +- OpenAPI spec: `openapi/Swarm.yaml` (follows SemVer independently from the bee version) +- Endpoints available at both root (`/bytes`) and versioned (`/v1/bytes`) + +### P2P networking + +- Transport: libp2p (`pkg/p2p/libp2p/`) +- Protocols use protobuf (gogo/protobuf with `--gogofaster_out`) — each protocol package has a `pb/` subdirectory with `.proto` and `doc.go` containing the `go:generate` directive +- Key protocols: + - `pushsync` — push chunks to their neighborhood + - `pullsync` — pull chunks from peers during syncing + - `retrieval` — retrieve chunks by address + - `pingpong` — liveness checking + - `hive` — peer discovery and address broadcasting + - `pricing` — price announcements between peers + +### Storage + +- Chunk types: Content-Addressed Chunks (`pkg/cac/`) and Single Owner Chunks (`pkg/soc/`) +- Core interfaces: `Putter`, `Getter`, `Hasser`, `Deleter` in `pkg/storage/` +- Storer: `pkg/storer/` manages local store (reserve, cache, upload store, pinning) +- Sharky: `pkg/sharky/` — blob storage engine (fixed-size slots) +- BMT: `pkg/bmt/` — Binary Merkle Tree hasher for chunk integrity +- State store: `pkg/statestore/` — LevelDB-backed key-value store +- Shed: `pkg/shed/` — typed LevelDB abstraction layer + +### Postage stamps + +- `pkg/postage/` — batch store, batch service, stamp types +- `pkg/postage/listener/` — listens to on-chain stamp events +- `pkg/postage/postagecontract/` — interacts with the postage stamp smart contract +- Stamps have batch ID, depth (log2 capacity), and amount (per-chunk value) + +### Storage incentives + +- `pkg/storageincentives/` — redistribution game agent +- Nodes in the correct neighborhood prove they store chunks and earn rewards + +## Key domain concepts + +- **Address** — 32-byte hash (`pkg/swarm/`). Used for both chunk and node overlay addresses. Proximity measured by XOR distance. +- **Chunk** — fundamental storage unit. Data is 4096 bytes (`ChunkSize = SectionSize * Branches = 32 * 128`), with an 8-byte span prefix (`SpanSize`), making `ChunkWithSpanSize = 4104`. +- **CAC** — Content Address Chunk. Address = BMT hash of data. +- **SOC** — Single Owner Chunk. Address derived from owner + identifier, signed by the owner. +- **Proximity order (PO)** — number of leading bits two addresses share. `MaxPO = 31`, `ExtendedPO = 36`. +- **Neighborhood** — addresses sharing a common prefix. Determines which chunks a node is responsible for. +- **Kademlia** — XOR-distance routing overlay. Peers organized in bins by PO. +- **Postage stamp** — proof of payment attached to chunks. Batch has depth (capacity) and amount (value per chunk). +- **Push sync** — forwards newly uploaded chunks to their neighborhood. +- **Pull sync** — syncs chunks between peers in overlapping neighborhoods. +- **Redistribution** — storage incentive game: prove storage, earn rewards. + +## Coding conventions + +Refer to `CODING.md` and `CODINGSTYLE.md` for the full rules. Summary of the most important ones: + +### Copyright header (enforced by goheader linter) + +Every `.go` file must start with: +```go +// Copyright The Swarm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +``` + +### Error handling + +- Propagate errors up; never log and return the same error +- Wrap with `fmt.Errorf("context: %w", err)` — produces stack-trace-like messages +- Avoid "failed to" prefixes: `"new store: %w"` not `"failed to create new store: %w"` +- Sentinel errors: `var ErrFoo = errors.New("package: description")` + +### Testing + +- Separate test packages preferred: `package foo_test`, not `package foo` +- Use `export_test.go` (in the real package) to expose internals for tests only +- Run tests in parallel (`t.Parallel()`) where possible +- Compact test names; use godoc for scenario description +- Avoid "fail" in test names (conflicts with test runner output) +- Flaky tests: suffix name with `FLAKY` so CI can separate them +- Integration tests: use `-tags=integration` build tag +- Use `t.Fatal`/`t.FailNow`, not `panic` + +### Concurrency + +- Every goroutine must have a defined termination path +- Channels: size 0 (unbuffered) or 1 — anything else needs justification +- Channels have an owning goroutine; prefer directional types + +### Style + +- American English (marshaling, not marshalling; canceled, not cancelled) +- Avoid `init()` functions +- Start enums at `iota + 1` +- Use `time.Duration` and `time.Time`, not raw integers +- Verify interface compliance: `var _ Interface = (*Impl)(nil)` +- No mutable globals — use dependency injection +- Exit only in `main()` + +### Commit messages + +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format. Allowed types: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test`. Header max 100 chars, footer max 72 chars. Imperative mood. Enforced by commitlint (see `commitlint.config.js`). + +### Logging + +- Levels: `Error`, `Warning`, `Info`, `Debug` (with V-levels) +- `Error`/`Warning` for node operators — no internal implementation details +- `Debug` for developers — include technical details +- Keys: `lower_snake_case`, specific (`peer_address` not `address`) +- Loggers are runtime-configurable via the `/loggers` API endpoint + +## Linting + +golangci-lint v2 with `.golangci.yml`. Notable enabled linters: +- `goheader` — enforces copyright header +- `paralleltest` — detects missing `t.Parallel()` +- `misspell` — catches British spellings +- `errorlint` — ensures proper error wrapping +- `gochecknoinits` — flags `init()` functions +- `prealloc` — suggests pre-allocating slices +- `forbidigo` — restricts `fmt.Print` usage (allowed only in `cmd/bee/cmd/`) +- `govet` with `enable-all: true` (disables `fieldalignment`, `shadow`) + +Run `make lint` to check. Run `make format` to auto-format. + +## Directory structure + +``` +cmd/bee/ CLI entry point and Cobra commands +openapi/ OpenAPI 3.0 specs (Swarm.yaml, SwarmCommon.yaml) +packaging/ system packaging (deb, rpm, homebrew, scoop, docker, systemd) +pkg/ + api/ HTTP API handlers and router + node/ node bootstrap and dependency wiring + swarm/ core types (Address, Chunk, constants) + p2p/ P2P transport (libp2p) + topology/ Kademlia routing table + storage/ storage interfaces + storer/ local store (reserve, cache, upload, pinning) + sharky/ blob storage engine + postage/ postage stamp system + storageincentives/ redistribution game + pushsync/ push sync protocol + pullsync/ pull sync protocol + retrieval/ chunk retrieval protocol + feeds/ mutable feed references + pss/ Postal Service over Swarm + soc/ Single Owner Chunks + cac/ Content Address Chunks + bmt/ Binary Merkle Tree hasher + accesscontrol/ ACT encryption + redundancy/ erasure coding (Reed-Solomon) + replicas/ dispersed replicas + manifest/ trie-based directory structures (Mantaray) + settlement/ payment channels (SWAP chequebook + pseudosettle) + accounting/ per-peer bandwidth accounting + crypto/ signing and key management + keystore/ encrypted key storage + log/ structured logging with V-levels + metrics/ Prometheus metrics + tracing/ OpenTracing / Jaeger + ... ~60 packages total +``` + +## Common pitfalls + +- `ChunkSize` is 4096 bytes (data only). `ChunkWithSpanSize` is 4104 (data + 8-byte span). Don't confuse them. +- Addresses are XOR-distance based — "closer" means more shared prefix bits, not numerically smaller. +- Don't log and return the same error — pick one. Errors propagate up, logging happens at handlers. +- Tests go in `package foo_test`, not `package foo`. Use `export_test.go` for internal access. +- Every goroutine needs a shutdown path — typically via context cancellation or a quit channel. +- Full node vs light node — reserve, storage incentives are only available on full nodes. +- Stamps can be unusable (expired, depleted, unsynced batch). Always check usability. +- The main bee version does NOT follow strict SemVer. The API version in `openapi/Swarm.yaml` does. +- Generated protobuf files (`*.pb.go`) are committed to the repo. Regenerate with `make protobuf`. +- Default branch is `master`, not `main`. From b2536ac5d523af034c901f0c5ea666d33b9e35c4 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Wed, 15 Apr 2026 15:25:59 +0200 Subject: [PATCH 03/11] docs: update AGENTS.md and CLAUDE.md --- AGENTS.md | 241 +++++++++++++++++++----------------------------- CLAUDE.md | 268 ++++++++++-------------------------------------------- 2 files changed, 144 insertions(+), 365 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 782ce2491da..16378d701fb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,16 +1,22 @@ -# CLAUDE.md +# AGENTS.md -This file provides guidance to AI coding assistants (Claude Code, Cursor, GitHub Copilot, Codex) when working with code in this repository. +Project instructions for **AI coding assistants and agents** (OpenAI Codex, Cursor, GitHub Copilot, Claude Code, and similar tools). This file is meant to be **self-contained** so any agent that discovers `AGENTS.md` gets enough context without another product-specific file. + +Codex users: see [Custom instructions with AGENTS.md](https://developers.openai.com/codex/guides/agents-md/) for how global and project instructions merge and for the default combined size limit (`project_doc_max_bytes`, often 32 KiB). + +This repo also has **`CLAUDE.md`**, tuned for **Claude Code** (shorter session prompt, `@` imports, `.claude/rules/`). Keep factual content aligned when you change workflows or versions. ## Project overview -Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication protocols: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game). +Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game). -**Module**: `github.com/ethersphere/bee/v2` -**Go version**: 1.26 (see `go.mod`) -**License**: BSD 3-clause (see `LICENSE`) +**Module**: `github.com/ethersphere/bee/v2` +**Go version**: 1.26 (see `go.mod`) +**License**: BSD 3-clause (see `LICENSE`) **Default branch**: `master` +Human-oriented contributing docs: `CONTRIBUTING.md`, `CODING.md`, `CODINGSTYLE.md`, `README.md`. + ## Build and test commands ```bash @@ -27,11 +33,13 @@ make clean # remove dist/ and go clean make docker-build # build Docker image via Dockerfile.dev ``` -CI-specific targets (skip tests with names ending in `FLAKY`): +CI-related targets (tests whose names end in `FLAKY` are handled separately): + - `make test-ci` / `make test-ci-race` — exclude flaky tests - `make test-ci-flaky` — run only flaky tests Beekeeper integration testing: + - `make beekeeper` — install beekeeper tool - `make beelocal` — start local k3s cluster - `make deploylocal` — deploy bee cluster @@ -42,198 +50,141 @@ Beekeeper integration testing: ### Entry point and CLI Binary built from `cmd/bee/main.go`. CLI uses Cobra + Viper: + - `bee start` — full or light node (`cmd/bee/cmd/start.go`) - `bee init` — initialize data directory - `bee deploy` — deploy smart contracts - `bee db` — database management - `bee version` — print version info -Configuration: option constants defined in `cmd/bee/cmd/cmd.go`. Viper reads from CLI flags, env vars (`BEE_` prefix), and YAML config. +Configuration: option constants in `cmd/bee/cmd/cmd.go`. Viper reads CLI flags, environment variables (`BEE_` prefix), and YAML config. ### Node bootstrap -`pkg/node/node.go` is the main orchestrator. `NewBee()` wires all subsystems via dependency injection — no global mutable state. The `Bee` struct holds references to every service and provides `Shutdown()` for clean teardown. +`pkg/node/node.go` is the main orchestrator. `NewBee()` wires subsystems via dependency injection; avoid global mutable state. The `Bee` struct holds service references and provides `Shutdown()` for teardown. ### HTTP API - Router: `gorilla/mux` in `pkg/api/router.go` -- Three route groups in `Mount()`: +- Route groups in `Mount()`: - `mountTechnicalDebug()` — `/node`, `/addresses`, `/health`, `/readiness`, `/metrics`, `/loggers`, pprof - `mountBusinessDebug()` — topology, accounting, settlements, stamps management - `mountAPI()` — `/bytes`, `/chunks`, `/bzz`, `/feeds`, `/soc`, `/stamps`, `/tags`, `/pins`, `/pss`, `/grantee` -- Route gating: `checkRouteAvailability` blocks endpoints during sync -- OpenAPI spec: `openapi/Swarm.yaml` (follows SemVer independently from the bee version) -- Endpoints available at both root (`/bytes`) and versioned (`/v1/bytes`) +- `checkRouteAvailability` can block endpoints during sync +- OpenAPI: `openapi/Swarm.yaml` (API versioning follows SemVer there; the main Bee release version does not) +- Endpoints exist at root (e.g. `/bytes`) and under `/v1/` (e.g. `/v1/bytes`) ### P2P networking - Transport: libp2p (`pkg/p2p/libp2p/`) -- Protocols use protobuf (gogo/protobuf with `--gogofaster_out`) — each protocol package has a `pb/` subdirectory with `.proto` and `doc.go` containing the `go:generate` directive -- Key protocols: - - `pushsync` — push chunks to their neighborhood - - `pullsync` — pull chunks from peers during syncing - - `retrieval` — retrieve chunks by address - - `pingpong` — liveness checking - - `hive` — peer discovery and address broadcasting - - `pricing` — price announcements between peers +- Wire formats: protobuf (gogo) — each protocol area has a `pb/` directory with `.proto` and `doc.go` (`go:generate` calling `protoc` + `--gogofaster_out`) +- Important protocol packages: `pushsync`, `pullsync`, `retrieval`, `pingpong`, `hive`, `pricing` ### Storage -- Chunk types: Content-Addressed Chunks (`pkg/cac/`) and Single Owner Chunks (`pkg/soc/`) -- Core interfaces: `Putter`, `Getter`, `Hasser`, `Deleter` in `pkg/storage/` -- Storer: `pkg/storer/` manages local store (reserve, cache, upload store, pinning) -- Sharky: `pkg/sharky/` — blob storage engine (fixed-size slots) -- BMT: `pkg/bmt/` — Binary Merkle Tree hasher for chunk integrity -- State store: `pkg/statestore/` — LevelDB-backed key-value store -- Shed: `pkg/shed/` — typed LevelDB abstraction layer - -### Postage stamps +- Chunk types: CAC (`pkg/cac/`), SOC (`pkg/soc/`) +- Interfaces: `pkg/storage/` (`Putter`, `Getter`, `Hasser`, `Deleter`) +- Local store: `pkg/storer/` (reserve, cache, upload, pinning) +- Blob engine: `pkg/sharky/` +- BMT: `pkg/bmt/` +- State: `pkg/statestore/` (LevelDB); `pkg/shed/` (typed LevelDB layer) -- `pkg/postage/` — batch store, batch service, stamp types -- `pkg/postage/listener/` — listens to on-chain stamp events -- `pkg/postage/postagecontract/` — interacts with the postage stamp smart contract -- Stamps have batch ID, depth (log2 capacity), and amount (per-chunk value) +### Postage and incentives -### Storage incentives - -- `pkg/storageincentives/` — redistribution game agent -- Nodes in the correct neighborhood prove they store chunks and earn rewards +- `pkg/postage/` — batches, stamps, services +- `pkg/postage/listener/` — on-chain events +- `pkg/postage/postagecontract/` — contract interaction +- Stamps: batch ID, depth (capacity), amount (per-chunk value) +- `pkg/storageincentives/` — redistribution / storage incentive game ## Key domain concepts -- **Address** — 32-byte hash (`pkg/swarm/`). Used for both chunk and node overlay addresses. Proximity measured by XOR distance. -- **Chunk** — fundamental storage unit. Data is 4096 bytes (`ChunkSize = SectionSize * Branches = 32 * 128`), with an 8-byte span prefix (`SpanSize`), making `ChunkWithSpanSize = 4104`. -- **CAC** — Content Address Chunk. Address = BMT hash of data. -- **SOC** — Single Owner Chunk. Address derived from owner + identifier, signed by the owner. -- **Proximity order (PO)** — number of leading bits two addresses share. `MaxPO = 31`, `ExtendedPO = 36`. -- **Neighborhood** — addresses sharing a common prefix. Determines which chunks a node is responsible for. -- **Kademlia** — XOR-distance routing overlay. Peers organized in bins by PO. -- **Postage stamp** — proof of payment attached to chunks. Batch has depth (capacity) and amount (value per chunk). -- **Push sync** — forwards newly uploaded chunks to their neighborhood. -- **Pull sync** — syncs chunks between peers in overlapping neighborhoods. -- **Redistribution** — storage incentive game: prove storage, earn rewards. +- **Address** — 32-byte hash (`pkg/swarm/`). Chunk and overlay addresses; proximity is XOR-based (more shared prefix bits = closer), not numeric ordering. +- **Chunk** — 4096 bytes of data (`ChunkSize = SectionSize * Branches = 32 * 128`), plus 8-byte span (`SpanSize`); `ChunkWithSpanSize = 4104`. +- **CAC** — content-addressed chunk; address from BMT root of data. +- **SOC** — single owner chunk; address from owner + id, with signature. +- **PO** — proximity order (shared prefix bits). `MaxPO = 31`, `ExtendedPO = 36`. +- **Neighborhood** — prefix / responsibility region for storage and sync. +- **Kademlia** — routing table over XOR distance (`pkg/topology/`). +- **Postage stamp** — payment signal attached to chunks. +- **Push sync / pull sync** — push new data toward neighborhood; pull historical sync between peers. +- **Redistribution** — incentive game proving reserve storage. + +## Coding conventions (summary) -## Coding conventions +Authoritative detail: `CODING.md` and `CODINGSTYLE.md`. -Refer to `CODING.md` and `CODINGSTYLE.md` for the full rules. Summary of the most important ones: +### Copyright (goheader) -### Copyright header (enforced by goheader linter) +Every `.go` file starts with: -Every `.go` file must start with: ```go -// Copyright The Swarm Authors. All rights reserved. +// Copyright The Swarm Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. ``` -### Error handling +### Errors, logging, concurrency -- Propagate errors up; never log and return the same error -- Wrap with `fmt.Errorf("context: %w", err)` — produces stack-trace-like messages -- Avoid "failed to" prefixes: `"new store: %w"` not `"failed to create new store: %w"` -- Sentinel errors: `var ErrFoo = errors.New("package: description")` +- Propagate errors; do not log and return the same error. Use `fmt.Errorf("context: %w", err)`. Avoid stacking "failed to" prefixes. +- Sentinel errors: `var ErrFoo = errors.New("package: description")` when appropriate. +- Logging: separate operator-facing (`Error`/`Warning`) from developer detail (`Debug`, V-levels). Keys: `lower_snake_case`, specific names. Runtime log tuning: `/loggers` API. +- Every goroutine needs a clear shutdown path. Channels: prefer unbuffered or size 1 unless strongly justified; an owning goroutine sends or closes. ### Testing -- Separate test packages preferred: `package foo_test`, not `package foo` -- Use `export_test.go` (in the real package) to expose internals for tests only -- Run tests in parallel (`t.Parallel()`) where possible -- Compact test names; use godoc for scenario description -- Avoid "fail" in test names (conflicts with test runner output) -- Flaky tests: suffix name with `FLAKY` so CI can separate them -- Integration tests: use `-tags=integration` build tag -- Use `t.Fatal`/`t.FailNow`, not `panic` - -### Concurrency - -- Every goroutine must have a defined termination path -- Channels: size 0 (unbuffered) or 1 — anything else needs justification -- Channels have an owning goroutine; prefer directional types - -### Style - -- American English (marshaling, not marshalling; canceled, not cancelled) -- Avoid `init()` functions -- Start enums at `iota + 1` -- Use `time.Duration` and `time.Time`, not raw integers -- Verify interface compliance: `var _ Interface = (*Impl)(nil)` -- No mutable globals — use dependency injection -- Exit only in `main()` - -### Commit messages +- Prefer external test packages: `package foo_test` not `package foo`. +- `export_test.go` in the real package to export symbols only for tests. +- Use `t.Parallel()` where safe. Avoid the word `fail` in test names. Suffix `FLAKY` for known-flaky tests. Integration: `-tags=integration`. Prefer `t.Fatal` / `t.FailNow` over `panic` in tests. -[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format. Allowed types: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test`. Header max 100 chars, footer max 72 chars. Imperative mood. Enforced by commitlint (see `commitlint.config.js`). +### Style and tooling -### Logging +- American English (e.g. marshaling, canceled). +- Avoid `init()` where possible (`gochecknoinits`). +- Enums often start at `iota + 1` when zero should mean "unset". +- Use `time.Time` / `time.Duration`, not raw ints for time. +- `var _ Interface = (*Impl)(nil)` where useful. +- Dependency injection over mutable globals. Exit only from `main()`. -- Levels: `Error`, `Warning`, `Info`, `Debug` (with V-levels) -- `Error`/`Warning` for node operators — no internal implementation details -- `Debug` for developers — include technical details -- Keys: `lower_snake_case`, specific (`peer_address` not `address`) -- Loggers are runtime-configurable via the `/loggers` API endpoint +### Commits -## Linting +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Allowed types in this repo: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test` (`commitlint.config.js`). Header max 100 characters; footer lines max 72. Imperative subject. -golangci-lint v2 with `.golangci.yml`. Notable enabled linters: -- `goheader` — enforces copyright header -- `paralleltest` — detects missing `t.Parallel()` -- `misspell` — catches British spellings -- `errorlint` — ensures proper error wrapping -- `gochecknoinits` — flags `init()` functions -- `prealloc` — suggests pre-allocating slices -- `forbidigo` — restricts `fmt.Print` usage (allowed only in `cmd/bee/cmd/`) -- `govet` with `enable-all: true` (disables `fieldalignment`, `shadow`) +### Linting -Run `make lint` to check. Run `make format` to auto-format. +`golangci-lint` v2 per `.golangci.yml`. Notable: `goheader`, `paralleltest`, `misspell`, `errorlint`, `gochecknoinits`, `prealloc`, `forbidigo` (no `fmt.Print` except under `cmd/bee/cmd/`), `govet` with `enable-all` (minus `fieldalignment`, `shadow`). Run `make lint` and `make format`. -## Directory structure +## Directory structure (high level) ``` -cmd/bee/ CLI entry point and Cobra commands -openapi/ OpenAPI 3.0 specs (Swarm.yaml, SwarmCommon.yaml) -packaging/ system packaging (deb, rpm, homebrew, scoop, docker, systemd) +cmd/bee/ CLI and Cobra commands +openapi/ OpenAPI specs (Swarm.yaml, SwarmCommon.yaml) +packaging/ deb, rpm, homebrew, scoop, docker, systemd pkg/ - api/ HTTP API handlers and router - node/ node bootstrap and dependency wiring - swarm/ core types (Address, Chunk, constants) - p2p/ P2P transport (libp2p) - topology/ Kademlia routing table + api/ HTTP API + node/ composition root + swarm/ Address, Chunk, core constants + p2p/ libp2p transport + topology/ Kademlia storage/ storage interfaces - storer/ local store (reserve, cache, upload, pinning) - sharky/ blob storage engine - postage/ postage stamp system - storageincentives/ redistribution game - pushsync/ push sync protocol - pullsync/ pull sync protocol - retrieval/ chunk retrieval protocol - feeds/ mutable feed references - pss/ Postal Service over Swarm - soc/ Single Owner Chunks - cac/ Content Address Chunks - bmt/ Binary Merkle Tree hasher - accesscontrol/ ACT encryption - redundancy/ erasure coding (Reed-Solomon) - replicas/ dispersed replicas - manifest/ trie-based directory structures (Mantaray) - settlement/ payment channels (SWAP chequebook + pseudosettle) - accounting/ per-peer bandwidth accounting - crypto/ signing and key management - keystore/ encrypted key storage - log/ structured logging with V-levels - metrics/ Prometheus metrics - tracing/ OpenTracing / Jaeger + storer/ local storer implementation + sharky/ blob slots + postage/ stamps and batches + storageincentives/ redistribution + pushsync/ pullsync/ retrieval/ pingpong/ hive/ pricing/ # protocols + feeds/ pss/ soc/ cac/ bmt/ manifest/ accesscontrol/ redundancy/ replicas/ + settlement/ accounting/ crypto/ keystore/ log/ metrics/ tracing/ ... ~60 packages total ``` ## Common pitfalls -- `ChunkSize` is 4096 bytes (data only). `ChunkWithSpanSize` is 4104 (data + 8-byte span). Don't confuse them. -- Addresses are XOR-distance based — "closer" means more shared prefix bits, not numerically smaller. -- Don't log and return the same error — pick one. Errors propagate up, logging happens at handlers. -- Tests go in `package foo_test`, not `package foo`. Use `export_test.go` for internal access. -- Every goroutine needs a shutdown path — typically via context cancellation or a quit channel. -- Full node vs light node — reserve, storage incentives are only available on full nodes. -- Stamps can be unusable (expired, depleted, unsynced batch). Always check usability. -- The main bee version does NOT follow strict SemVer. The API version in `openapi/Swarm.yaml` does. -- Generated protobuf files (`*.pb.go`) are committed to the repo. Regenerate with `make protobuf`. -- Default branch is `master`, not `main`. +- Do not confuse `ChunkSize` (4096 data bytes) with `ChunkWithSpanSize` (4104 including span). +- XOR distance: "closer" is more shared prefix bits, not smaller integers. +- Do not both log and return the same error. +- Tests: `foo_test` + `export_test.go` pattern; respect `FLAKY` naming for CI. +- Goroutines must be stoppable (context cancel, quit channel, etc.). +- Full node vs light node: reserve and storage incentives are full-node concerns. +- Postage batches can be unusable (expired, depleted, unsynced); check before relying on stamps. +- `*.pb.go` files are committed; regenerate with `make protobuf` after `.proto` changes. +- Default branch name is `master`, not `main`. diff --git a/CLAUDE.md b/CLAUDE.md index 782ce2491da..e4a36b6a39b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,239 +1,67 @@ # CLAUDE.md -This file provides guidance to AI coding assistants (Claude Code, Cursor, GitHub Copilot, Codex) when working with code in this repository. +Instructions for [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) in this repository. This file is loaded as project context at session start. For the full, tool-neutral project guide (Codex, Cursor, Copilot, etc.), see `AGENTS.md`. -## Project overview +Official reference: [How Claude remembers your project](https://docs.anthropic.com/en/docs/claude-code/claude-md). -Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication protocols: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game). +## Claude Code–specific notes -**Module**: `github.com/ethersphere/bee/v2` -**Go version**: 1.26 (see `go.mod`) -**License**: BSD 3-clause (see `LICENSE`) -**Default branch**: `master` +- Prefer **concise, verifiable** bullets; long prose belongs in repo docs, not here. +- **Personal overrides** (not committed): `CLAUDE.local.md` at repo root (add to `.gitignore` if you create it). +- **Path-scoped rules**: `.claude/rules/` for conventions tied to directories or file patterns. +- **Pull in more context** when needed (imports resolve relative to this file): + - @CODING.md @CODINGSTYLE.md @CONTRIBUTING.md + - @README.md +- Run **`/init`** in Claude Code to refresh or extend this file from the codebase; merge by hand rather than losing team edits. -## Build and test commands +## Project snapshot + +Bee is the reference Go implementation of an Ethereum Swarm node: chunk storage, Kademlia routing, postage, push/pull sync, PSS, feeds, storage incentives. + +| Item | Value | +|------|--------| +| Module | `github.com/ethersphere/bee/v2` | +| Go | 1.26 (`go.mod`) | +| Default branch | `master` | +| License | BSD 3-clause (`LICENSE`) | + +## Commands (verify before shipping) ```bash -make binary # build dist/bee (CGO_ENABLED=0, version ldflags injected) +make binary # dist/bee, CGO_ENABLED=0 + ldflags make build # compile all packages make test # unit tests (-failfast) -make test-race # unit tests with race detector -make test-integration # integration tests (requires -tags=integration) -make lint # golangci-lint v2.11.3 (see .golangci.yml) -make vet # go vet +make test-race # + race detector +make test-integration # -tags=integration +make lint && make vet # golangci-lint v2.11.3 + go vet make format # gofumpt + gci -make protobuf # regenerate protobuf files (requires protoc + gogofaster) -make clean # remove dist/ and go clean -make docker-build # build Docker image via Dockerfile.dev +make protobuf # needs protoc + gogofaster ``` -CI-specific targets (skip tests with names ending in `FLAKY`): -- `make test-ci` / `make test-ci-race` — exclude flaky tests -- `make test-ci-flaky` — run only flaky tests - -Beekeeper integration testing: -- `make beekeeper` — install beekeeper tool -- `make beelocal` — start local k3s cluster -- `make deploylocal` — deploy bee cluster -- `make testlocal` — run integration checks (pingpong, connectivity, pushsync, retrieval, etc.) - -## Architecture - -### Entry point and CLI - -Binary built from `cmd/bee/main.go`. CLI uses Cobra + Viper: -- `bee start` — full or light node (`cmd/bee/cmd/start.go`) -- `bee init` — initialize data directory -- `bee deploy` — deploy smart contracts -- `bee db` — database management -- `bee version` — print version info - -Configuration: option constants defined in `cmd/bee/cmd/cmd.go`. Viper reads from CLI flags, env vars (`BEE_` prefix), and YAML config. - -### Node bootstrap - -`pkg/node/node.go` is the main orchestrator. `NewBee()` wires all subsystems via dependency injection — no global mutable state. The `Bee` struct holds references to every service and provides `Shutdown()` for clean teardown. - -### HTTP API - -- Router: `gorilla/mux` in `pkg/api/router.go` -- Three route groups in `Mount()`: - - `mountTechnicalDebug()` — `/node`, `/addresses`, `/health`, `/readiness`, `/metrics`, `/loggers`, pprof - - `mountBusinessDebug()` — topology, accounting, settlements, stamps management - - `mountAPI()` — `/bytes`, `/chunks`, `/bzz`, `/feeds`, `/soc`, `/stamps`, `/tags`, `/pins`, `/pss`, `/grantee` -- Route gating: `checkRouteAvailability` blocks endpoints during sync -- OpenAPI spec: `openapi/Swarm.yaml` (follows SemVer independently from the bee version) -- Endpoints available at both root (`/bytes`) and versioned (`/v1/bytes`) - -### P2P networking - -- Transport: libp2p (`pkg/p2p/libp2p/`) -- Protocols use protobuf (gogo/protobuf with `--gogofaster_out`) — each protocol package has a `pb/` subdirectory with `.proto` and `doc.go` containing the `go:generate` directive -- Key protocols: - - `pushsync` — push chunks to their neighborhood - - `pullsync` — pull chunks from peers during syncing - - `retrieval` — retrieve chunks by address - - `pingpong` — liveness checking - - `hive` — peer discovery and address broadcasting - - `pricing` — price announcements between peers - -### Storage - -- Chunk types: Content-Addressed Chunks (`pkg/cac/`) and Single Owner Chunks (`pkg/soc/`) -- Core interfaces: `Putter`, `Getter`, `Hasser`, `Deleter` in `pkg/storage/` -- Storer: `pkg/storer/` manages local store (reserve, cache, upload store, pinning) -- Sharky: `pkg/sharky/` — blob storage engine (fixed-size slots) -- BMT: `pkg/bmt/` — Binary Merkle Tree hasher for chunk integrity -- State store: `pkg/statestore/` — LevelDB-backed key-value store -- Shed: `pkg/shed/` — typed LevelDB abstraction layer - -### Postage stamps - -- `pkg/postage/` — batch store, batch service, stamp types -- `pkg/postage/listener/` — listens to on-chain stamp events -- `pkg/postage/postagecontract/` — interacts with the postage stamp smart contract -- Stamps have batch ID, depth (log2 capacity), and amount (per-chunk value) - -### Storage incentives - -- `pkg/storageincentives/` — redistribution game agent -- Nodes in the correct neighborhood prove they store chunks and earn rewards - -## Key domain concepts +CI: `make test-ci` / `make test-ci-race` skip `*FLAKY*` tests; `make test-ci-flaky` runs only those. Beekeeper: `make beekeeper`, `make beelocal`, `make deploylocal`, `make testlocal`. -- **Address** — 32-byte hash (`pkg/swarm/`). Used for both chunk and node overlay addresses. Proximity measured by XOR distance. -- **Chunk** — fundamental storage unit. Data is 4096 bytes (`ChunkSize = SectionSize * Branches = 32 * 128`), with an 8-byte span prefix (`SpanSize`), making `ChunkWithSpanSize = 4104`. -- **CAC** — Content Address Chunk. Address = BMT hash of data. -- **SOC** — Single Owner Chunk. Address derived from owner + identifier, signed by the owner. -- **Proximity order (PO)** — number of leading bits two addresses share. `MaxPO = 31`, `ExtendedPO = 36`. -- **Neighborhood** — addresses sharing a common prefix. Determines which chunks a node is responsible for. -- **Kademlia** — XOR-distance routing overlay. Peers organized in bins by PO. -- **Postage stamp** — proof of payment attached to chunks. Batch has depth (capacity) and amount (value per chunk). -- **Push sync** — forwards newly uploaded chunks to their neighborhood. -- **Pull sync** — syncs chunks between peers in overlapping neighborhoods. -- **Redistribution** — storage incentive game: prove storage, earn rewards. +## Where things live -## Coding conventions +| Area | Location | +|------|-----------| +| CLI | `cmd/bee/` (Cobra + Viper; options in `cmd/bee/cmd/cmd.go`, env `BEE_*`) | +| Bootstrap | `pkg/node/node.go` — `NewBee()`, DI, `Shutdown()` | +| HTTP API | `pkg/api/router.go` — technical debug, business debug, public API; `openapi/Swarm.yaml` | +| P2P | `pkg/p2p/libp2p/`; protobuf per protocol under `*/pb/` (`doc.go` + `go:generate`) | +| Core types | `pkg/swarm/` — `Address`, `Chunk`, `ChunkSize` (4096) + span (8) → `ChunkWithSpanSize` 4104 | +| Store | `pkg/storer/`, `pkg/storage/`, `pkg/sharky/`, `pkg/statestore/`, `pkg/shed/` | +| Chunks | `pkg/cac/`, `pkg/soc/` | +| Postage | `pkg/postage/` (+ `listener/`, `postagecontract/`) | +| Incentives | `pkg/storageincentives/` | -Refer to `CODING.md` and `CODINGSTYLE.md` for the full rules. Summary of the most important ones: +Protocols to remember by name: `pushsync`, `pullsync`, `retrieval`, `pingpong`, `hive`, `pricing`. -### Copyright header (enforced by goheader linter) +## Rules Claude should not forget -Every `.go` file must start with: -```go -// Copyright The Swarm Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -``` - -### Error handling - -- Propagate errors up; never log and return the same error -- Wrap with `fmt.Errorf("context: %w", err)` — produces stack-trace-like messages -- Avoid "failed to" prefixes: `"new store: %w"` not `"failed to create new store: %w"` -- Sentinel errors: `var ErrFoo = errors.New("package: description")` - -### Testing - -- Separate test packages preferred: `package foo_test`, not `package foo` -- Use `export_test.go` (in the real package) to expose internals for tests only -- Run tests in parallel (`t.Parallel()`) where possible -- Compact test names; use godoc for scenario description -- Avoid "fail" in test names (conflicts with test runner output) -- Flaky tests: suffix name with `FLAKY` so CI can separate them -- Integration tests: use `-tags=integration` build tag -- Use `t.Fatal`/`t.FailNow`, not `panic` - -### Concurrency - -- Every goroutine must have a defined termination path -- Channels: size 0 (unbuffered) or 1 — anything else needs justification -- Channels have an owning goroutine; prefer directional types - -### Style - -- American English (marshaling, not marshalling; canceled, not cancelled) -- Avoid `init()` functions -- Start enums at `iota + 1` -- Use `time.Duration` and `time.Time`, not raw integers -- Verify interface compliance: `var _ Interface = (*Impl)(nil)` -- No mutable globals — use dependency injection -- Exit only in `main()` - -### Commit messages - -[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format. Allowed types: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test`. Header max 100 chars, footer max 72 chars. Imperative mood. Enforced by commitlint (see `commitlint.config.js`). - -### Logging - -- Levels: `Error`, `Warning`, `Info`, `Debug` (with V-levels) -- `Error`/`Warning` for node operators — no internal implementation details -- `Debug` for developers — include technical details -- Keys: `lower_snake_case`, specific (`peer_address` not `address`) -- Loggers are runtime-configurable via the `/loggers` API endpoint - -## Linting - -golangci-lint v2 with `.golangci.yml`. Notable enabled linters: -- `goheader` — enforces copyright header -- `paralleltest` — detects missing `t.Parallel()` -- `misspell` — catches British spellings -- `errorlint` — ensures proper error wrapping -- `gochecknoinits` — flags `init()` functions -- `prealloc` — suggests pre-allocating slices -- `forbidigo` — restricts `fmt.Print` usage (allowed only in `cmd/bee/cmd/`) -- `govet` with `enable-all: true` (disables `fieldalignment`, `shadow`) - -Run `make lint` to check. Run `make format` to auto-format. - -## Directory structure - -``` -cmd/bee/ CLI entry point and Cobra commands -openapi/ OpenAPI 3.0 specs (Swarm.yaml, SwarmCommon.yaml) -packaging/ system packaging (deb, rpm, homebrew, scoop, docker, systemd) -pkg/ - api/ HTTP API handlers and router - node/ node bootstrap and dependency wiring - swarm/ core types (Address, Chunk, constants) - p2p/ P2P transport (libp2p) - topology/ Kademlia routing table - storage/ storage interfaces - storer/ local store (reserve, cache, upload, pinning) - sharky/ blob storage engine - postage/ postage stamp system - storageincentives/ redistribution game - pushsync/ push sync protocol - pullsync/ pull sync protocol - retrieval/ chunk retrieval protocol - feeds/ mutable feed references - pss/ Postal Service over Swarm - soc/ Single Owner Chunks - cac/ Content Address Chunks - bmt/ Binary Merkle Tree hasher - accesscontrol/ ACT encryption - redundancy/ erasure coding (Reed-Solomon) - replicas/ dispersed replicas - manifest/ trie-based directory structures (Mantaray) - settlement/ payment channels (SWAP chequebook + pseudosettle) - accounting/ per-peer bandwidth accounting - crypto/ signing and key management - keystore/ encrypted key storage - log/ structured logging with V-levels - metrics/ Prometheus metrics - tracing/ OpenTracing / Jaeger - ... ~60 packages total -``` +- **Errors:** propagate; do not log and return the same error. Wrap with `fmt.Errorf("…: %w", err)`. Skip noisy "failed to" chains. +- **Tests:** prefer `package foo_test`; `export_test.go` for test-only exports; `t.Parallel()` where safe; flaky tests end with `FLAKY`; integration uses `-tags=integration`. +- **Go files:** Swarm copyright header (see `goheader` in `.golangci.yml`). American English. No `init()` unless unavoidable. No `fmt.Print` outside `cmd/bee/cmd/` (forbidigo). +- **Commits:** Conventional Commits; types in `commitlint.config.js`; header ≤100 chars, footer lines ≤72. +- **Product facts:** Bee release version is not strict SemVer; HTTP API version in `openapi/Swarm.yaml` is. XOR proximity, not numeric order. `MaxPO` 31, `ExtendedPO` 36. -## Common pitfalls - -- `ChunkSize` is 4096 bytes (data only). `ChunkWithSpanSize` is 4104 (data + 8-byte span). Don't confuse them. -- Addresses are XOR-distance based — "closer" means more shared prefix bits, not numerically smaller. -- Don't log and return the same error — pick one. Errors propagate up, logging happens at handlers. -- Tests go in `package foo_test`, not `package foo`. Use `export_test.go` for internal access. -- Every goroutine needs a shutdown path — typically via context cancellation or a quit channel. -- Full node vs light node — reserve, storage incentives are only available on full nodes. -- Stamps can be unusable (expired, depleted, unsynced batch). Always check usability. -- The main bee version does NOT follow strict SemVer. The API version in `openapi/Swarm.yaml` does. -- Generated protobuf files (`*.pb.go`) are committed to the repo. Regenerate with `make protobuf`. -- Default branch is `master`, not `main`. +When in doubt, read `AGENTS.md` for the long-form map and pitfalls, or import the coding docs above. From 8fc73ddd424e0de105e3a020fc5c87ed4108b3fa Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Wed, 15 Apr 2026 18:19:24 +0200 Subject: [PATCH 04/11] lint: trigger ci Made-with: Cursor From f47de7050a659a2575dd294c89a8dd70fbc79801 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Thu, 16 Apr 2026 13:17:27 +0200 Subject: [PATCH 05/11] chore: trigger ci From bfa02ac9ae7cd3af3b96e34eb1f34de67126de96 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Thu, 16 Apr 2026 13:31:57 +0200 Subject: [PATCH 06/11] docs: remove flaky related infos --- AGENTS.md | 9 +++------ CLAUDE.md | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 16378d701fb..0b71e6e0c53 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,10 +33,7 @@ make clean # remove dist/ and go clean make docker-build # build Docker image via Dockerfile.dev ``` -CI-related targets (tests whose names end in `FLAKY` are handled separately): - -- `make test-ci` / `make test-ci-race` — exclude flaky tests -- `make test-ci-flaky` — run only flaky tests +CI-oriented targets: `make test-ci` / `make test-ci-race` (see `Makefile` for flags). Beekeeper integration testing: @@ -135,7 +132,7 @@ Every `.go` file starts with: - Prefer external test packages: `package foo_test` not `package foo`. - `export_test.go` in the real package to export symbols only for tests. -- Use `t.Parallel()` where safe. Avoid the word `fail` in test names. Suffix `FLAKY` for known-flaky tests. Integration: `-tags=integration`. Prefer `t.Fatal` / `t.FailNow` over `panic` in tests. +- Use `t.Parallel()` where safe. Avoid the word `fail` in test names. Integration: `-tags=integration`. Prefer `t.Fatal` / `t.FailNow` over `panic` in tests. ### Style and tooling @@ -182,7 +179,7 @@ pkg/ - Do not confuse `ChunkSize` (4096 data bytes) with `ChunkWithSpanSize` (4104 including span). - XOR distance: "closer" is more shared prefix bits, not smaller integers. - Do not both log and return the same error. -- Tests: `foo_test` + `export_test.go` pattern; respect `FLAKY` naming for CI. +- Tests: `foo_test` + `export_test.go` pattern. - Goroutines must be stoppable (context cancel, quit channel, etc.). - Full node vs light node: reserve and storage incentives are full-node concerns. - Postage batches can be unusable (expired, depleted, unsynced); check before relying on stamps. diff --git a/CLAUDE.md b/CLAUDE.md index e4a36b6a39b..146621dc50b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -38,7 +38,7 @@ make format # gofumpt + gci make protobuf # needs protoc + gogofaster ``` -CI: `make test-ci` / `make test-ci-race` skip `*FLAKY*` tests; `make test-ci-flaky` runs only those. Beekeeper: `make beekeeper`, `make beelocal`, `make deploylocal`, `make testlocal`. +CI: `make test-ci` / `make test-ci-race` (see `Makefile`). Beekeeper: `make beekeeper`, `make beelocal`, `make deploylocal`, `make testlocal`. ## Where things live @@ -59,7 +59,7 @@ Protocols to remember by name: `pushsync`, `pullsync`, `retrieval`, `pingpong`, ## Rules Claude should not forget - **Errors:** propagate; do not log and return the same error. Wrap with `fmt.Errorf("…: %w", err)`. Skip noisy "failed to" chains. -- **Tests:** prefer `package foo_test`; `export_test.go` for test-only exports; `t.Parallel()` where safe; flaky tests end with `FLAKY`; integration uses `-tags=integration`. +- **Tests:** prefer `package foo_test`; `export_test.go` for test-only exports; `t.Parallel()` where safe; integration uses `-tags=integration`. - **Go files:** Swarm copyright header (see `goheader` in `.golangci.yml`). American English. No `init()` unless unavoidable. No `fmt.Print` outside `cmd/bee/cmd/` (forbidigo). - **Commits:** Conventional Commits; types in `commitlint.config.js`; header ≤100 chars, footer lines ≤72. - **Product facts:** Bee release version is not strict SemVer; HTTP API version in `openapi/Swarm.yaml` is. XOR proximity, not numeric order. `MaxPO` 31, `ExtendedPO` 36. From 8e17f24b9e525a33372be06e9f8bf385e33488cf Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Thu, 16 Apr 2026 14:32:46 +0200 Subject: [PATCH 07/11] docs: remove CLAUDE.md --- CLAUDE.md | 67 ------------------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 146621dc50b..00000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,67 +0,0 @@ -# CLAUDE.md - -Instructions for [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) in this repository. This file is loaded as project context at session start. For the full, tool-neutral project guide (Codex, Cursor, Copilot, etc.), see `AGENTS.md`. - -Official reference: [How Claude remembers your project](https://docs.anthropic.com/en/docs/claude-code/claude-md). - -## Claude Code–specific notes - -- Prefer **concise, verifiable** bullets; long prose belongs in repo docs, not here. -- **Personal overrides** (not committed): `CLAUDE.local.md` at repo root (add to `.gitignore` if you create it). -- **Path-scoped rules**: `.claude/rules/` for conventions tied to directories or file patterns. -- **Pull in more context** when needed (imports resolve relative to this file): - - @CODING.md @CODINGSTYLE.md @CONTRIBUTING.md - - @README.md -- Run **`/init`** in Claude Code to refresh or extend this file from the codebase; merge by hand rather than losing team edits. - -## Project snapshot - -Bee is the reference Go implementation of an Ethereum Swarm node: chunk storage, Kademlia routing, postage, push/pull sync, PSS, feeds, storage incentives. - -| Item | Value | -|------|--------| -| Module | `github.com/ethersphere/bee/v2` | -| Go | 1.26 (`go.mod`) | -| Default branch | `master` | -| License | BSD 3-clause (`LICENSE`) | - -## Commands (verify before shipping) - -```bash -make binary # dist/bee, CGO_ENABLED=0 + ldflags -make build # compile all packages -make test # unit tests (-failfast) -make test-race # + race detector -make test-integration # -tags=integration -make lint && make vet # golangci-lint v2.11.3 + go vet -make format # gofumpt + gci -make protobuf # needs protoc + gogofaster -``` - -CI: `make test-ci` / `make test-ci-race` (see `Makefile`). Beekeeper: `make beekeeper`, `make beelocal`, `make deploylocal`, `make testlocal`. - -## Where things live - -| Area | Location | -|------|-----------| -| CLI | `cmd/bee/` (Cobra + Viper; options in `cmd/bee/cmd/cmd.go`, env `BEE_*`) | -| Bootstrap | `pkg/node/node.go` — `NewBee()`, DI, `Shutdown()` | -| HTTP API | `pkg/api/router.go` — technical debug, business debug, public API; `openapi/Swarm.yaml` | -| P2P | `pkg/p2p/libp2p/`; protobuf per protocol under `*/pb/` (`doc.go` + `go:generate`) | -| Core types | `pkg/swarm/` — `Address`, `Chunk`, `ChunkSize` (4096) + span (8) → `ChunkWithSpanSize` 4104 | -| Store | `pkg/storer/`, `pkg/storage/`, `pkg/sharky/`, `pkg/statestore/`, `pkg/shed/` | -| Chunks | `pkg/cac/`, `pkg/soc/` | -| Postage | `pkg/postage/` (+ `listener/`, `postagecontract/`) | -| Incentives | `pkg/storageincentives/` | - -Protocols to remember by name: `pushsync`, `pullsync`, `retrieval`, `pingpong`, `hive`, `pricing`. - -## Rules Claude should not forget - -- **Errors:** propagate; do not log and return the same error. Wrap with `fmt.Errorf("…: %w", err)`. Skip noisy "failed to" chains. -- **Tests:** prefer `package foo_test`; `export_test.go` for test-only exports; `t.Parallel()` where safe; integration uses `-tags=integration`. -- **Go files:** Swarm copyright header (see `goheader` in `.golangci.yml`). American English. No `init()` unless unavoidable. No `fmt.Print` outside `cmd/bee/cmd/` (forbidigo). -- **Commits:** Conventional Commits; types in `commitlint.config.js`; header ≤100 chars, footer lines ≤72. -- **Product facts:** Bee release version is not strict SemVer; HTTP API version in `openapi/Swarm.yaml` is. XOR proximity, not numeric order. `MaxPO` 31, `ExtendedPO` 36. - -When in doubt, read `AGENTS.md` for the long-form map and pitfalls, or import the coding docs above. From 9a3590db8e98d1f9c7c0241593c98bb4be9d6dc5 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Thu, 16 Apr 2026 14:36:44 +0200 Subject: [PATCH 08/11] docs: enhance AGENTS.md with contribution guidelines and pre-commit checklist --- AGENTS.md | 63 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 0b71e6e0c53..924a58d706f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,30 +17,55 @@ Bee is the reference Go implementation of an Ethereum Swarm node. It implements Human-oriented contributing docs: `CONTRIBUTING.md`, `CODING.md`, `CODINGSTYLE.md`, `README.md`. -## Build and test commands +## Guidelines + +Keep changes **minimal and focused**. Only touch code that belongs to the task. Do not refactor unrelated code, rename symbols for style only, or mix unrelated fixes in one commit or PR. + +Read **`CONTRIBUTING.md`**, **`CODING.md`**, and **`CODINGSTYLE.md`** for process, patterns, and style. Prefer matching existing naming, types, imports, and log style in the files you edit. + +Do **not** add, remove, or update `go.mod` dependencies unless the task **explicitly** requires it or the person asking for the work **explicitly** requests a dependency change. + +Handle errors and logging the way this repo does: propagate errors with context (`fmt.Errorf("…: %w", err)`), avoid logging and returning the same error, and use structured logging with clear operator vs developer levels (see `CODING.md`). + +Prefer **`package foo_test`** tests, **`export_test.go`** when you must export internals, and **`t.Parallel()`** only where it is safe. Add or update tests when behavior changes. Integration tests use **`-tags=integration`**. + +## Pre-commit checklist + +Before you finish a change set (especially before a commit or PR), run these and fix failures: + +1. **Formatting** — `make format` (gofumpt + gci; see `CODING.md`). +2. **Compile** — `make build` (all packages) and, when you need the binary artifact, `make binary` (`dist/bee`, `CGO_ENABLED=0`). +3. **Tests** — `make test` (unit tests, `-failfast`). Use `make test-race` when concurrency is central to the change. Use `make test-integration` only when you touch integration-tagged code. +4. **Static checks** — `make lint` and `make vet` (see `.golangci.yml`). + +CI pipelines may use `make test-ci` / `make test-ci-race` (see `Makefile` for flags). + +## Dev commands (quick reference) ```bash -make binary # build dist/bee (CGO_ENABLED=0, version ldflags injected) -make build # compile all packages -make test # unit tests (-failfast) -make test-race # unit tests with race detector -make test-integration # integration tests (requires -tags=integration) -make lint # golangci-lint v2.11.3 (see .golangci.yml) -make vet # go vet -make format # gofumpt + gci -make protobuf # regenerate protobuf files (requires protoc + gogofaster) -make clean # remove dist/ and go clean -make docker-build # build Docker image via Dockerfile.dev +make binary # dist/bee +make build # compile all packages +make test # unit tests +make test-race # unit tests + race detector +make lint # golangci-lint (see .golangci.yml) +make vet # go vet ``` -CI-oriented targets: `make test-ci` / `make test-ci-race` (see `Makefile` for flags). +## Commit message format and PR titles + +This repo uses **[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)** with **`commitlint.config.js`**: allowed types are `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test`. Header **max 100** characters; footer lines **max 72**. Use **imperative** mood and **no trailing period** on the subject. -Beekeeper integration testing: +Use an optional **scope** (often a top-level area such as `api`, `storer`, `node`) when it clarifies impact: + +```text +(): + +fix(api): reject directory upload without content-type +test(storer): cover session cleanup on error +docs: clarify agent pre-commit steps +``` -- `make beekeeper` — install beekeeper tool -- `make beelocal` — start local k3s cluster -- `make deploylocal` — deploy bee cluster -- `make testlocal` — run integration checks (pingpong, connectivity, pushsync, retrieval, etc.) +**Pull request titles** follow the same idea: same type and scope style, concise lowercase description (match what you will squash or merge). ## Architecture @@ -145,7 +170,7 @@ Every `.go` file starts with: ### Commits -[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). Allowed types in this repo: `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `test` (`commitlint.config.js`). Header max 100 characters; footer lines max 72. Imperative subject. +See **[Commit message format and PR titles](#commit-message-format-and-pr-titles)** above. ### Linting From 9dbbd0369405f7b1f13da940109c25c492e2f1e1 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Fri, 1 May 2026 17:37:10 +0200 Subject: [PATCH 09/11] docs: update AGENTS.md to streamline instructions and clarify testing guidelines --- AGENTS.md | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 924a58d706f..7e4317596a5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,10 +2,6 @@ Project instructions for **AI coding assistants and agents** (OpenAI Codex, Cursor, GitHub Copilot, Claude Code, and similar tools). This file is meant to be **self-contained** so any agent that discovers `AGENTS.md` gets enough context without another product-specific file. -Codex users: see [Custom instructions with AGENTS.md](https://developers.openai.com/codex/guides/agents-md/) for how global and project instructions merge and for the default combined size limit (`project_doc_max_bytes`, often 32 KiB). - -This repo also has **`CLAUDE.md`**, tuned for **Claude Code** (shorter session prompt, `@` imports, `.claude/rules/`). Keep factual content aligned when you change workflows or versions. - ## Project overview Bee is the reference Go implementation of an Ethereum Swarm node. It implements decentralized storage and communication: content-addressed chunk storage, Kademlia-based routing, postage stamp accounting, push/pull syncing, PSS messaging, feeds, and storage incentives (redistribution game). @@ -35,7 +31,7 @@ Before you finish a change set (especially before a commit or PR), run these and 1. **Formatting** — `make format` (gofumpt + gci; see `CODING.md`). 2. **Compile** — `make build` (all packages) and, when you need the binary artifact, `make binary` (`dist/bee`, `CGO_ENABLED=0`). -3. **Tests** — `make test` (unit tests, `-failfast`). Use `make test-race` when concurrency is central to the change. Use `make test-integration` only when you touch integration-tagged code. +3. **Tests** — `make test` (unit tests, `-failfast`). For a single package use `go test ./pkg//...`. Use `make test-race` when concurrency is central to the change. Use `make test-integration` only when you touch integration-tagged code. 4. **Static checks** — `make lint` and `make vet` (see `.golangci.yml`). CI pipelines may use `make test-ci` / `make test-ci-race` (see `Makefile` for flags). @@ -174,30 +170,7 @@ See **[Commit message format and PR titles](#commit-message-format-and-pr-titles ### Linting -`golangci-lint` v2 per `.golangci.yml`. Notable: `goheader`, `paralleltest`, `misspell`, `errorlint`, `gochecknoinits`, `prealloc`, `forbidigo` (no `fmt.Print` except under `cmd/bee/cmd/`), `govet` with `enable-all` (minus `fieldalignment`, `shadow`). Run `make lint` and `make format`. - -## Directory structure (high level) - -``` -cmd/bee/ CLI and Cobra commands -openapi/ OpenAPI specs (Swarm.yaml, SwarmCommon.yaml) -packaging/ deb, rpm, homebrew, scoop, docker, systemd -pkg/ - api/ HTTP API - node/ composition root - swarm/ Address, Chunk, core constants - p2p/ libp2p transport - topology/ Kademlia - storage/ storage interfaces - storer/ local storer implementation - sharky/ blob slots - postage/ stamps and batches - storageincentives/ redistribution - pushsync/ pullsync/ retrieval/ pingpong/ hive/ pricing/ # protocols - feeds/ pss/ soc/ cac/ bmt/ manifest/ accesscontrol/ redundancy/ replicas/ - settlement/ accounting/ crypto/ keystore/ log/ metrics/ tracing/ - ... ~60 packages total -``` +`golangci-lint` v2 per `.golangci.yml`. Run `make lint`. ## Common pitfalls @@ -208,5 +181,5 @@ pkg/ - Goroutines must be stoppable (context cancel, quit channel, etc.). - Full node vs light node: reserve and storage incentives are full-node concerns. - Postage batches can be unusable (expired, depleted, unsynced); check before relying on stamps. -- `*.pb.go` files are committed; regenerate with `make protobuf` after `.proto` changes. +- `*.pb.go` is generated; do not edit by hand. Regenerate with `make protobuf` after `.proto` changes. - Default branch name is `master`, not `main`. From ae3a40de7fe911119d9a0c1b8895d14f67ff1db8 Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Fri, 1 May 2026 17:39:15 +0200 Subject: [PATCH 10/11] docs: create CLAUDE.md with initial code notes and reference to AGENTS.md --- CLAUDE.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..4d47058ee77 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +# CLAUDE.md + +@AGENTS.md + +## claude code notes + +- `AGENTS.md` is the shared source of truth for project instructions. From f65949be5f1b40b3634502df26d091a599eaffca Mon Sep 17 00:00:00 2001 From: akrem-chabchoub Date: Fri, 1 May 2026 17:41:12 +0200 Subject: [PATCH 11/11] docs: update AGENTS.md and CLAUDE.md --- AGENTS.md | 2 +- CLAUDE.md | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7e4317596a5..5834ec6ae25 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md -Project instructions for **AI coding assistants and agents** (OpenAI Codex, Cursor, GitHub Copilot, Claude Code, and similar tools). This file is meant to be **self-contained** so any agent that discovers `AGENTS.md` gets enough context without another product-specific file. +Project instructions for **AI coding assistants and agents** (OpenAI Codex, Cursor, GitHub Copilot, Claude Code, and similar tools). This file is the canonical source of shared project instructions; `CLAUDE.md` imports this file for Claude Code. ## Project overview diff --git a/CLAUDE.md b/CLAUDE.md index 4d47058ee77..43c994c2d36 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,7 +1 @@ -# CLAUDE.md - @AGENTS.md - -## claude code notes - -- `AGENTS.md` is the shared source of truth for project instructions.