diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,20 @@
 
 ## [Unreleased]
 
+## 0.12.0.1 — 2026-10-28
+
+### Changed
+
+- Require `mori://shinzui/baikai/packages/baikai` 0.10.0.0,
+  `mori://shinzui/baikai/packages/baikai-claude` 0.7.3.0,
+  `mori://shinzui/baikai/packages/baikai-openai` 0.7.3.0 and
+  `mori://shinzui/baikai/packages/baikai-effectful` 0.4.0.5.
+- Require `mori://shinzui/shikumi/packages/shikumi` 0.4.1.1 and
+  `mori://shinzui/shikumi/packages/shikumi-trace` 0.3.0.2. Until upstream releases
+  compatible bounds, consumer projects must allow newer Baikai specifically for
+  Shikumi, Shikumi Cache and Shikumi Trace, as shown in this repository's
+  `cabal.project`. The response codec and text-program paths retain compatibility.
+
 ## 0.12.0.0 — 2026-10-27
 
 ### Breaking Changes
diff --git a/kioku-core.cabal b/kioku-core.cabal
--- a/kioku-core.cabal
+++ b/kioku-core.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: kioku-core
-version: 0.12.0.0
+version: 0.12.0.1
 synopsis: Reusable agent memory runtime
 description:
   Core runtime for kioku. M1 establishes the application effect stack; later
@@ -113,10 +113,10 @@
   ghc-prof-options: -fno-opt-coercion
   build-depends:
     aeson >=2.2 && <2.3,
-    baikai >=0.7.0.0 && <0.9,
-    baikai-claude ^>=0.7.0.0,
-    baikai-effectful ^>=0.4.0.1,
-    baikai-openai ^>=0.7.0.0,
+    baikai ^>=0.10.0.0,
+    baikai-claude ^>=0.7.3.0,
+    baikai-effectful ^>=0.4.0.5,
+    baikai-openai ^>=0.7.3.0,
     base >=4.21 && <5,
     bytestring >=0.11 && <0.13,
     containers >=0.6 && <0.8,
@@ -136,7 +136,7 @@
     keiki ^>=0.9.1.0,
     keiro ^>=0.22.0.0,
     keiro-core ^>=0.22.0.0,
-    kioku-api ^>=0.12.0.0,
+    kioku-api ^>=0.12.0.1,
     kiroku-store ^>=0.12.0.0,
     lens >=5.2 && <5.4,
     mmzk-typeid >=0.7 && <0.8,
@@ -144,8 +144,8 @@
     relay-pagination-hasql ^>=0.1.1.2,
     shibuya-core ^>=0.12.0.0,
     shibuya-kiroku-adapter ^>=0.7.0.0,
-    shikumi ^>=0.4.0.0,
-    shikumi-trace ^>=0.3.0.0,
+    shikumi ^>=0.4.1.1,
+    shikumi-trace ^>=0.3.0.2,
     text >=2.1 && <2.2,
     time >=1.12 && <1.15,
     unix >=2.8.8 && <2.9,
@@ -193,7 +193,7 @@
   build-depends:
     aeson >=2.2,
     async >=2.2 && <2.3,
-    baikai >=0.7.0.0 && <0.9,
+    baikai ^>=0.10.0.0,
     base >=4.21 && <5,
     bytestring >=0.11,
     containers >=0.6,
@@ -207,15 +207,15 @@
     hasql-transaction >=1.0,
     keiro ^>=0.22.0.0,
     keiro-core ^>=0.22.0.0,
-    kioku-api ^>=0.12.0.0,
-    kioku-core ^>=0.12.0.0,
-    kioku-migrations:test-support ^>=0.12.0.0,
+    kioku-api ^>=0.12.0.1,
+    kioku-core ^>=0.12.0.1,
+    kioku-migrations:test-support ^>=0.12.0.1,
     kiroku-store ^>=0.12.0.0,
     lens >=5.2,
     relay-pagination ^>=0.1.1.2,
     shibuya-core ^>=0.12.0.0,
