diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,16 @@
 
 ## Unreleased
 
+## 0.1.0.1 - 2026-06-21
+
+### Fixed
+
+- Adapted `Shikumi.Error.fromBaikaiError` and streaming response reassembly to the baikai 0.2 API.
+
+### Changed
+
+- Constrained baikai package dependencies to the 0.2 series for Hackage builds.
+
 ## 0.1.0.0 - 2026-06-13
 
 ### Added
diff --git a/shikumi.cabal b/shikumi.cabal
--- a/shikumi.cabal
+++ b/shikumi.cabal
@@ -1,6 +1,6 @@
 cabal-version:   3.4
 name:            shikumi
-version:         0.1.0.0
+version:         0.1.0.1
 synopsis:        Typed, structured, evaluable LM programs over baikai
 category:        AI
 description:
@@ -52,10 +52,10 @@
 
   build-depends:
     , aeson
-    , baikai
-    , baikai-claude
-    , baikai-effectful
-    , baikai-openai
+    , baikai             >=0.2  && <0.3
+    , baikai-claude      >=0.2  && <0.3
+    , baikai-effectful   >=0.2  && <0.3
+    , baikai-openai      >=0.2  && <0.3
     , base               >=4.20 && <5
     , base64-bytestring
     , bytestring
@@ -108,10 +108,10 @@
 
   build-depends:
     , aeson
-    , baikai
-    , baikai-claude
-    , baikai-effectful
-    , baikai-openai
+    , baikai             >=0.2      && <0.3
+    , baikai-claude      >=0.2      && <0.3
+    , baikai-effectful   >=0.2      && <0.3
+    , baikai-openai      >=0.2      && <0.3
     , base
     , base64-bytestring
     , bytestring
@@ -121,7 +121,7 @@
     , generic-lens
     , lens
     , QuickCheck
-    , shikumi            ^>=0.1.0.0
+    , shikumi            ^>=0.1.0.1
     , stm
     , streamly-core
     , tasty
diff --git a/src/Shikumi/Error.hs b/src/Shikumi/Error.hs
--- a/src/Shikumi/Error.hs
+++ b/src/Shikumi/Error.hs
@@ -11,7 +11,7 @@
   )
 where
 
-import Baikai.Error (BaikaiError (..))
+import Baikai.Error (BaikaiError (..), ErrorCategory (..))
 import Data.Text (Text)
 import Data.Text qualified as T
 
@@ -37,19 +37,20 @@
   deriving stock (Eq, Show)
 
 -- | Total mapping from baikai's transport-level errors into shikumi's
--- vocabulary. baikai's constructors are 'ProviderError', 'RequestInvalid',
--- 'DecodeError', and 'ProcessError'.
---
--- 'RequestInvalid' maps to 'SchemaMismatch' because in baikai a malformed request
--- is almost always bad schema/parameters; 'DecodeError' maps to 'InvalidJSON'
--- because baikai's decode failures are JSON parse failures of the provider
--- response. These two judgments are the only non-mechanical choices.
+-- vocabulary. Invalid requests map to 'SchemaMismatch' because in baikai a
+-- malformed request is almost always bad schema/parameters; decode failures
+-- map to 'InvalidJSON' because baikai's decode failures are JSON parse
+-- failures of the provider response.
 fromBaikaiError :: BaikaiError -> ShikumiError
-fromBaikaiError = \case
-  ProviderError t -> ProviderFailure t
-  RequestInvalid t -> SchemaMismatch ("invalid request: " <> t)
-  DecodeError t -> InvalidJSON t
-  ProcessError n t -> ProviderFailure ("process exited " <> T.pack (show n) <> ": " <> t)
+fromBaikaiError e = case category e of
+  DecodeFailure -> InvalidJSON (message e)
+  InvalidRequest -> SchemaMismatch ("invalid request: " <> message e)
+  ProcessFailure ->
+    ProviderFailure $
+      case exitCode e of
+        Just n -> "process exited " <> T.pack (show n) <> ": " <> message e
+        Nothing -> message e
+  _ -> ProviderFailure (message e)
 
 -- | Which errors are worth retrying. Provider/transport failures and timeouts are
 -- transient; decode, schema, validation, and budget errors are deterministic and
diff --git a/src/Shikumi/Stream.hs b/src/Shikumi/Stream.hs
--- a/src/Shikumi/Stream.hs
+++ b/src/Shikumi/Stream.hs
@@ -183,8 +183,8 @@
   [] -> synthResponse (fromMaybe "" (firstTextEnd evs))
   where
     terminalPayloads =
-      [p | EventDone (TerminalPayload _ (AssistantMessage p)) <- evs]
-        ++ [p | EventError (TerminalPayload _ (AssistantMessage p)) <- evs]
+      [p | EventDone TerminalPayload {message = AssistantMessage p} <- evs]
+        ++ [p | EventError TerminalPayload {message = AssistantMessage p} <- evs]
 
 -- | A response carrying @t@ as its single assistant text block.
 synthResponse :: Text -> Response
diff --git a/test/ErrorSpec.hs b/test/ErrorSpec.hs
--- a/test/ErrorSpec.hs
+++ b/test/ErrorSpec.hs
@@ -1,9 +1,9 @@
 -- | Pins the 'BaikaiError' -> 'ShikumiError' mapping and the 'isTransient'
