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