This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This guide provides comprehensive instructions for AI agents working on the Heimdall codebase. It covers the architecture, development workflows, and critical guidelines for effective contributions.
Heimdall is the consensus client of Polygon PoS, built on Cosmos SDK and CometBFT. It manages validator selection, checkpointing to Ethereum L1, and span/sprint coordination. Bor is the separate execution client that handles block production and transaction execution. Together they form the complete Polygon PoS stack.
Heimdall focuses on BFT consensus, cross-chain communication, and validator management.
- Checkpoint (
x/checkpoint/): Multi-stage L1 checkpoint submission with vote extension verification - Stake (
x/stake/): Validator staking, delegation, and slashing management - Bor (
x/bor/): Producer set management and span configuration for Bor chain - Milestone (
x/milestone/): Milestone tracking for Bor finality guarantees - Clerk (
x/clerk/): Event listening and state sync record processing - Topup (
x/topup/): Fee top-up operations for validators - ChainManager (
x/chainmanager/): Chain configuration and contract address management - Bridge (
bridge/): Cross-chain event listener and processor for L1/L2 communication - SideTxs (
sidetxs/): Side transaction system for validator-verified external data - App (
app/): Core application setup with ABCI++ handlers and module orchestration
- Cosmos SDK Patterns: Standard module structure (keeper/types/client), dependency injection
- ABCI++ Integration: Vote extensions for side transactions, PrepareProposal for message inclusion
- Cross-chain Safety: Multi-signature verification for checkpoints, validator-attested state syncs
- Go Idioms: Explicit error handling, interfaces for testability, structured logging
-
Build: Build the heimdalld binary
make build
-
Lint: Run golangci-lint
make lint-deps && make lint -
Test: Run tests with vulnerability check
make test -
Proto: Regenerate protobuf code (requires Docker)
make proto-all
Each module in x/ follows standard Cosmos SDK layout:
x/<module>/
├── keeper/ # State management and business logic
├── types/ # Messages, events, genesis, queries
├── client/ # CLI commands and query handlers
├── testutil/ # Mock interfaces and test setup
├── module.go # Module registration
├── depinject.go # Dependency injection config
└── README.md # Module documentation-
Unit Tests: Test individual functions
go test -v ./path/to/package
Security rules are in .claude/rules/. They load automatically based on which files are being edited:
security.md-- always active: pre-commit checklist, Go security patterns, dependency checksconsensus-critical.md--app/,sidetxs/,x/checkpoint/,x/milestone/,x/bor/: determinism, vote extension integrity, tallying thresholdscross-chain.md--bridge/,helper/,contracts/,x/stake/,x/topup/,x/clerk/,x/chainmanager/: L1 receipt validation, nonce replay, event log verificationcontract-interactions.md--helper/call.go,helper/tx.go,contracts/,x/bor/grpc/, keepers, bridge processors: IContractCaller security, ABI encoding, tx construction, gRPC clientp2p-and-networking.md--helper/config.go,bridge/listener/,bridge/broadcaster/,cmd/,packaging/templates/: CometBFT P2P config, RPC endpoint security, bridge networking, RabbitMQstate-and-migration.md--migration/,types/,common/,proto/,x/*/types/: state migration safety, proto compatibility, shared type integrity
- ABCI++ handlers (
app/abci.go,app/vote_ext_utils.go) -- consensus break, chain halt - Vote extension tallying -- forged approvals, unauthorized state changes
- L1 receipt validation (
helper/call.go) -- fake validator joins, stolen funds - Staking nonce checks (
x/stake/keeper/side_msg_server.go) -- replay attacks - Checkpoint verification (
x/checkpoint/keeper/side_msg_server.go) -- forged checkpoints - Bridge event processing (
bridge/) -- state sync corruption
- Any change to files matched by
consensus-critical.mdorcross-chain.md - New RPC endpoints or API handlers
- Dependency updates (especially forked
cosmos-sdk,cometbft,bor) - Changes to validation logic, threshold calculations, or signature verification
- Any change touching
helper/call.go(the L1 interface)
- Identify impact: What other modules or components depend on this code?
- Plan implementation: Outline the approach before writing code
- Plan testing: How will you verify correctness? What edge cases exist?
- Check for breaking changes: Will this affect APIs, proto definitions, or stored state?
- Check security implications: Does this touch consensus, cross-chain, or validator logic? See
.claude/rules/
- Proto Changes: Always run
make proto-allafter modifying.protofiles - Keeper Dependencies: Update
expected_keepers.gowhen adding cross-module calls - Vote Extensions: Side tx results must be deterministic across all validators
- Bridge Events: New event types need both listener and processor implementations
- State Changes: Only modify state in keeper methods, never in ABCI handlers directly
- Large, sweeping changes: Keep PRs focused and reviewable
- Mixing unrelated changes: One logical change per PR
- Ignoring CI failures: All checks must pass
- Skipping proto generation: Proto/Go mismatch causes runtime panics
- Non-obvious behavior or edge cases
- Cross-chain assumptions that depend on L1/Bor state
- Consensus-critical logic where bugs affect network liveness
- Vote extension handling and determinism requirements
- Why simpler alternatives don't work
// Checkpoint interval must match L1 contract config, otherwise submissions fail.
const CheckpointInterval = 256
// FetchValidatorSet at span start, not current block, to ensure
// all validators agree on the producer set for this span.
func (k Keeper) GetSpanValidators(ctx sdk.Context, spanID uint64) ([]Validator, error)
// ProcessCheckpoint must be deterministic - all validators must compute
// the same result from the same inputs, or consensus breaks.
func (k Keeper) ProcessCheckpoint(ctx sdk.Context, checkpoint *Checkpoint) error- Self-explanatory code - if the code is clear, don't add noise
- Restating code in English -
// increment counterabovecounter++ - Describing what changed - that belongs in commit messages, not code
Before adding a comment, ask: Would someone reading just the current code (no PR, no git history) find this helpful?
-
Logging: Use zerolog with appropriate levels
helper.Logger.Debug().Uint64("span", spanID).Msg("Processing span")
-
Metrics: Add prometheus metrics for monitoring
metrics.CheckpointCount.Inc()
-
Bridge Debugging: Check RabbitMQ queues for stuck events
rabbitmqctl list_queues
Prefix with module name: x/checkpoint: fix vote extension validation
- All tests pass (
make test) - Linting passes (
make lint) - Proto files in sync (
make proto-all)
- develop - Main development branch, PRs target here
- main - Stable release branch
Update CLAUDE.md when:
- Claude makes a mistake or wrong assumption → Add clarifying context
- New patterns or conventions are established → Document them
- Frequently asked questions arise → Add answers here
This file should evolve over time to capture project-specific knowledge that helps AI agents work more effectively.