|
1 | 1 | # CLAUDE.md |
2 | 2 |
|
3 | | -This file provides guidance to Claude Code when working with this Substrate blockchain repository. |
| 3 | +This file provides strict guidance to Claude Code when working with this Substrate blockchain repository. These rules are non-negotiable and must be followed exactly. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Torus is a stake-driven peer-to-peer network built on Substrate. The blockchain manages agents (validators and miners), token emissions, staking, and governance. Code quality is critical - runtime panics will halt the entire chain. |
4 | 8 |
|
5 | 9 | ## References |
6 | 10 |
|
7 | 11 | - @README.md - Project overview, quick start, network setup |
8 | 12 | - @CONTRIBUTING.md - Development setup (Nix), guidelines, testing |
9 | 13 | - @docs/pallet-structure.md - Architecture and API design |
10 | 14 | - @docs/xtask-manual.md - Development tooling guide |
| 15 | +- @docs/linear-emission.md - Token distribution algorithm |
11 | 16 |
|
12 | 17 | ## Core Pallets |
13 | 18 |
|
14 | | -- **`torus0`**: Agent registration, staking, burn mechanisms |
15 | | -- **`emission0`**: Token distribution with linear emission algorithm |
16 | | -- **`governance`**: Proposals, voting, treasury, roles |
| 19 | +- **`torus0`**: Agent registration, staking, burn mechanisms, fee management |
| 20 | +- **`emission0`**: Token distribution with linear emission algorithm, weight control |
| 21 | +- **`governance`**: Proposals, voting, treasury, roles (allocators, curators) |
17 | 22 | - **`permission0`**: Permission and access control |
18 | 23 |
|
| 24 | +## Architecture Principles |
| 25 | + |
| 26 | +- **API-first design**: Each pallet has separate `api` crate to prevent circular dependencies |
| 27 | +- **Domain separation**: Complex logic split into focused modules (agent.rs, stake.rs, etc.) |
| 28 | +- **Storage efficiency**: Use container types to minimize state size |
| 29 | +- **Zero-panic policy**: Runtime code must NEVER panic under any circumstances |
| 30 | + |
19 | 31 | ## Essential Commands |
20 | 32 |
|
21 | 33 | ```sh |
22 | | -nix develop # Enter development environment |
23 | | -just # Run checks and tests (default) |
| 34 | +# Development environment (REQUIRED - provides correct Rust version, dependencies) |
| 35 | +nix develop |
| 36 | + |
| 37 | +# Running tests and checks |
| 38 | +just # Run all checks and tests (default) |
24 | 39 | just check # Clippy linting only |
25 | 40 | just test # Test suite only |
26 | | -cargo xtask coverage # Test coverage report |
| 41 | +cargo xtask coverage # Generate code coverage report |
| 42 | + |
| 43 | +# Local development |
| 44 | +cargo xtask run local --alice # Run local node with Alice account |
| 45 | +cargo xtask generate-spec gen-new # Create new chain spec |
| 46 | +cargo build --release # Build the node |
27 | 47 | ``` |
28 | 48 |
|
29 | | -## Critical Safety Rules |
| 49 | +## STRICT RUST CODING RULES |
| 50 | + |
| 51 | +### Error Handling - CRITICAL SAFETY |
| 52 | + |
| 53 | +- **MUST NEVER** use `unwrap()`, `expect()`, `assert!()`, or any panicking operations in pallet code |
| 54 | +- **MUST ALWAYS** use `ensure!` macro for validation, NEVER `assert!` |
| 55 | +- **MUST ALWAYS** use the `?` operator for error propagation |
| 56 | +- **MUST ALWAYS** use pattern matching with proper error handling: |
| 57 | + ```rust |
| 58 | + let Some(value) = some_option else { |
| 59 | + return Err(Error::<T>::SomeError.into()); |
| 60 | + }; |
| 61 | + ``` |
| 62 | + |
| 63 | +### Arithmetic Operations - NO EXCEPTIONS |
| 64 | + |
| 65 | +- **MUST NEVER** use raw arithmetic operators (`+`, `-`, `*`, `/`) in runtime code |
| 66 | +- **MUST ALWAYS** use `saturating_add()`, `saturating_sub()`, `saturating_mul()` for balance operations |
| 67 | +- **MUST ALWAYS** use `checked_div()` for division - NEVER the `/` operator |
| 68 | +- **MUST ALWAYS** use `FixedU128` for ALL percentage and ratio calculations |
| 69 | +- **MUST ALWAYS** handle overflow explicitly with `checked_*` operations when needed |
| 70 | + |
| 71 | +### Function Structure - MANDATORY PATTERNS |
| 72 | + |
| 73 | +- **MUST ALWAYS** write functions as generic `pub fn name<T: Config>()` rather than `impl<T: Config> Pallet<T>` |
| 74 | +- **MUST ALWAYS** use type aliases: `AccountIdOf<T>`, `BalanceOf<T>`, etc. |
| 75 | +- **MUST ALWAYS** validate ALL inputs in private functions before storage operations |
| 76 | +- **MUST NEVER** expose unsafe operations through public functions |
| 77 | + |
| 78 | +### Storage Operations - STRICT REQUIREMENTS |
| 79 | + |
| 80 | +- **MUST ALWAYS** use `try_mutate` when the operation can fail |
| 81 | +- **MUST ALWAYS** check existence with `contains_key` before accessing storage |
| 82 | +- **MUST ALWAYS** use `BoundedVec` for ALL storage collections |
| 83 | +- **MUST ALWAYS** validate data BEFORE storage mutations |
| 84 | +- **MUST NEVER** perform multiple storage writes when one would suffice |
| 85 | + |
| 86 | +### Extrinsic Requirements - NO FLEXIBILITY |
| 87 | + |
| 88 | +- **MUST ALWAYS** use manual call indexing: `#[pallet::call_index(n)]` |
| 89 | +- **MUST ALWAYS** specify weight info for ALL extrinsics |
| 90 | +- **MUST ALWAYS** emit appropriate events after state changes |
| 91 | +- **MUST ALWAYS** use `ensure_signed(origin)?` at the start of signed extrinsics |
| 92 | + |
| 93 | +### Documentation - MANDATORY |
| 94 | + |
| 95 | +- **MUST ALWAYS** document ALL storage items, extrinsics, errors, and public functions |
| 96 | +- **MUST ALWAYS** use `///` doc comments for items exported to client SDKs |
| 97 | +- **MUST NEVER** leave TODOs or incomplete implementations in production code |
| 98 | + |
| 99 | +### Import and Dependency Rules |
| 100 | + |
| 101 | +- **MUST ALWAYS** use `polkadot_sdk` umbrella crate - NEVER individual substrate dependencies |
| 102 | +- **MUST ALWAYS** use `use crate::*` for intra-pallet imports |
| 103 | +- **MUST NEVER** use wildcard imports except for preludes |
| 104 | + |
| 105 | +### Type Safety - ZERO TOLERANCE |
| 106 | + |
| 107 | +- **MUST ALWAYS** use `BoundedVec<T, ConstU32<MAX>>` for storage, NEVER `Vec<T>` |
| 108 | +- **MUST ALWAYS** convert with error handling: `BoundedVec::try_from(vec)?` |
| 109 | +- **MUST ALWAYS** use proper type conversions with `.try_into()` and handle errors |
| 110 | +- **MUST NEVER** use `as` for lossy numeric conversions |
| 111 | + |
| 112 | +### Common Code Patterns - REQUIRED |
| 113 | + |
| 114 | +- **MUST ALWAYS** emit events after successful state changes: |
| 115 | + ```rust |
| 116 | + Pallet::<T>::deposit_event(Event::<T>::SomethingHappened(who, what)); |
| 117 | + ``` |
| 118 | +- **MUST ALWAYS** validate string data is UTF-8: |
| 119 | + ```rust |
| 120 | + ensure!(core::str::from_utf8(bytes).is_ok(), Error::<T>::InvalidUtf8); |
| 121 | + ``` |
| 122 | +- **MUST ALWAYS** check bounds before operations: |
| 123 | + ```rust |
| 124 | + ensure!(value <= T::MaxValue::get(), Error::<T>::ValueTooLarge); |
| 125 | + ``` |
| 126 | + |
| 127 | +### Testing Requirements - NON-NEGOTIABLE |
| 128 | + |
| 129 | +- **MUST ALWAYS** write comprehensive tests for ALL extrinsics |
| 130 | +- **MUST ALWAYS** test error conditions and edge cases |
| 131 | +- **MUST ALWAYS** benchmark ALL extrinsics for weight calculation |
| 132 | +- **MUST NEVER** merge code without adequate test coverage |
| 133 | + |
| 134 | +### Migration Safety - CRITICAL |
| 135 | + |
| 136 | +- **MUST ALWAYS** use `VersionedMigration` for storage migrations |
| 137 | +- **MUST ALWAYS** increment storage version when changing storage |
| 138 | +- **MUST NEVER** modify storage structure without a migration |
| 139 | +- **MUST ALWAYS** test migrations with realistic data |
| 140 | + |
| 141 | +### Code Style - ENFORCED BY CI |
| 142 | + |
| 143 | +- **MUST ALWAYS** run `cargo fmt` before committing |
| 144 | +- **MUST ALWAYS** fix ALL clippy warnings |
| 145 | +- **MUST ALWAYS** use descriptive variable names, no single letters |
| 146 | +- **MUST NEVER** use repetitive and redundant comments within code |
| 147 | +- **MUST NEVER** ignore compiler or clippy warnings with `#[allow(...)]` |
| 148 | + |
| 149 | +### Before committing: |
30 | 150 |
|
31 | | -- Never use `unwrap()`, `expect()`, or panicking operations in pallet code |
32 | | -- Use `checked_div()` instead of `/` for arithmetic operations |
33 | | -- Panics in runtime code will halt the chain |
34 | | -- Use `FixedU128` for financial calculations |
| 151 | +1. **MUST** run `cargo fmt` |
| 152 | +2. **MUST** run `just check` and fix all warnings |
| 153 | +3. **MUST** run `just test` and ensure all pass |
| 154 | +4. **MUST** run `cargo xtask coverage` to verify coverage |
| 155 | +5. **MUST** test runtime upgrades if storage changed |
0 commit comments