diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# v2.0.0.2
+
+Work around the bugs in Cabal/Haddock that cause missing documentation for two-hop reexported internal modules.
+
 # v2.0.0.1
 
 Support for `pqi-1.1`.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,19 +6,27 @@
 PostgreSQL driver for Haskell, that prioritizes:
 
 - Performance
-- Typesafety
+- Reliability
 - Flexibility
 
 # Status
 
 Hasql is production-ready, actively maintained and the API is moderately stable. It's used by many companies and most notably by the [Postgrest](https://github.com/PostgREST/postgrest) project.
 
-# A New Era: Pluggable Transport
+# Pluggable Transport
 
-Hasql's transport is now pluggable via [`pqi`](https://github.com/nikita-volkov/pqi). `Hasql.Connection.acquire` takes an adapter explicitly:
+Hasql's transport is pluggable via [`pqi`](https://github.com/nikita-volkov/pqi). Hasql itself carries no C dependency. It programs against the `pqi` interface, and you pick the adapter that implements it. That means you depend on two packages, not one:
 
+```cabal
+build-depends:
+  hasql,
+  pqi-ffi,  -- or pqi-native
+```
+
+`Hasql.Connection.acquire` then takes the adapter explicitly, as its first argument:
+
 ```haskell
-import Pqi.Ffi qualified    -- the existing C-backed libpq transport
+import Pqi.Ffi qualified    -- the C-backed libpq transport
 import Pqi.Native qualified -- alpha: pure-Haskell, no C dependency, interchangeable with Pqi.Ffi
 
 connection <- Hasql.Connection.acquire Pqi.Ffi.adapter settings
@@ -26,8 +34,10 @@
 connection <- Hasql.Connection.acquire Pqi.Native.adapter settings
 ```
 
