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