auditor

An aarch64 constant-time memory access auditing tool.
git clone git://git.ppad.tech/auditor.git
Log | Files | Refs | README | LICENSE

CLAUDE.md (4072B)


      1 # ppad-auditor
      2 
      3 Haskell tool for static analysis of GHC aarch64 assembly with a focus
      4 on constant-time memory access auditing.
      5 
      6 ## Project Structure
      7 
      8 - `lib/` - library source (parser, CFG, analysis)
      9 - `app/` - CLI entrypoint
     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-auditor.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) when helpful.
     34 Current dependencies: aeson, bytestring, containers, megaparsec, text,
     35 optparse-applicative.
     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 - Current project deps: aeson, bytestring, containers, megaparsec,
     45   optparse-applicative, text
     46 - ppad-* libraries
     47 - Test dependencies (tasty, QuickCheck, etc. for test-suite only)
     48 - Benchmark dependencies (criterion, weigh for benchmark only)
     49 
     50 ## Code Style
     51 
     52 ### Performance
     53 
     54 - Prefer strict data structures where it simplifies analysis
     55 - Avoid unnecessary allocations in hot paths (parsing, dataflow)
     56 
     57 ### Type safety
     58 
     59 - Encode invariants into the type system
     60 - Use newtypes liberally (e.g., Reg, Sym, Label)
     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 fixtures from real GHC aarch64 dumps and hand-crafted samples
     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