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