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