CLAUDE.md (3936B)
1 # ppad-bolt7 2 3 Haskell implementation of BOLT #7 (Lightning Network routing gossip). 4 5 Specification: https://github.com/lightning/bolts/blob/master/07-routing-gossip.md 6 7 ## Project Structure 8 9 - `lib/` - library source (Lightning.Protocol.BOLT7) 10 - `test/` - tests (tasty + tasty-hunit) 11 - `bench/` - benchmarks (criterion for timing, weigh for allocations) 12 - `etc/` - reference materials (BOLT spec) 13 - `flake.nix` - nix flake for dependency and build management 14 - `ppad-bolt7.cabal` - cabal package definition 15 - `CLAUDE.md` / `AGENTS.md` - keep these in sync 16 17 ## Build and Test 18 19 Enter devshell and use cabal: 20 21 ``` 22 nix develop 23 cabal build 24 cabal test 25 cabal bench 26 ``` 27 28 Do not use stack. All dependency and build management via nix. 29 30 ## Dependencies 31 32 ### ppad libraries (use freely) 33 34 Use ppad libraries (github.com/ppad-tech, git.ppad.tech) liberally. 35 36 ### External libraries 37 38 Use only minimal external dependencies. Prefer GHC's core/boot libraries 39 (base, bytestring, primitive, etc.). 40 41 **Ask for explicit confirmation before adding any library outside of:** 42 - GHC boot/core libraries 43 - ppad-* libraries 44 - Test dependencies (tasty, QuickCheck, etc. for test-suite only) 45 - Benchmark dependencies (criterion, weigh for benchmark only) 46 47 ## Code Style 48 49 ### Performance 50 51 - Use strictness annotations (BangPatterns) liberally 52 - Prefer UNPACK for strict record fields 53 - Use MagicHash, UnboxedTuples, GHC.Exts for hot paths 54 - Do not rely on UNBOX pragmas; implement primitives directly with 55 MagicHash and GHC.Exts when needed 56 - Use INLINE pragmas for small functions 57 - Refer to ppad-sha256 and ppad-fixed for low-level patterns 58 59 ### Type safety 60 61 - Encode invariants into the type system 62 - Use newtypes liberally (e.g., Sec, Pub, Session) 63 - Use ADTs to make illegal states unrepresentable 64 - Prefer smart constructors that validate inputs 65 66 ### Safety 67 68 - Never use partial Prelude functions (head, tail, !!, etc.) 69 - Use Maybe/Either for fallible operations 70 - Validate all inputs at system boundaries 71 72 ### Formatting 73 74 - Keep lines under 80 characters 75 - Use Haskell2010 76 - Module header with copyright, license, maintainer 77 - OPTIONS_HADDOCK prune for public modules 78 - Haddock examples for exported functions 79 80 ## Testing 81 82 Use tasty to wrap all tests: 83 - tasty-hunit for unit tests with known vectors 84 - tasty-quickcheck for property-based tests 85 - Source test vectors from specifications (RFC, BOLT spec, Wycheproof, etc.) 86 87 Property tests should enforce invariants that can't be encoded in types. 88 89 ## Benchmarking 90 91 Always maintain benchmark suites: 92 - `bench/Main.hs` - criterion for wall-time benchmarks 93 - `bench/Weight.hs` - weigh for allocation tracking 94 95 Define NFData instances for types that need benchmarking. 96 97 ## Git Workflow 98 99 - Feature branches for development; commit freely there 100 - Logical, atomic commits on feature branches 101 - Master should be mostly merge commits 102 - Merge to master with `--no-ff` after validation 103 - Always build and test before creating a merge commit 104 - Write detailed merge commit messages summarising changes 105 106 ### Worktree flow (for planned work) 107 108 When starting work on an implementation plan: 109 110 ``` 111 git worktree add ./impl-<desc> -b impl/<desc> master 112 # work in that worktree 113 # merge to master when complete 114 git worktree remove ./impl-<desc> 115 ``` 116 117 ### Commits 118 119 - Higher-level descriptions in merge commits 120 - Never update git config 121 - Never use destructive git commands (push --force, hard reset) without 122 explicit request 123 - Never skip hooks unless explicitly requested 124 125 ## Planning 126 127 When planning work: 128 - Highlight which steps can be done independently 129 - Consider forking subagents for concurrent work on independent steps 130 - Write implementation plans to `plans/IMPL<n>.md` if the project uses 131 this convention 132 133 ## Flake Structure 134 135 The flake.nix follows ppad conventions: 136 - Uses ppad-nixpkgs as base 137 - Follows references to avoid duplication 138 - Supports LLVM backend via cabal flag 139 - Provides devShell with ghc, cabal, cc, llvm