# AGENTS.md: Haskell

## Commands
- Detect the tool: `stack.yaml` → `stack build --fast`, `stack test`; otherwise cabal → `cabal build all`, `cabal test all`. Use the resolver/`index-state` and GHC version the repo pins.
- Lint: `hlint src test app` · Format: the configured formatter (`fourmolu -i` or `ormolu -i`) on changed files only.
- Fast feedback: `ghcid` or `cabal repl` if configured.

## Code
- Builds are warning-free under the project's flags (`-Wall` and friends). Fix warnings; don't add `{-# OPTIONS_GHC -Wno-... #-}` to silence them.
- Total functions only: no `head`, `tail`, `fromJust`, `!!`, `read` or incomplete pattern matches in library code. Use `NonEmpty`, `listToMaybe`, `readMaybe`, and handle every constructor.
- `Text` (strict) for text and `ByteString` for bytes; `String` only at legacy edges. Enable `OverloadedStrings` where the project does.
- Model the domain with newtypes and sum types; make invalid states unrepresentable. Smart constructors return `Either Error a`.
- Follow the project's effect style (plain `IO` with a `ReaderT Env IO` app monad, mtl classes, or an effects library). Don't introduce a second style.
- Errors: expected failures are values (`Either`, `ExceptT` or the effect library's error); exceptions are for truly exceptional IO. Use `bracket`/`withFile`/`ResourceT` so resources are always released.
- Strictness: strict fields (`!`) or `StrictData` for long-lived records; use `foldl'`, never lazy `foldl` on big lists.
- Explicit export lists on modules; qualified imports for containers (`import qualified Data.Map.Strict as Map`).
- Add dependencies to the `.cabal`/`package.yaml` with sensible version bounds; keep the lockfile/freeze file updated.

## Tests
hspec or tasty in `test/`, with QuickCheck/Hedgehog properties for pure functions and round-trips (e.g. encode/decode).

## Done when
Build and tests pass with no new warnings and hlint clean on changed modules.
