CLAUDE.md (3954B)
1 # ppad-bolt1 2 3 Haskell implementation of BOLT #1 (Lightning Network base protocol). 4 5 Specification: https://github.com/lightning/bolts/blob/master/01-messaging.md 6 7 ## Project Structure 8 9 - `lib/` - library source (public API: Lightning.Protocol.BOLT1; 10 submodules are internal) 11 - `test/` - tests (tasty + tasty-hunit) 12 - `bench/` - benchmarks (criterion for timing, weigh for allocations) 13 - `etc/` - reference materials (BOLT spec, pinned upstream commit) 14 - `flake.nix` - nix flake for dependency and build management 15 - `ppad-bolt1.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 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., Sec, Pub, Session) 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 - Use Maybe/Either for fallible operations 71 - Validate all inputs at system boundaries 72 73 ### Formatting 74 75 - Keep lines under 80 characters 76 - Use Haskell2010 77 - Module header with copyright, license, maintainer 78 - OPTIONS_HADDOCK prune for public modules 79 - Haddock examples for exported functions 80 81 ## Testing 82 83 Use tasty to wrap all tests: 84 - tasty-hunit for unit tests with known vectors 85 - tasty-quickcheck for property-based tests 86 - Source test vectors from specifications (RFC, BOLT spec, Wycheproof, etc.) 87 88 Property tests should enforce invariants that can't be encoded in types. 89 90 ## Benchmarking 91 92 Always maintain benchmark suites: 93 - `bench/Main.hs` - criterion for wall-time benchmarks 94 - `bench/Weight.hs` - weigh for allocation tracking 95 96 Define NFData instances for types that need benchmarking. 97 98 ## Git Workflow 99 100 - Feature branches for development; commit freely there 101 - Logical, atomic commits on feature branches 102 - Master should be mostly merge commits 103 - Merge to master with `--no-ff` after validation 104 - Always build and test before creating a merge commit 105 - Write detailed merge commit messages summarising changes 106 107 ### Worktree flow (for planned work) 108 109 When starting work on an implementation plan: 110 111 ``` 112 git worktree add ./impl-<desc> -b impl/<desc> master 113 # work in that worktree 114 # merge to master when complete 115 git worktree remove ./impl-<desc> 116 ``` 117 118 ### Commits 119 120 - Higher-level descriptions in merge commits 121 - Never update git config 122 - Never use destructive git commands (push --force, hard reset) without 123 explicit request 124 - Never skip hooks unless explicitly requested 125 126 ## Planning 127 128 When planning work: 129 - Highlight which steps can be done independently 130 - Consider forking subagents for concurrent work on independent steps 131 - Write implementation plans to `plans/IMPL<n>.md` if the project uses 132 this convention 133 134 ## Flake Structure 135 136 The flake.nix follows ppad conventions: 137 - Uses ppad-nixpkgs as base 138 - Follows references to avoid duplication 139 - Provides devShell with ghc, cabal, cc, llvm