-[`pqi-native`](https://github.com/nikita-volkov/pqi-native) is the goal of this new era: a from-scratch, pure-Haskell implementation of the Postgres wire protocol, verified byte-for-byte against `libpq` via [`pqi-conformance`](https://github.com/nikita-volkov/pqi-conformance). **It's alpha** - not yet proven at production scale - while [`pqi-ffi`](https://github.com/nikita-volkov/pqi-ffi) remains the stable, production-proven default. The two adapters are fully interchangeable: swapping between them is a one-line change (a different `Adapter` value, nothing else), so early adopters can try `pqi-native` today with no lock-in and no rewrite to fall back if needed. Feedback welcome on [GitHub Discussions](https://github.com/nikita-volkov/hasql/discussions).
+[`pqi-ffi`](https://github.com/nikita-volkov/pqi-ffi) is the stable, production-proven default. It binds the C `libpq` library, so it requires `libpq` of at least version 14 to be installed to compile - which typically just means having a recent PostgreSQL distro installed. Through it Hasql is tested against a wide range of PostgreSQL servers, starting from version 9.
 
+[`pqi-native`](https://github.com/nikita-volkov/pqi-native) is a from-scratch, pure-Haskell implementation of the Postgres wire protocol, with no C dependency at all. It is thoroughly tested: [`pqi-conformance`](https://github.com/nikita-volkov/pqi-conformance) runs it side by side with `libpq` on the same inputs and checks that the results agree, and the test-suites of `hasql`, [`hasql-pool`](https://github.com/nikita-volkov/hasql-pool) and [`hasql-transaction`](https://github.com/nikita-volkov/hasql-transaction) now run against both adapters, so the whole stack above the transport is exercised on `pqi-native` too. **It's still labelled alpha** - not yet proven at production scale. The two adapters are fully interchangeable: swapping between them is a one-line change (a different `Adapter` value, nothing else), so you can try `pqi-native` today with no lock-in and no rewrite to fall back if needed.
+
 # Ecosystem
 
 Hasql is not just a single library, it is a granular ecosystem of composable libraries, each isolated to perform its own task and stay simple.
@@ -60,6 +70,16 @@
 
 <sup>Want to list your package or correct something here? Make a PR.</sup>
 
+## Transport adapters
+
+Unlike the extension libraries above, which are optional, a transport adapter is mandatory: Hasql needs one to talk to the server at all. See [Pluggable Transport](#pluggable-transport) for how to pick one.
+
+- ["pqi"](https://github.com/nikita-volkov/pqi) - the driver-agnostic interface that Hasql programs against. Pulled in automatically. You don't depend on it directly.
+
+- ["pqi-ffi"](https://github.com/nikita-volkov/pqi-ffi) - the stable adapter, backed by the C `libpq` library.
+
+- ["pqi-native"](https://github.com/nikita-volkov/pqi-native) - an alpha pure-Haskell adapter speaking the PostgreSQL wire protocol directly, with no C dependency.
+
 ## Why make it an ecosystem?
 
 - **Focus.**
@@ -107,7 +127,7 @@
 import qualified Hasql.Encoders as Encoders
 import qualified Hasql.Session as Session
 import qualified Hasql.Statement as Statement
-import qualified Pqi.Ffi -- from "pqi-ffi" (stable); swap for "Pqi.Native" from "pqi-native" (alpha, fully interchangeable) to try the pure-Haskell backend
+import qualified Pqi.Ffi -- from "pqi-ffi" (stable). Swap for "Pqi.Native" from "pqi-native" (alpha, fully interchangeable) to try the pure-Haskell backend
 
 main :: IO ()
 main = do
diff --git a/hasql.cabal b/hasql.cabal
--- a/hasql.cabal
+++ b/hasql.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: hasql
-version: 2.0.0.1
+version: 2.0.0.2
 category: Hasql, Database, PostgreSQL
 synopsis: Fast PostgreSQL driver with a flexible mapping API
 description:
@@ -9,15 +9,34 @@
   Extended functionality such as pooling, transactions and compile-time checking of SQL is provided by extension libraries.
   For more details and tutorials see <https://github.com/nikita-volkov/hasql the readme>.
 
-  The API comes free from all kinds of exceptions.
-  All error-reporting is explicit and is presented using the 'Either' type.
+  All error-reporting is explicit:
+  database, protocol and connection failures are reported via the 'Either' type
+  instead of being thrown as exceptions.
 
-  \"hasql\" requires you to have the \"libpq\" C-library of at least version 14 installed to compile.
-  \"libpq\" comes distributed with PostgreSQL,
-  so typically all you need is just to install the latest PostgreSQL distro.
+  The transport layer is pluggable via <https://hackage.haskell.org/package/pqi pqi>,
+  so \"hasql\" itself carries no C dependency.
+  To compile an application you need to depend on \"hasql\" together with one adapter package
+  and pass that adapter to @Hasql.Connection.acquire@ as its first argument.
+  Two adapters are available:
 
-  Despite the mentioned requirements for \"libpq\" \"hasql\" is thoroughly tested to be compatible
-  with a wide range of PostgreSQL servers starting from version 9.
+  * <https://hackage.haskell.org/package/pqi-ffi pqi-ffi> -
+    the stable, production-proven adapter, backed by the C \"libpq\" library.
+    It requires \"libpq\" of at least version 14 to be installed to compile.
+    \"libpq\" comes distributed with PostgreSQL,
+    so typically all you need is just to install the latest PostgreSQL distro.
+    Via this adapter \"hasql\" is thoroughly tested to be compatible
+    with a wide range of PostgreSQL servers starting from version 9.
+
+  * <https://hackage.haskell.org/package/pqi-native pqi-native> -
+    a pure-Haskell adapter, which speaks the PostgreSQL wire protocol directly
+    and thus requires no C dependency at all.
+    It is thoroughly tested:
+    <https://github.com/nikita-volkov/pqi-conformance pqi-conformance> runs it
+    side by side with \"libpq\" on the same inputs and checks that the results agree,
+    and the test-suites of \"hasql\", \"hasql-pool\" and \"hasql-transaction\"
+    run against both adapters.
+    It is still labelled __alpha__, but is fully interchangeable with \"pqi-ffi\":
+    switching between the two is a one-line change.
 
 homepage: https://github.com/nikita-volkov/hasql
 bug-reports: https://github.com/nikita-volkov/hasql/issues
diff --git a/src/library-tests/Integration/Sharing/SpecHook.hs b/src/library-tests/Integration/Sharing/SpecHook.hs
--- a/src/library-tests/Integration/Sharing/SpecHook.hs
+++ b/src/library-tests/Integration/Sharing/SpecHook.hs
@@ -10,10 +10,9 @@
 type HookedSpec = SpecWith Scripts.ScopeParams
 
 hook :: HookedSpec -> SpecWith Pqi.Adapter
-hook hookedSpec =
-  parallel do
-    byDistro "postgres:9"
-    byDistro "postgres:18"
+hook hookedSpec = do
+  byDistro "postgres:9"
+  byDistro "postgres:18"
   where
     byDistro tagName =
       describe (toList tagName)
@@ -27,4 +26,4 @@
                   }
                 (\(host, port) -> action (adapter, host, port))
           )
-          hookedSpec
+          (parallel hookedSpec)
diff --git a/src/library/Hasql/Connection.hs b/src/library/Hasql/Connection.hs
--- a/src/library/Hasql/Connection.hs
+++ b/src/library/Hasql/Connection.hs
@@ -28,6 +28,26 @@
 
 -- |
 -- Establish a connection according to the provided settings.
+--
+-- The first argument is a 'Pqi.Adapter', which defines the backend
+-- implementation used to talk to PostgreSQL (for example, libpq via the
+-- <https://hackage.haskell.org/package/pqi-ffi pqi-ffi> package, or a pure
+-- Haskell implementation via the
+-- <https://hackage.haskell.org/package/pqi-native pqi-native> package).
+--
+-- This is the only place in the library where users choose the adapter.
+--
+-- Typical usage is to pass the application's default adapter.
+--
+-- This function:
+--
+-- - Opens a PostgreSQL connection using the constructed connection string.
+-- - Validates that the connection is healthy.
+-- - Checks the server version for compatibility.
+-- - Initializes session-level settings (encoding and message verbosity).
+--
+-- On success, returns a 'Connection' wrapped in 'Right'.
+-- On failure, returns a classified 'ConnectionError' in 'Left'.
 acquire ::
   Adapter ->
   Settings.Settings ->
diff --git a/src/library/Hasql/Decoders.hs b/src/library/Hasql/Decoders.hs
--- a/src/library/Hasql/Decoders.hs
+++ b/src/library/Hasql/Decoders.hs
@@ -86,6 +86,60 @@
   )
 where
 
-import Hasql.Codecs.Decoders
-import Hasql.Engine.Decoders.Result
-import Hasql.Engine.Decoders.Row
+-- Every identifier below is imported directly from the module it's
+-- actually declared in, rather than from an intermediate re-export
+-- module. Haddock has a bug where docs of an identifier re-exported
+-- through more than one hop (declaration site -> intermediate re-export
+-- -> here) silently render blank on Hackage; importing straight from the
+-- declaration site keeps this a single hop.
+import Hasql.Codecs.Decoders (array, composite, listArray, record, vectorArray)
+import Hasql.Codecs.Decoders.Array (Array, dimension, element)
+import Hasql.Codecs.Decoders.Composite (Composite, field)
+import Hasql.Codecs.Decoders.NullableOrNot (NullableOrNot, nonNullable, nullable)
+import Hasql.Codecs.Decoders.Value
+  ( Value,
+    bool,
+    bpchar,
+    bytea,
+    char,
+    citext,
+    custom,
+    date,
+    datemultirange,
+    daterange,
+    enum,
+    float4,
+    float8,
+    hstore,
+    inet,
+    int2,
+    int4,
+    int4multirange,
+    int4range,
+    int8,
+    int8multirange,
+    int8range,
+    interval,
+    json,
+    jsonBytes,
+    jsonb,
+    jsonbBytes,
+    macaddr,
+    numeric,
+    nummultirange,
+    numrange,
+    refine,
+    text,
+    time,
+    timestamp,
+    timestamptz,
+    timetz,
+    tsmultirange,
+    tsrange,
+    tstzmultirange,
+    tstzrange,
+    uuid,
+    varchar,
+  )
+import Hasql.Engine.Decoders.Result (Result, foldlRows, foldrRows, noResult, rowList, rowMaybe, rowVector, rowsAffected, singleRow)
+import Hasql.Engine.Decoders.Row (Row, column)
diff --git a/src/library/Hasql/Encoders.hs b/src/library/Hasql/Encoders.hs
--- a/src/library/Hasql/Encoders.hs
+++ b/src/library/Hasql/Encoders.hs
@@ -77,4 +77,63 @@
   )
 where
 
-import Hasql.Codecs.Encoders
+-- Every identifier below is imported directly from the module it's
+-- actually declared in, rather than from "Hasql.Codecs.Encoders" (which
+-- merely re-exports them). Haddock has a bug where docs of an identifier
+-- re-exported through more than one hop (declaration site -> intermediate
+-- re-export -> here) silently render blank on Hackage; importing straight
+-- from the declaration site keeps this a single hop.
+import Hasql.Codecs.Encoders (array, composite, foldableArray)
+import Hasql.Codecs.Encoders.Array (Array, dimension, element)
+import Hasql.Codecs.Encoders.Composite (Composite, field)
+import Hasql.Codecs.Encoders.NullableOrNot (NullableOrNot, nonNullable, nullable)
+import Hasql.Codecs.Encoders.Params (Params, noParams, param)
+import Hasql.Codecs.Encoders.Value
+  ( Value,
+    bool,
+    bpchar,
+    bytea,
+    char,
+    citext,
+    custom,
+    date,
+    datemultirange,
+    daterange,
+    enum,
+    float4,
+    float8,
+    hstore,
+    inet,
+    int2,
+    int4,
+    int4multirange,
+    int4range,
+    int8,
+    int8multirange,
+    int8range,
+    interval,
+    json,
+    jsonBytes,
+    jsonLazyBytes,
+    jsonb,
+    jsonbBytes,
+    jsonbLazyBytes,
+    macaddr,
+    name,
+    numeric,
+    nummultirange,
+    numrange,
+    oid,
+    text,
+    time,
+    timestamp,
+    timestamptz,
+    timetz,
+    tsmultirange,
+    tsrange,
+    tstzmultirange,
+    tstzrange,
+    unknown,
+    uuid,
+    varchar,
+  )