-    shikumi ^>=0.4.0.0,
-    shikumi-trace ^>=0.3.0.0,
+    shikumi ^>=0.4.1.1,
+    shikumi-trace ^>=0.3.0.2,
     tasty >=1.5,
     tasty-expected-failure >=0.12,
     tasty-hunit >=0.10,
diff --git a/test/Kioku/AIRuntimeSpec.hs b/test/Kioku/AIRuntimeSpec.hs
--- a/test/Kioku/AIRuntimeSpec.hs
+++ b/test/Kioku/AIRuntimeSpec.hs
@@ -1,12 +1,13 @@
 module Kioku.AIRuntimeSpec (tests) where
 
 import Baikai.Api (Api (..))
-import Baikai.Content (AssistantContent (..), emptyTextContent)
+import Baikai.Content (AssistantContent (..), DataContent (..), emptyTextContent)
 import Baikai.Interactive qualified as I
 import Baikai.Model qualified as M
 import Baikai.Options qualified as O
 import Baikai.Provider.Registry qualified as R
 import Baikai.Response (emptyResponse)
+import Baikai.ThinkingLevel (ThinkingLevel (ThinkingNone))
 import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar)
 import Control.Exception (IOException, try)
 import Control.Lens ((&), (.~))
@@ -29,6 +30,7 @@
 import Kioku.Distill.Runtime
 import Kioku.Distill.Scene
 import Shikumi.Schema.Types (field)
+import Shikumi.Trace.ResponseJSON ()
 import System.Exit (ExitCode (..))
 import System.IO (hClose)
 import System.IO.Temp (withSystemTempFile)
@@ -75,6 +77,12 @@
           case refused of
             Left _ -> pure ()
             Right _ -> assertFailure "Responses was authorized without API permission",
+      testCase "explicit reasoning off survives configuration and Shikumi dispatch" $
+        mapM_ testThinkingPreference [Nothing, Just ThinkingNone],
+      testCase "Shikumi response codec preserves structured assistant data" $ do
+        let structured = DataContent (A.object ["answer" A..= ("fixture" :: T.Text)]) (Just (Map.singleton "answer" (Map.singleton "fixture" 0.75))) (Just (Map.singleton "answer" 0.5)) (Just "fixture")
+            response = emptyResponse & #message . #content .~ V.singleton (AssistantData structured)
+        A.eitherDecode (A.encode response) @?= Right response,
       testCase "disabled construction and all features make no calls" $ do
         rt <- expect =<< newAIRuntime noHostCapabilities disabledAIConfig
         mapM_ (\f -> executionAvailability rt f @?= Left (AIDisabled f)) [minBound .. maxBound]
@@ -123,6 +131,30 @@
           )
           [WrongId, Missing, BadDomain, Nonzero, Symlink, Oversized, Cancelled]
     ]
+
+testThinkingPreference :: Maybe ThinkingLevel -> IO ()
+testThinkingPreference preference = do
+  let options = maybe (A.object []) (\p -> A.object ["thinking" A..= p]) preference
+      value =
+        A.object
+          [ "version" A..= (1 :: Int),
+            "distillation"
+              A..= A.object
+                [ "mode" A..= ("api" :: T.Text),
+                  "api" A..= ("fixture" :: T.Text),
+                  "model" A..= ("fixture" :: T.Text),
+                  "provider" A..= ("fixture" :: T.Text),
+                  "baseUrl" A..= ("" :: T.Text),
+                  "options" A..= options
+                ]
+          ]
+      handler = R.apiProviderWith (Custom "fixture") (\_ _ _ -> error "unexpected stream") $ \_ _ opts -> do
+        opts.thinking @?= preference
+        pure (emptyResponse & #message . #content .~ V.singleton (AssistantText (emptyTextContent & #text .~ "[[ ## answer ## ]]\nfixture\n[[ ## completed ## ]]")))
+  (cfg, _) <- expect (parseEither parseAIConfig value)
+  registry <- R.newProviderRegistryFrom [handler]
+  rt <- expect =<< newAIRuntime noHostCapabilities {apiRegistry = Just registry} cfg
+  smoke rt >>= (@?= Right (RuntimeSmokeOutput (field "fixture")))
 
 testBatchOverride :: IO ()
 testBatchOverride = do