--- classification. Deliberately breaking the mapping (e.g. mapping 'DecodeError'
+-- classification. Deliberately breaking the mapping (e.g. mapping 'decodeError'
 -- to 'ProviderFailure') makes this group fail.
 module ErrorSpec (tests) where
 
-import Baikai.Error (BaikaiError (..))
+import Baikai.Error (decodeError, invalidRequest, processError, providerError)
 import Shikumi.Error
   ( ShikumiError (..),
     fromBaikaiError,
@@ -16,14 +16,14 @@
 tests =
   testGroup
     "ErrorSpec"
-    [ testCase "maps ProviderError -> ProviderFailure" $
-        fromBaikaiError (ProviderError "x") @?= ProviderFailure "x",
-      testCase "maps DecodeError -> InvalidJSON" $
-        fromBaikaiError (DecodeError "y") @?= InvalidJSON "y",
-      testCase "maps RequestInvalid -> SchemaMismatch" $
-        fromBaikaiError (RequestInvalid "z") @?= SchemaMismatch "invalid request: z",
-      testCase "maps ProcessError -> ProviderFailure" $
-        fromBaikaiError (ProcessError 2 "boom") @?= ProviderFailure "process exited 2: boom",
+    [ testCase "maps providerError -> ProviderFailure" $
+        fromBaikaiError (providerError "x") @?= ProviderFailure "x",
+      testCase "maps decodeError -> InvalidJSON" $
+        fromBaikaiError (decodeError "y") @?= InvalidJSON "y",
+      testCase "maps invalidRequest -> SchemaMismatch" $
+        fromBaikaiError (invalidRequest "z") @?= SchemaMismatch "invalid request: z",
+      testCase "maps processError -> ProviderFailure" $
+        fromBaikaiError (processError 2 "boom") @?= ProviderFailure "process exited 2: boom",
       testCase "isTransient classification" $ do
         isTransient (ProviderFailure "") @?= True
         isTransient (Timeout "") @?= True
diff --git a/test/StreamSpec.hs b/test/StreamSpec.hs
--- a/test/StreamSpec.hs
+++ b/test/StreamSpec.hs
@@ -19,6 +19,7 @@
     StartPayload (..),
     StopReason (..),
     TerminalPayload (..),
+    doneTerminal,
     _Context,
     _Model,
     _Options,
@@ -106,7 +107,7 @@
 -- | The 'Response' assembled from a stream's terminal event.
 terminalResponse :: [AssistantMessageEvent] -> Response
 terminalResponse evs =
-  case [p | EventDone (TerminalPayload _ (AssistantMessage p)) <- evs] of
+  case [p | EventDone TerminalPayload {message = AssistantMessage p} <- evs] of
     (p : _) -> _Response & #message .~ p
     [] -> mkResponse ""
 
@@ -121,7 +122,7 @@
   ]
     ++ [TextDelta (DeltaPayload 0 d) | d <- deltas]
     ++ [ TextEnd (BlockEndPayload 0 (T.concat deltas)),
-         EventDone (TerminalPayload Stop (AssistantMessage (payloadWith terminalText)))
+         EventDone (doneTerminal Stop (AssistantMessage (payloadWith terminalText)))
        ]
   where
     payloadWith t = (_Response ^. #message) & #content .~ V.singleton (AssistantText (_TextContent & #text .~ t))
diff --git a/test/StubProvider.hs b/test/StubProvider.hs
--- a/test/StubProvider.hs
+++ b/test/StubProvider.hs
@@ -95,7 +95,7 @@
     TextStart IndexPayload {contentIndex = 0},
     TextDelta DeltaPayload {contentIndex = 0, delta = t},
     TextEnd BlockEndPayload {contentIndex = 0, content = t},
-    EventDone TerminalPayload {reason = Stop, message = AssistantMessage (stubPayloadWith t)}
+    EventDone (doneTerminal Stop (AssistantMessage (stubPayloadWith t)))
   ]
 
 -- | Build an isolated registry from a @complete@ implementation, reusing the
@@ -122,7 +122,7 @@
 costStubRegistry c t =
   mkRegistry t (\_ _ _ -> pure (stubResponse t & #message . #usage . #cost . #usd .~ c))
 
--- | A registry whose @complete@ throws 'ProviderError' (a transient failure) the
+-- | A registry whose @complete@ throws 'providerError' (a transient failure) the
 -- first @failTimes@ calls, then returns the given text. The 'IORef' records the
 -- total number of attempts (used by the retry tests).
 failingStubRegistry :: IORef Int -> Int -> Text -> IO ProviderRegistry
@@ -130,17 +130,17 @@
   mkRegistry t $ \_ _ _ -> do
     n <- atomicModifyIORef' ref (\k -> (k + 1, k + 1))
     if n <= failTimes
-      then throwIO (ProviderError ("stub transient failure #" <> T.pack (show n)))
+      then throwIO (providerError ("stub transient failure #" <> T.pack (show n)))
       else pure (stubResponse t)
 
--- | A registry whose @complete@ always throws 'RequestInvalid' (a non-transient
+-- | A registry whose @complete@ always throws 'invalidRequest' (a non-transient
 -- failure that maps to 'Shikumi.Error.SchemaMismatch'). The 'IORef' records the
 -- number of attempts (a retry must not increase it).
 invalidStubRegistry :: IORef Int -> IO ProviderRegistry
 invalidStubRegistry ref =
   mkRegistry "" $ \_ _ _ -> do
     _ <- atomicModifyIORef' ref (\k -> (k + 1, k + 1))
-    throwIO (RequestInvalid "stub bad request")
+    throwIO (invalidRequest "stub bad request")
 
 -- | A registry whose @complete@ records observed concurrency: it bumps @cur@ on
 -- entry (updating the running maximum in @mx@), sleeps briefly, and decrements on
