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

AGENTS.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