tx

Minimal transaction primitives (docs.ppad.tech/tx).
git clone git://git.ppad.tech/tx.git
Log | Files | Refs | README | LICENSE

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