bolt8

Encrypted and authenticated transport, per BOLT #8 (docs.ppad.tech/bolt8).
git clone git://git.ppad.tech/bolt8.git
Log | Files | Refs | README | LICENSE

CLAUDE.md (4207B)


      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 
      7 ## Project Structure
      8 
      9 - `lib/` - library source (Lightning.Protocol.BOLT8)
     10 - `test/` - tests (tasty + tasty-hunit)
     11 - `bench/` - benchmarks (criterion for timing, weigh for allocations)
     12 - `flake.nix` - nix flake for dependency and build management
     13 - `ppad-bolt8.cabal` - cabal package definition
     14 - `CLAUDE.md` / `AGENTS.md` - keep these in sync
     15 
     16 ## Build and Test
     17 
     18 Enter devshell and use cabal:
     19 
     20 ```
     21 nix develop
     22 cabal build
     23 cabal test
     24 cabal bench
     25 ```
     26 
     27 Do not use stack. All dependency and build management via nix.
     28 
     29 ## Dependencies
     30 
     31 ### ppad libraries (use freely)
     32 
     33 Use ppad libraries (github.com/ppad-tech, git.ppad.tech) liberally.
     34 Current dependencies: ppad-aead, ppad-hkdf, ppad-secp256k1, ppad-sha256.
     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 - 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