diff --git a/.hlint.yaml b/.hlint.yaml
new file mode 100644
--- /dev/null
+++ b/.hlint.yaml
@@ -0,0 +1,3561 @@
+# himari hlint configuration
+#
+# このファイルはDhallによって自動生成されています。
+# 直接編集しないでください。
+#
+# himariが推奨するスタイルを機械的にチェックするためのhlint設定ファイルです。
+# 部分関数や危険な関数の使用を警告したり、
+# より可読性の高いパターンを提案します。
+#
+# 使い方:
+#   * このファイルをプロジェクトルートに .hlint.yaml としてコピー
+#   * または .hlint.yaml から参照: - arguments: [--hint=path/to/this/.hlint.yaml]
+- group:
+    enabled: true
+    name: generalise
+- group:
+    enabled: true
+    name: dollar
+- group:
+    enabled: true
+    name: "use-lens"
+- group:
+    enabled: true
+    name: "use-th-quotes"
+- functions:
+    - message: Discards error info. Use eitherDecode instead to get error messages.
+      name: Data.Aeson.decode
+      within: []
+    - message: Discards error info. Use eitherDecodeStrict instead to get error messages.
+      name: Data.Aeson.decodeStrict
+      within: []
+    - message: Discards error info. Use eitherDecodeFileStrict instead to get error messages.
+      name: Data.Aeson.decodeFileStrict
+      within: []
+    - message: Discards error info. Use eitherDecodeStrictText instead to get error messages.
+      name: Data.Aeson.decodeStrictText
+      within: []
+- functions:
+    - message: Deprecated alias since aeson 2.2.0.0. Use eitherDecode instead.
+      name: "Data.Aeson.decode'"
+      within: []
+    - message: Deprecated alias since aeson 2.2.0.0. Use eitherDecodeStrict instead.
+      name: "Data.Aeson.decodeStrict'"
+      within: []
+    - message: Deprecated alias since aeson 2.2.0.0. Use eitherDecodeFileStrict instead.
+      name: "Data.Aeson.decodeFileStrict'"
+      within: []
+- functions:
+    - message: Deprecated alias since aeson 2.2.0.0. Use eitherDecode instead.
+      name: "Data.Aeson.eitherDecode'"
+      within: []
+    - message: Deprecated alias since aeson 2.2.0.0. Use eitherDecodeStrict instead.
+      name: "Data.Aeson.eitherDecodeStrict'"
+      within: []
+    - message: Deprecated alias since aeson 2.2.0.0. Use eitherDecodeFileStrict instead.
+      name: "Data.Aeson.eitherDecodeFileStrict'"
+      within: []
+- functions:
+    - message: Deprecated alias since aeson 2.2.0.0. Use throwDecode instead.
+      name: "Data.Aeson.throwDecode'"
+      within: []
+    - message: Deprecated alias since aeson 2.2.0.0. Use throwDecodeStrict instead.
+      name: "Data.Aeson.throwDecodeStrict'"
+      within: []
+- functions:
+    - message: Discards error info. Use parseEither instead to get error messages.
+      name: Data.Aeson.parseMaybe
+      within: []
+    - message: Discards error info. Use parseEither instead to get error messages.
+      name: Data.Aeson.Types.parseMaybe
+      within: []
+    - message: Discards error info. Use parseEither instead to get error messages.
+      name: Data.Aeson.Types.Internal.parseMaybe
+      within: []
+- modules:
+    - message: Unsafe ST operations. Use Control.Monad.ST instead.
+      name: Control.Monad.ST.Unsafe
+      within: []
+    - message: Unsafe lazy ST operations. Use Control.Monad.ST.Lazy instead.
+      name: Control.Monad.ST.Lazy.Unsafe
+      within: []
+- functions:
+    - message: Deprecated and partial. Use bitSizeMaybe or finiteBitSize instead.
+      name: Data.Bits.bitSize
+      within: []
+    - message: Undefined for negative or overflow shift.
+      name: Data.Bits.unsafeShiftL
+      within: []
+    - message: Undefined for negative or overflow shift.
+      name: Data.Bits.unsafeShiftR
+      within: []
+    - message: Undefined for negative rotation.
+      name: Data.Bits.rotateL
+      within: []
+    - message: Undefined for negative rotation.
+      name: Data.Bits.rotateR
+      within: []
+- functions:
+    - message: Use Data.ByteString.uncons instead
+      name: Data.ByteString.head
+      within: []
+    - message: Use Data.ByteString.uncons instead
+      name: Data.ByteString.tail
+      within: []
+    - message: Use Data.ByteString.unsnoc instead
+      name: Data.ByteString.init
+      within: []
+    - message: Use Data.ByteString.unsnoc instead
+      name: Data.ByteString.last
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl with explicit initial value."
+      name: Data.ByteString.foldl1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl' with explicit initial value."
+      name: "Data.ByteString.foldl1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr with explicit initial value."
+      name: Data.ByteString.foldr1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr' with explicit initial value."
+      name: "Data.ByteString.foldr1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.maximum
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.minimum
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.ByteString.indexMaybe or Data.ByteString.(!?) instead"
+      name: Data.ByteString.index
+      within: []
+- functions:
+    - message: Use Data.ByteString.Char8.uncons instead
+      name: Data.ByteString.Char8.head
+      within: []
+    - message: Use Data.ByteString.Char8.uncons instead
+      name: Data.ByteString.Char8.tail
+      within: []
+    - message: Use Data.ByteString.Char8.unsnoc instead
+      name: Data.ByteString.Char8.init
+      within: []
+    - message: Use Data.ByteString.Char8.unsnoc instead
+      name: Data.ByteString.Char8.last
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl with explicit initial value."
+      name: Data.ByteString.Char8.foldl1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl' with explicit initial value."
+      name: "Data.ByteString.Char8.foldl1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr with explicit initial value."
+      name: Data.ByteString.Char8.foldr1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr' with explicit initial value."
+      name: "Data.ByteString.Char8.foldr1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.Char8.maximum
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.Char8.minimum
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.ByteString.Char8.indexMaybe or Data.ByteString.Char8.(!?) instead"
+      name: Data.ByteString.Char8.index
+      within: []
+- functions:
+    - message: Use Data.ByteString.Lazy.uncons instead
+      name: Data.ByteString.Lazy.head
+      within: []
+    - message: Use Data.ByteString.Lazy.uncons instead
+      name: Data.ByteString.Lazy.tail
+      within: []
+    - message: Use Data.ByteString.Lazy.unsnoc instead
+      name: Data.ByteString.Lazy.init
+      within: []
+    - message: Use Data.ByteString.Lazy.unsnoc instead
+      name: Data.ByteString.Lazy.last
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl with explicit initial value."
+      name: Data.ByteString.Lazy.foldl1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl' with explicit initial value."
+      name: "Data.ByteString.Lazy.foldl1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr with explicit initial value."
+      name: Data.ByteString.Lazy.foldr1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr' with explicit initial value."
+      name: "Data.ByteString.Lazy.foldr1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.Lazy.maximum
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.Lazy.minimum
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.ByteString.Lazy.indexMaybe or Data.ByteString.Lazy.(!?) instead"
+      name: Data.ByteString.Lazy.index
+      within: []
+    - message: "Partial: throws on empty ByteString."
+      name: Data.ByteString.Lazy.cycle
+      within: []
+- functions:
+    - message: Use Data.ByteString.Lazy.Char8.uncons instead
+      name: Data.ByteString.Lazy.Char8.head
+      within: []
+    - message: Use Data.ByteString.Lazy.Char8.uncons instead
+      name: Data.ByteString.Lazy.Char8.tail
+      within: []
+    - message: Use Data.ByteString.Lazy.Char8.unsnoc instead
+      name: Data.ByteString.Lazy.Char8.init
+      within: []
+    - message: Use Data.ByteString.Lazy.Char8.unsnoc instead
+      name: Data.ByteString.Lazy.Char8.last
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl with explicit initial value."
+      name: Data.ByteString.Lazy.Char8.foldl1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldl' with explicit initial value."
+      name: "Data.ByteString.Lazy.Char8.foldl1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr with explicit initial value."
+      name: Data.ByteString.Lazy.Char8.foldr1
+      within: []
+    - message: "Partial: throws on empty ByteString. Use foldr' with explicit initial value."
+      name: "Data.ByteString.Lazy.Char8.foldr1'"
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.Lazy.Char8.maximum
+      within: []
+    - message: "Partial: throws on empty ByteString. Use fold with explicit initial value."
+      name: Data.ByteString.Lazy.Char8.minimum
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.ByteString.Lazy.Char8.indexMaybe or Data.ByteString.Lazy.Char8.(!?) instead"
+      name: Data.ByteString.Lazy.Char8.index
+      within: []
+    - message: "Partial: throws on empty ByteString."
+      name: Data.ByteString.Lazy.Char8.cycle
+      within: []
+- functions:
+    - message: Use Data.ByteString.Short.uncons instead
+      name: Data.ByteString.Short.head
+      within: []
+    - message: Use Data.ByteString.Short.uncons instead
+      name: Data.ByteString.Short.tail
+      within: []
+    - message: Use Data.ByteString.Short.unsnoc instead
+      name: Data.ByteString.Short.init
+      within: []
+    - message: Use Data.ByteString.Short.unsnoc instead
+      name: Data.ByteString.Short.last
+      within: []
+    - message: "Partial: throws on empty ShortByteString. Use foldl with explicit initial value."
+      name: Data.ByteString.Short.foldl1
+      within: []
+    - message: "Partial: throws on empty ShortByteString. Use foldl' with explicit initial value."
+      name: "Data.ByteString.Short.foldl1'"
+      within: []
+    - message: "Partial: throws on empty ShortByteString. Use foldr with explicit initial value."
+      name: Data.ByteString.Short.foldr1
+      within: []
+    - message: "Partial: throws on empty ShortByteString. Use foldr' with explicit initial value."
+      name: "Data.ByteString.Short.foldr1'"
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.ByteString.Short.indexMaybe or Data.ByteString.Short.(!?) instead"
+      name: Data.ByteString.Short.index
+      within: []
+- functions:
+    - message: "Unsafe: no bounds check. Use Data.ByteString.uncons instead"
+      name: Data.ByteString.Unsafe.unsafeHead
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.ByteString.uncons instead"
+      name: Data.ByteString.Unsafe.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.ByteString.unsnoc instead"
+      name: Data.ByteString.Unsafe.unsafeInit
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.ByteString.unsnoc instead"
+      name: Data.ByteString.Unsafe.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.ByteString.indexMaybe instead"
+      name: Data.ByteString.Unsafe.unsafeIndex
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.ByteString.take instead"
+      name: Data.ByteString.Unsafe.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.ByteString.drop instead"
+      name: Data.ByteString.Unsafe.unsafeDrop
+      within: []
+- functions:
+    - message: "Partial: throws on non-hex-digit character. Use digitToIntMay from Himari.Char which returns Maybe."
+      name: Data.Char.digitToInt
+      within: []
+    - message: "Partial: throws on out-of-range (must be 0-15). Use intToDigitMay from Himari.Char which returns Maybe."
+      name: Data.Char.intToDigit
+      within: []
+    - message: "Partial: throws on invalid code point. Use chrMay from Himari.Char which returns Maybe."
+      name: Data.Char.chr
+      within: []
+- functions:
+    - message: "Exceptions don't propagate to parent thread. Use async or withAsync from UnliftIO.Async instead."
+      name: forkIO
+      within: []
+    - message: "Exceptions don't propagate to parent thread. Use asyncBound or withAsyncBound from UnliftIO.Async instead."
+      name: forkOS
+      within: []
+    - message: "Exceptions don't propagate to parent thread. Use asyncOn or withAsyncOn from UnliftIO.Async instead."
+      name: forkOn
+      within: []
+    - message: "Exceptions don't propagate to parent thread. Use asyncWithUnmask or withAsyncWithUnmask from UnliftIO.Async instead."
+      name: forkIOWithUnmask
+      within: []
+    - message: "Deprecated and exceptions don't propagate. Use asyncWithUnmask or withAsyncWithUnmask from UnliftIO.Async instead."
+      name: forkWithUnmask
+      within: []
+    - message: Use withAsync from UnliftIO.Async for automatic cancellation and exception handling.
+      name: forkFinally
+      within: []
+    - message: Prefer structured cancellation with cancel or withAsync from UnliftIO.Async.
+      name: killThread
+      within: []
+    - message: "Almost impossible to use correctly. Consider using typed-process or UnliftIO.Async."
+      name: forkProcess
+      within: []
+- functions:
+    - message: "Use Data.Map.lookup or Data.Map.!? instead"
+      name: "Data.Map.!"
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.lookupMin instead."
+      name: Data.Map.findMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.lookupMax instead."
+      name: Data.Map.findMax
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.Map.lookupMin/lookupMax or check size."
+      name: Data.Map.elemAt
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Map.deleteAt
+      within: []
+    - message: "Partial: throws if key not found. Use Data.Map.lookupIndex instead."
+      name: Data.Map.findIndex
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Map.updateAt
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.minViewWithKey instead."
+      name: Data.Map.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.maxViewWithKey instead."
+      name: Data.Map.deleteFindMax
+      within: []
+- functions:
+    - message: "Use Data.Map.Strict.lookup or Data.Map.Strict.!? instead"
+      name: "Data.Map.Strict.!"
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Strict.lookupMin instead."
+      name: Data.Map.Strict.findMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Strict.lookupMax instead."
+      name: Data.Map.Strict.findMax
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.Map.Strict.lookupMin/lookupMax or check size."
+      name: Data.Map.Strict.elemAt
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Map.Strict.deleteAt
+      within: []
+    - message: "Partial: throws if key not found. Use Data.Map.Strict.lookupIndex instead."
+      name: Data.Map.Strict.findIndex
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Map.Strict.updateAt
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Strict.minViewWithKey instead."
+      name: Data.Map.Strict.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Strict.maxViewWithKey instead."
+      name: Data.Map.Strict.deleteFindMax
+      within: []
+- functions:
+    - message: "Use Data.Map.Lazy.lookup or Data.Map.Lazy.!? instead"
+      name: "Data.Map.Lazy.!"
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Lazy.lookupMin instead."
+      name: Data.Map.Lazy.findMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Lazy.lookupMax instead."
+      name: Data.Map.Lazy.findMax
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.Map.Lazy.lookupMin/lookupMax or check size."
+      name: Data.Map.Lazy.elemAt
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Map.Lazy.deleteAt
+      within: []
+    - message: "Partial: throws if key not found. Use Data.Map.Lazy.lookupIndex instead."
+      name: Data.Map.Lazy.findIndex
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Map.Lazy.updateAt
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Lazy.minViewWithKey instead."
+      name: Data.Map.Lazy.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.Map.Lazy.maxViewWithKey instead."
+      name: Data.Map.Lazy.deleteFindMax
+      within: []
+- functions:
+    - message: "Partial: throws on empty set. Use Data.Set.lookupMin instead."
+      name: Data.Set.findMin
+      within: []
+    - message: "Partial: throws on empty set. Use Data.Set.lookupMax instead."
+      name: Data.Set.findMax
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use Data.Set.lookupMin/lookupMax or check size."
+      name: Data.Set.elemAt
+      within: []
+    - message: "Partial: throws on out-of-bounds. Check size before using."
+      name: Data.Set.deleteAt
+      within: []
+    - message: "Partial: throws if element not found. Use Data.Set.lookupIndex instead."
+      name: Data.Set.findIndex
+      within: []
+    - message: "Partial: throws on empty set. Use Data.Set.minView instead."
+      name: Data.Set.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty set. Use Data.Set.maxView instead."
+      name: Data.Set.deleteFindMax
+      within: []
+- functions:
+    - message: "Use Data.IntMap.lookup or Data.IntMap.!? instead"
+      name: "Data.IntMap.!"
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.lookupMin instead."
+      name: Data.IntMap.findMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.lookupMax instead."
+      name: Data.IntMap.findMax
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.minViewWithKey instead."
+      name: Data.IntMap.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.maxViewWithKey instead."
+      name: Data.IntMap.deleteFindMax
+      within: []
+- functions:
+    - message: "Use Data.IntMap.Strict.lookup or Data.IntMap.Strict.!? instead"
+      name: "Data.IntMap.Strict.!"
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Strict.lookupMin instead."
+      name: Data.IntMap.Strict.findMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Strict.lookupMax instead."
+      name: Data.IntMap.Strict.findMax
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Strict.minViewWithKey instead."
+      name: Data.IntMap.Strict.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Strict.maxViewWithKey instead."
+      name: Data.IntMap.Strict.deleteFindMax
+      within: []
+- functions:
+    - message: "Use Data.IntMap.Lazy.lookup or Data.IntMap.Lazy.!? instead"
+      name: "Data.IntMap.Lazy.!"
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Lazy.lookupMin instead."
+      name: Data.IntMap.Lazy.findMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Lazy.lookupMax instead."
+      name: Data.IntMap.Lazy.findMax
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Lazy.minViewWithKey instead."
+      name: Data.IntMap.Lazy.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty map. Use Data.IntMap.Lazy.maxViewWithKey instead."
+      name: Data.IntMap.Lazy.deleteFindMax
+      within: []
+- functions:
+    - message: "Partial: throws on empty set. Use Data.IntSet.lookupMin instead."
+      name: Data.IntSet.findMin
+      within: []
+    - message: "Partial: throws on empty set. Use Data.IntSet.lookupMax instead."
+      name: Data.IntSet.findMax
+      within: []
+    - message: "Partial: throws on empty set. Use Data.IntSet.minView instead."
+      name: Data.IntSet.deleteFindMin
+      within: []
+    - message: "Partial: throws on empty set. Use Data.IntSet.maxView instead."
+      name: Data.IntSet.deleteFindMax
+      within: []
+- functions:
+    - message: "Partial: throws on out-of-bounds. Use Data.Sequence.lookup or Data.Sequence.!? instead."
+      name: Data.Sequence.index
+      within: []
+    - message: "Partial: throws on empty Seq."
+      name: Data.Sequence.scanl1
+      within: []
+    - message: "Partial: throws on empty Seq."
+      name: Data.Sequence.scanr1
+      within: []
+- hint:
+    lhs: Data.Text.pack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.unpack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.pack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.unpack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.toStrict
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.fromStrict
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Encoding.encodeUtf8
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Encoding.decodeUtf8
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.Encoding.encodeUtf8
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.Encoding.decodeUtf8
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.ByteString.pack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.ByteString.unpack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.ByteString.Lazy.pack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.ByteString.Lazy.unpack
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.ByteString.Lazy.toStrict
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.ByteString.Lazy.fromStrict
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.Builder.fromText
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.Builder.fromLazyText
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.Builder.fromString
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- hint:
+    lhs: Data.Text.Lazy.Builder.toLazyText
+    note: Use convert from Data.Convertible for uniform type conversion
+    rhs: convert
+- functions:
+    - message: "Don't throw in pure code. Use throwM in MonadThrow context."
+      name: throw
+      within: []
+    - message: Use typed exceptions with throwM instead of throwString.
+      name: throwString
+      within: []
+    - message: Use typed exceptions with throwM instead of throwIO.
+      name: throwIO
+      within: []
+    - message: "Avoid in production code. For development placeholders, consider typed holes instead."
+      name: error
+      within: []
+    - message: Remember to implement before release. Consider typed holes for better error messages.
+      name: undefined
+      within: []
+    - message: Use proper error handling
+      name: errorWithoutStackTrace
+      within: []
+- functions:
+    - message: "Partial: throws on empty Fold. Use (^?) instead."
+      name: "Control.Lens.Fold.^?!"
+      within: []
+    - message: "Partial: throws on empty Fold. Use (^@?) instead."
+      name: "Control.Lens.Fold.^@?!"
+      within: []
+    - message: "Partial: throws on 0 or >1 elements. Consider using (^?) or ensure exactly 1 element."
+      name: Control.Lens.Traversal.singular
+      within: []
+    - message: "Partial: throws on 0 or >1 elements."
+      name: Control.Lens.Traversal.unsafeSingular
+      within: []
+    - message: "Unsafe: may throw if list length changes."
+      name: Control.Lens.Traversal.unsafePartsOf
+      within: []
+    - message: "Unsafe: may throw if list length changes."
+      name: Control.Lens.Traversal.iunsafePartsOf
+      within: []
+- functions:
+    - message: "Unsound: violates lens laws unless lenses are disjoint. Use alongside instead."
+      name: Control.Lens.Unsound.lensProduct
+      within: []
+    - message: "Unsound: violates prism laws. Use without instead."
+      name: Control.Lens.Unsound.prismSum
+      within: []
+    - message: "Unsound: violates traversal laws unless traversals are disjoint. Use failing instead."
+      name: Control.Lens.Unsound.adjoin
+      within: []
+- modules:
+    - message: Replace with Control.Monad.Writer.CPS to avoid space leaks.
+      name: Control.Monad.Writer
+      within: []
+    - message: Replace with Control.Monad.Writer.CPS to avoid space leaks.
+      name: Control.Monad.Writer.Lazy
+      within: []
+    - message: Replace with Control.Monad.Writer.CPS to avoid space leaks.
+      name: Control.Monad.Writer.Strict
+      within: []
+    - message: Replace with Control.Monad.RWS.CPS to avoid space leaks.
+      name: Control.Monad.RWS
+      within: []
+    - message: Replace with Control.Monad.RWS.CPS to avoid space leaks.
+      name: Control.Monad.RWS.Lazy
+      within: []
+    - message: Replace with Control.Monad.RWS.CPS to avoid space leaks.
+      name: Control.Monad.RWS.Strict
+      within: []
+- modules:
+    - message: "Ambiguous: Use Control.Monad.State.Lazy or Control.Monad.State.Strict explicitly."
+      name: Control.Monad.State
+      within: []
+    - message: "Redirect: Import Control.Monad.Trans.Class or Control.Monad.IO.Class directly."
+      name: Control.Monad.Trans
+      within: []
+    - message: "Redirect: Import Data.Functor.Identity directly."
+      name: Control.Monad.Identity
+      within: []
+- functions:
+    - message: "O(n^2) complexity. Use ordNub or nubOrd instead."
+      name: nub
+      within: []
+    - message: "Lazy accumulator causes space leaks. Use foldl' instead."
+      name: foldl
+      within: []
+    - message: "O(n) stack space. Use length with explicit conversion."
+      name: genericLength
+      within: []
+- hint:
+    lhs: trace
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTrace
+- hint:
+    lhs: traceId
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceId
+- hint:
+    lhs: traceShow
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceShow
+- hint:
+    lhs: traceShowId
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceShowId
+- hint:
+    lhs: traceWith
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceWith
+- hint:
+    lhs: traceShowWith
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceShowWith
+- hint:
+    lhs: traceStack
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceStack
+- hint:
+    lhs: traceIO
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceIO
+- hint:
+    lhs: traceM
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceM
+- hint:
+    lhs: traceShowM
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceShowM
+- hint:
+    lhs: traceEvent
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceEvent
+- hint:
+    lhs: traceEventIO
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceEventIO
+- hint:
+    lhs: traceMarker
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceMarker
+- hint:
+    lhs: traceMarkerIO
+    note: "pTrace* provides pretty-printed output for easier debugging"
+    rhs: pTraceMarkerIO
+- functions:
+    - message: Unsafe primitive state token conversion. Use safe alternatives.
+      name: unsafePrimToPrim
+      within: []
+    - message: Unsafe freeze without copying. Use freezeArray for safety.
+      name: unsafeFreezeArray
+      within: []
+    - message: Unsafe thaw without copying. Use thawArray for safety.
+      name: unsafeThawArray
+      within: []
+    - message: Unsafe freeze without copying. Use freezeByteArray for safety.
+      name: unsafeFreezeByteArray
+      within: []
+    - message: Unsafe thaw without copying. Use thawByteArray for safety.
+      name: unsafeThawByteArray
+      within: []
+    - message: Unsafe freeze without copying. Use freezeSmallArray for safety.
+      name: unsafeFreezeSmallArray
+      within: []
+    - message: Unsafe thaw without copying. Use thawSmallArray for safety.
+      name: unsafeThawSmallArray
+      within: []
+    - message: Unsafe freeze without copying. Use freezePrimArray for safety.
+      name: unsafeFreezePrimArray
+      within: []
+    - message: Unsafe thaw without copying. Use thawPrimArray for safety.
+      name: unsafeThawPrimArray
+      within: []
+- modules:
+    - as: B
+      importStyle: explicitOrQualified
+      name: Data.ByteString
+    - as: B8
+      importStyle: explicitOrQualified
+      name: Data.ByteString.Char8
+    - as: BL
+      importStyle: explicitOrQualified
+      name: Data.ByteString.Lazy
+    - as: BL8
+      importStyle: explicitOrQualified
+      name: Data.ByteString.Lazy.Char8
+    - as: T
+      importStyle: explicitOrQualified
+      name: Data.Text
+    - as: TL
+      importStyle: explicitOrQualified
+      name: Data.Text.Lazy
+    - message: "Data.Map is a re-export of Data.Map.Lazy. Use Data.Map.Strict or Data.Map.Lazy directly."
+      name: Data.Map
+      within: []
+    - as: Map
+      importStyle: explicitOrQualified
+      name: Data.Map.Strict
+    - as: MapL
+      importStyle: explicitOrQualified
+      name: Data.Map.Lazy
+    - message: "Data.IntMap is a re-export of Data.IntMap.Lazy. Use Data.IntMap.Strict or Data.IntMap.Lazy directly."
+      name: Data.IntMap
+      within: []
+    - as: IntMap
+      importStyle: explicitOrQualified
+      name: Data.IntMap.Strict
+    - as: IntMapL
+      importStyle: explicitOrQualified
+      name: Data.IntMap.Lazy
+    - as: Set
+      importStyle: explicitOrQualified
+      name: Data.Set
+    - as: Seq
+      importStyle: explicitOrQualified
+      name: Data.Sequence
+    - as: IntSet
+      importStyle: explicitOrQualified
+      name: Data.IntSet
+    - as: HM
+      importStyle: explicitOrQualified
+      name: Data.HashMap.Strict
+    - as: HML
+      importStyle: explicitOrQualified
+      name: Data.HashMap.Lazy
+    - as: HS
+      importStyle: explicitOrQualified
+      name: Data.HashSet
+    - as: L
+      importStyle: explicitOrQualified
+      name: Data.List
+    - as: NE
+      importStyle: explicitOrQualified
+      name: Data.List.NonEmpty
+    - as: C
+      importStyle: explicitOrQualified
+      name: Data.Char
+    - as: Key
+      importStyle: explicitOrQualified
+      name: Data.Aeson.Key
+    - as: KeyMap
+      importStyle: explicitOrQualified
+      name: Data.Aeson.KeyMap
+    - as: V
+      importStyle: explicitOrQualified
+      name: Data.Vector
+    - as: VG
+      importStyle: explicitOrQualified
+      name: Data.Vector.Generic
+    - as: VS
+      importStyle: explicitOrQualified
+      name: Data.Vector.Storable
+    - as: VU
+      importStyle: explicitOrQualified
+      name: Data.Vector.Unboxed
+- functions:
+    - message: "Partial: throws on maxBound. Use succMay, succDef, or succSafe from Safe instead."
+      name: succ
+      within: []
+    - message: "Partial: throws on minBound. Use predMay, predDef, or predSafe from Safe instead."
+      name: pred
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use toEnumMay, toEnumDef, or toEnumSafe from Safe instead."
+      name: toEnum
+      within: []
+- functions:
+    - message: "Partial: throws on empty list. Use headMay or headDef from Safe instead."
+      name: Data.List.head
+      within: []
+    - message: "Partial: throws on empty list. Use tailMay, tailDef, or tailSafe from Safe instead."
+      name: Data.List.tail
+      within: []
+    - message: "Partial: throws on empty list. Use initMay, initDef, or initSafe from Safe instead."
+      name: Data.List.init
+      within: []
+    - message: "Partial: throws on empty list. Use lastMay or lastDef from Safe instead."
+      name: Data.List.last
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use atMay or atDef from Safe instead."
+      name: "Data.List.!!"
+      within: []
+    - message: "Partial: throws on empty list. Use cycleMay or cycleDef from Safe instead."
+      name: Data.List.cycle
+      within: []
+    - message: "Partial: throws on empty list. Use scanl1May or scanl1Def from Safe instead."
+      name: Data.List.scanl1
+      within: []
+    - message: "Partial: throws on empty list. Use scanr1May or scanr1Def from Safe instead."
+      name: Data.List.scanr1
+      within: []
+    - message: "Partial: throws on empty list. Use foldl1May from Safe instead."
+      name: Data.List.foldl1
+      within: []
+    - message: "Partial: throws on empty list. Use foldl1May' from Safe instead."
+      name: "Data.List.foldl1'"
+      within: []
+    - message: "Partial: throws on empty list. Use foldr1May from Safe instead."
+      name: Data.List.foldr1
+      within: []
+    - message: "Partial: throws on empty list. Use maximumMay or maximumBound from Safe instead."
+      name: Data.List.maximum
+      within: []
+    - message: "Partial: throws on empty list. Use minimumMay or minimumBound from Safe instead."
+      name: Data.List.minimum
+      within: []
+    - message: "Partial: throws on empty list. Use maximumByMay or maximumBoundBy from Safe instead."
+      name: Data.List.maximumBy
+      within: []
+    - message: "Partial: throws on empty list. Use minimumByMay or minimumBoundBy from Safe instead."
+      name: Data.List.minimumBy
+      within: []
+- functions:
+    - message: "Partial: throws on Nothing. Use fromMaybe or pattern match instead."
+      name: Data.Maybe.fromJust
+      within: []
+- functions:
+    - message: "Partial: throws on parse failure. Use readMay or readDef from Safe instead."
+      name: read
+      within: []
+- functions:
+    - message: "Partial: throws on empty structure. Use foldl1May from Safe.Foldable instead."
+      name: Data.Foldable.foldl1
+      within: []
+    - message: "Partial: throws on empty structure. Use foldr1May from Safe.Foldable instead."
+      name: Data.Foldable.foldr1
+      within: []
+    - message: "Partial: throws on empty structure. Use maximumMay or maximumBound from Safe.Foldable instead."
+      name: Data.Foldable.maximum
+      within: []
+    - message: "Partial: throws on empty structure. Use minimumMay or minimumBound from Safe.Foldable instead."
+      name: Data.Foldable.minimum
+      within: []
+    - message: "Partial: throws on empty structure. Use maximumByMay or maximumBoundBy from Safe.Foldable instead."
+      name: Data.Foldable.maximumBy
+      within: []
+    - message: "Partial: throws on empty structure. Use minimumByMay or minimumBoundBy from Safe.Foldable instead."
+      name: Data.Foldable.minimumBy
+      within: []
+- functions:
+    - message: "Partial: throws on empty structure. Use bifoldl with a default value instead."
+      name: Data.Bifoldable.bifoldl1
+      within: []
+    - message: "Partial: throws on empty structure. Use bifoldr with a default value instead."
+      name: Data.Bifoldable.bifoldr1
+      within: []
+    - message: "Partial: throws on empty structure. Use bifoldr with explicit initial value."
+      name: Data.Bifoldable.bimaximum
+      within: []
+    - message: "Partial: throws on empty structure. Use bifoldr with explicit initial value."
+      name: Data.Bifoldable.biminimum
+      within: []
+    - message: "Partial: throws on empty structure. Use bifoldr with explicit initial value."
+      name: Data.Bifoldable.bimaximumBy
+      within: []
+    - message: "Partial: throws on empty structure. Use bifoldr with explicit initial value."
+      name: Data.Bifoldable.biminimumBy
+      within: []
+- functions:
+    - message: "Partial: throws on out-of-bounds. Use atMay or atDef from Safe with toList instead."
+      name: "Data.List.NonEmpty.!!"
+      within: []
+    - message: "Partial: throws on empty list. Use nonEmpty instead."
+      name: Data.List.NonEmpty.fromList
+      within: []
+- functions:
+    - message: "Partial: throws on out-of-range. Use indexMay or indexDef from Safe instead."
+      name: Data.Ix.index
+      within: []
+- functions:
+    - message: "Partial: synonym for error. Use throwM or Left instead."
+      name: Safe.abort
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use atMay or atDef instead."
+      name: Safe.at
+      within: []
+    - message: "Partial: throws on empty list. Use headMay or headDef instead."
+      name: Safe.headErr
+      within: []
+    - message: "Partial: throws on empty list. Use tailMay or tailDef instead."
+      name: Safe.tailErr
+      within: []
+    - message: "Partial: throws on missing key. Use lookup or lookupJustDef instead."
+      name: Safe.lookupJust
+      within: []
+    - message: "Partial: throws when not found. Use find or findJustDef instead."
+      name: Safe.findJust
+      within: []
+    - message: "Partial: throws when not found. Use elemIndex or elemIndexJustDef instead."
+      name: Safe.elemIndexJust
+      within: []
+    - message: "Partial: throws when not found. Use findIndex or findIndexJustDef instead."
+      name: Safe.findIndexJust
+      within: []
+- functions:
+    - message: "Partial: throws on empty list. Use tailMay or tailDef instead."
+      name: Safe.tailNote
+      within: []
+    - message: "Partial: throws on empty list. Use initMay or initDef instead."
+      name: Safe.initNote
+      within: []
+    - message: "Partial: throws on empty list. Use headMay or headDef instead."
+      name: Safe.headNote
+      within: []
+    - message: "Partial: throws on empty list. Use lastMay or lastDef instead."
+      name: Safe.lastNote
+      within: []
+    - message: "Partial: throws on empty list. Use minimumMay or minimumBound instead."
+      name: Safe.minimumNote
+      within: []
+    - message: "Partial: throws on empty list. Use maximumMay or maximumBound instead."
+      name: Safe.maximumNote
+      within: []
+    - message: "Partial: throws on empty list. Use minimumByMay or minimumBoundBy instead."
+      name: Safe.minimumByNote
+      within: []
+    - message: "Partial: throws on empty list. Use maximumByMay or maximumBoundBy instead."
+      name: Safe.maximumByNote
+      within: []
+    - message: "Partial: throws on empty list. Use foldr1May instead."
+      name: Safe.foldr1Note
+      within: []
+    - message: "Partial: throws on empty list. Use foldl1May instead."
+      name: Safe.foldl1Note
+      within: []
+    - message: "Partial: throws on empty list. Use foldl1May' instead."
+      name: "Safe.foldl1Note'"
+      within: []
+    - message: "Partial: throws on empty list. Use scanr1May or scanr1Def instead."
+      name: Safe.scanr1Note
+      within: []
+    - message: "Partial: throws on empty list. Use scanl1May or scanl1Def instead."
+      name: Safe.scanl1Note
+      within: []
+    - message: "Partial: throws on empty list. Use cycleMay or cycleDef instead."
+      name: Safe.cycleNote
+      within: []
+    - message: "Partial: throws on Nothing. Use fromMaybe instead."
+      name: Safe.fromJustNote
+      within: []
+    - message: "Partial: throws on False. Use guard or when instead."
+      name: Safe.assertNote
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use atMay or atDef instead."
+      name: Safe.atNote
+      within: []
+    - message: "Partial: throws on parse failure. Use readMay or readDef instead."
+      name: Safe.readNote
+      within: []
+    - message: "Partial: throws on missing key. Use lookup or lookupJustDef instead."
+      name: Safe.lookupJustNote
+      within: []
+    - message: "Partial: throws when not found. Use find or findJustDef instead."
+      name: Safe.findJustNote
+      within: []
+    - message: "Partial: throws when not found. Use elemIndex or elemIndexJustDef instead."
+      name: Safe.elemIndexJustNote
+      within: []
+    - message: "Partial: throws when not found. Use findIndex or findIndexJustDef instead."
+      name: Safe.findIndexJustNote
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use toEnumMay or toEnumDef instead."
+      name: Safe.toEnumNote
+      within: []
+    - message: "Partial: throws on maxBound. Use succMay or succDef instead."
+      name: Safe.succNote
+      within: []
+    - message: "Partial: throws on minBound. Use predMay or predDef instead."
+      name: Safe.predNote
+      within: []
+    - message: "Partial: throws on out-of-range. Use indexMay or indexDef instead."
+      name: Safe.indexNote
+      within: []
+- functions:
+    - message: "Partial: throws on insufficient elements. Use takeExactMay or takeExactDef instead."
+      name: Safe.Exact.takeExact
+      within: []
+    - message: "Partial: throws on insufficient elements. Use dropExactMay or dropExactDef instead."
+      name: Safe.Exact.dropExact
+      within: []
+    - message: "Partial: throws on insufficient elements. Use splitAtExactMay or splitAtExactDef instead."
+      name: Safe.Exact.splitAtExact
+      within: []
+    - message: "Partial: throws on length mismatch. Use zipExactMay or zipExactDef instead."
+      name: Safe.Exact.zipExact
+      within: []
+    - message: "Partial: throws on length mismatch. Use zipWithExactMay or zipWithExactDef instead."
+      name: Safe.Exact.zipWithExact
+      within: []
+    - message: "Partial: throws on length mismatch. Use zip3ExactMay or zip3ExactDef instead."
+      name: Safe.Exact.zip3Exact
+      within: []
+    - message: "Partial: throws on length mismatch. Use zipWith3ExactMay or zipWith3ExactDef instead."
+      name: Safe.Exact.zipWith3Exact
+      within: []
+    - message: "Partial: throws on insufficient elements. Use takeExactMay or takeExactDef instead."
+      name: Safe.Exact.takeExactNote
+      within: []
+    - message: "Partial: throws on insufficient elements. Use dropExactMay or dropExactDef instead."
+      name: Safe.Exact.dropExactNote
+      within: []
+    - message: "Partial: throws on insufficient elements. Use splitAtExactMay or splitAtExactDef instead."
+      name: Safe.Exact.splitAtExactNote
+      within: []
+    - message: "Partial: throws on length mismatch. Use zipExactMay or zipExactDef instead."
+      name: Safe.Exact.zipExactNote
+      within: []
+    - message: "Partial: throws on length mismatch. Use zipWithExactMay or zipWithExactDef instead."
+      name: Safe.Exact.zipWithExactNote
+      within: []
+    - message: "Partial: throws on length mismatch. Use zip3ExactMay or zip3ExactDef instead."
+      name: Safe.Exact.zip3ExactNote
+      within: []
+    - message: "Partial: throws on length mismatch. Use zipWith3ExactMay or zipWith3ExactDef instead."
+      name: Safe.Exact.zipWith3ExactNote
+      within: []
+- functions:
+    - message: "Partial: throws on empty structure. Use foldl1May instead."
+      name: Safe.Foldable.foldl1Note
+      within: []
+    - message: "Partial: throws on empty structure. Use foldr1May instead."
+      name: Safe.Foldable.foldr1Note
+      within: []
+    - message: "Partial: throws on empty structure. Use minimumMay or minimumBound instead."
+      name: Safe.Foldable.minimumNote
+      within: []
+    - message: "Partial: throws on empty structure. Use maximumMay or maximumBound instead."
+      name: Safe.Foldable.maximumNote
+      within: []
+    - message: "Partial: throws on empty structure. Use minimumByMay or minimumBoundBy instead."
+      name: Safe.Foldable.minimumByNote
+      within: []
+    - message: "Partial: throws on empty structure. Use maximumByMay or maximumBoundBy instead."
+      name: Safe.Foldable.maximumByNote
+      within: []
+    - message: "Partial: throws when not found. Use find or findJustDef instead."
+      name: Safe.Foldable.findJust
+      within: []
+    - message: "Partial: throws when not found. Use find or findJustDef instead."
+      name: Safe.Foldable.findJustNote
+      within: []
+- functions:
+    - message: Encoding depends on LANG env. Use Text or ByteString.
+      name: System.IO.getChar
+      within: []
+    - message: Encoding depends on LANG env. Use Text or ByteString.
+      name: System.IO.getLine
+      within: []
+    - message: "Lazy IO + env-dependent encoding. Use strict Text or ByteString."
+      name: System.IO.getContents
+      within: []
+    - message: "Lazy IO + env-dependent encoding. Use Data.Text.IO.readFile or Data.ByteString.readFile."
+      name: System.IO.readFile
+      within: []
+    - message: "Lazy IO + env-dependent encoding."
+      name: System.IO.interact
+      within: []
+    - message: "Env-dependent + partial (uses read)."
+      name: System.IO.readIO
+      within: []
+    - message: "Env-dependent + partial (uses read)."
+      name: System.IO.readLn
+      within: []
+    - message: Encoding depends on LANG env. Use Text or ByteString.
+      name: System.IO.putChar
+      within: []
+    - message: Encoding depends on LANG env. Use Text or ByteString.
+      name: System.IO.putStr
+      within: []
+    - message: Encoding depends on LANG env. Use Text or ByteString.
+      name: System.IO.putStrLn
+      within: []
+    - message: Encoding depends on LANG env. Use Text or ByteString.
+      name: System.IO.print
+      within: []
+    - message: "Env-dependent encoding. Use Data.Text.IO.writeFile or Data.ByteString.writeFile."
+      name: System.IO.writeFile
+      within: []
+    - message: "Env-dependent encoding. Use Data.Text.IO.appendFile or Data.ByteString.appendFile."
+      name: System.IO.appendFile
+      within: []
+- functions:
+    - message: Use Data.Text.uncons instead
+      name: Data.Text.head
+      within: []
+    - message: Use Data.Text.uncons instead
+      name: Data.Text.tail
+      within: []
+    - message: Use Data.Text.unsnoc instead
+      name: Data.Text.init
+      within: []
+    - message: Use Data.Text.unsnoc instead
+      name: Data.Text.last
+      within: []
+    - message: "Partial: throws on empty Text. Use foldl with explicit initial value."
+      name: Data.Text.foldl1
+      within: []
+    - message: "Partial: throws on empty Text. Use foldl' with explicit initial value."
+      name: "Data.Text.foldl1'"
+      within: []
+    - message: "Partial: throws on empty Text. Use foldr with explicit initial value."
+      name: Data.Text.foldr1
+      within: []
+    - message: "Partial: throws on empty Text. Use fold with explicit initial value."
+      name: Data.Text.maximum
+      within: []
+    - message: "Partial: throws on empty Text. Use fold with explicit initial value."
+      name: Data.Text.minimum
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use safe indexing alternatives."
+      name: Data.Text.index
+      within: []
+- functions:
+    - message: Use Data.Text.Lazy.uncons instead
+      name: Data.Text.Lazy.head
+      within: []
+    - message: Use Data.Text.Lazy.uncons instead
+      name: Data.Text.Lazy.tail
+      within: []
+    - message: Use Data.Text.Lazy.unsnoc instead
+      name: Data.Text.Lazy.init
+      within: []
+    - message: Use Data.Text.Lazy.unsnoc instead
+      name: Data.Text.Lazy.last
+      within: []
+    - message: "Partial: throws on empty Text. Use foldl with explicit initial value."
+      name: Data.Text.Lazy.foldl1
+      within: []
+    - message: "Partial: throws on empty Text. Use foldl' with explicit initial value."
+      name: "Data.Text.Lazy.foldl1'"
+      within: []
+    - message: "Partial: throws on empty Text. Use foldr with explicit initial value."
+      name: Data.Text.Lazy.foldr1
+      within: []
+    - message: "Partial: throws on empty Text. Use fold with explicit initial value."
+      name: Data.Text.Lazy.maximum
+      within: []
+    - message: "Partial: throws on empty Text. Use fold with explicit initial value."
+      name: Data.Text.Lazy.minimum
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use safe indexing alternatives."
+      name: Data.Text.Lazy.index
+      within: []
+    - message: "Partial: throws on empty Text."
+      name: Data.Text.Lazy.cycle
+      within: []
+- functions:
+    - message: "Unsafe: no bounds check. Use Data.Text.uncons instead"
+      name: Data.Text.Unsafe.unsafeHead
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.Text.uncons instead"
+      name: Data.Text.Unsafe.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.Text.take instead"
+      name: Data.Text.Unsafe.takeWord8
+      within: []
+    - message: "Unsafe: no bounds check. Use Data.Text.drop instead"
+      name: Data.Text.Unsafe.dropWord8
+      within: []
+- functions:
+    - message: "Use System.Process.Typed.runProcess_ instead for type-safe process execution."
+      name: System.Process.callProcess
+      within: []
+    - message: "Use System.Process.Typed.runProcess_ with shell instead for type-safe process execution."
+      name: System.Process.callCommand
+      within: []
+    - message: "Use System.Process.Typed.startProcess instead for type-safe process execution."
+      name: System.Process.spawnProcess
+      within: []
+    - message: "Use System.Process.Typed.startProcess with shell instead for type-safe process execution."
+      name: System.Process.spawnCommand
+      within: []
+    - message: "Use System.Process.Typed.startProcess instead for type-safe process execution."
+      name: System.Process.createProcess
+      within: []
+    - message: "Use System.Process.Typed.startProcess instead for type-safe process execution."
+      name: System.Process.createProcess_
+      within: []
+    - message: "Use System.Process.Typed.stopProcess instead for type-safe process cleanup."
+      name: System.Process.cleanupProcess
+      within: []
+    - message: "Use System.Process.Typed.readProcessStdout instead for type-safe output capture."
+      name: System.Process.readProcess
+      within: []
+    - message: "Use System.Process.Typed.readProcess instead for type-safe output capture."
+      name: System.Process.readProcessWithExitCode
+      within: []
+    - message: "Use System.Process.Typed.readProcessStdout instead for type-safe output capture."
+      name: System.Process.readCreateProcess
+      within: []
+    - message: "Use System.Process.Typed.readProcess instead for type-safe output capture."
+      name: System.Process.readCreateProcessWithExitCode
+      within: []
+    - message: Use System.Process.Typed.waitExitCode instead for MonadIO support.
+      name: System.Process.waitForProcess
+      within: []
+    - message: Use System.Process.Typed.getExitCode instead for MonadIO support.
+      name: System.Process.getProcessExitCode
+      within: []
+    - message: Use System.Process.Typed.stopProcess instead for proper cleanup.
+      name: System.Process.terminateProcess
+      within: []
+    - message: Consider using System.Process.Typed with setCreateGroup for process group management.
+      name: System.Process.interruptProcessGroupOf
+      within: []
+    - message: "Use System.Process.Typed.runProcess with shell instead for type-safe process execution."
+      name: System.Process.runCommand
+      within: []
+    - message: "Use System.Process.Typed.runProcess instead for type-safe process execution."
+      name: System.Process.runProcess
+      within: []
+    - message: Use System.Process.Typed.startProcess with shell and createPipe instead.
+      name: System.Process.runInteractiveCommand
+      within: []
+    - message: Use System.Process.Typed.startProcess with createPipe instead.
+      name: System.Process.runInteractiveProcess
+      within: []
+    - message: "Use System.Process.Typed.runProcess with shell instead for type-safe process execution."
+      name: System.Process.system
+      within: []
+    - message: "Use System.Process.Typed.runProcess instead for type-safe process execution."
+      name: System.Process.rawSystem
+      within: []
+    - message: "Use System.Process.Typed.proc instead for type-safe ProcessConfig."
+      name: System.Process.proc
+      within: []
+    - message: "Use System.Process.Typed.shell instead for type-safe ProcessConfig."
+      name: System.Process.shell
+      within: []
+    - message: Use System.Process.Typed.withProcessWait or withProcessTerm instead for MonadUnliftIO support.
+      name: System.Process.withCreateProcess
+      within: []
+    - message: Use System.Process.Typed.withProcessWait_ or withProcessTerm_ instead for MonadUnliftIO support.
+      name: System.Process.withCreateProcess_
+      within: []
+- functions:
+    - message: Use typed exceptions instead. Define a proper exception type.
+      name: UnliftIO.Exception.throwString
+      within: []
+    - message: Use typed exceptions instead. Define a proper exception type.
+      name: UnliftIO.Exception.stringException
+      within: []
+- functions:
+    - message: Use UnliftIO.Async.async instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.async
+      within: []
+    - message: Use UnliftIO.Async.asyncBound instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.asyncBound
+      within: []
+    - message: Use UnliftIO.Async.asyncOn instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.asyncOn
+      within: []
+    - message: Use UnliftIO.Async.asyncWithUnmask instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.asyncWithUnmask
+      within: []
+    - message: Use UnliftIO.Async.withAsync instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.withAsync
+      within: []
+    - message: Use UnliftIO.Async.withAsyncBound instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.withAsyncBound
+      within: []
+    - message: Use UnliftIO.Async.withAsyncOn instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.withAsyncOn
+      within: []
+    - message: Use UnliftIO.Async.withAsyncWithUnmask instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.withAsyncWithUnmask
+      within: []
+    - message: Use UnliftIO.Async.wait instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.wait
+      within: []
+    - message: Use UnliftIO.Async.poll instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.poll
+      within: []
+    - message: Use UnliftIO.Async.waitCatch instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitCatch
+      within: []
+    - message: Use UnliftIO.Async.cancel instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.cancel
+      within: []
+    - message: Use UnliftIO.Async.uninterruptibleCancel instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.uninterruptibleCancel
+      within: []
+    - message: Use UnliftIO.Async.cancelWith instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.cancelWith
+      within: []
+    - message: Use UnliftIO.Async.race instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.race
+      within: []
+    - message: Use UnliftIO.Async.race_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.race_
+      within: []
+    - message: Use UnliftIO.Async.concurrently instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.concurrently
+      within: []
+    - message: Use UnliftIO.Async.concurrently_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.concurrently_
+      within: []
+    - message: Use UnliftIO.Async.mapConcurrently instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.mapConcurrently
+      within: []
+    - message: Use UnliftIO.Async.forConcurrently instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.forConcurrently
+      within: []
+    - message: Use UnliftIO.Async.mapConcurrently_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.mapConcurrently_
+      within: []
+    - message: Use UnliftIO.Async.forConcurrently_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.forConcurrently_
+      within: []
+    - message: Use UnliftIO.Async.replicateConcurrently instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.replicateConcurrently
+      within: []
+    - message: Use UnliftIO.Async.replicateConcurrently_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.replicateConcurrently_
+      within: []
+    - message: Use UnliftIO.Async.waitAny instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitAny
+      within: []
+    - message: Use UnliftIO.Async.waitAnyCatch instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitAnyCatch
+      within: []
+    - message: Use UnliftIO.Async.waitAnyCancel instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitAnyCancel
+      within: []
+    - message: Use UnliftIO.Async.waitAnyCatchCancel instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitAnyCatchCancel
+      within: []
+    - message: Use UnliftIO.Async.waitEither instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitEither
+      within: []
+    - message: Use UnliftIO.Async.waitEitherCatch instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitEitherCatch
+      within: []
+    - message: Use UnliftIO.Async.waitEitherCancel instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitEitherCancel
+      within: []
+    - message: Use UnliftIO.Async.waitEitherCatchCancel instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitEitherCatchCancel
+      within: []
+    - message: Use UnliftIO.Async.waitEither_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitEither_
+      within: []
+    - message: Use UnliftIO.Async.waitBoth instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.waitBoth
+      within: []
+    - message: Use UnliftIO.Async.link instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.link
+      within: []
+    - message: Use UnliftIO.Async.linkOnly instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.linkOnly
+      within: []
+    - message: Use UnliftIO.Async.link2 instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.link2
+      within: []
+    - message: Use UnliftIO.Async.link2Only instead for MonadUnliftIO support.
+      name: Control.Concurrent.Async.link2Only
+      within: []
+- functions:
+    - message: Use UnliftIO.Exception.catch instead for MonadUnliftIO support.
+      name: Control.Exception.catch
+      within: []
+    - message: Use UnliftIO.Exception.catchJust instead for MonadUnliftIO support.
+      name: Control.Exception.catchJust
+      within: []
+    - message: Use UnliftIO.Exception.handle instead for MonadUnliftIO support.
+      name: Control.Exception.handle
+      within: []
+    - message: Use UnliftIO.Exception.handleJust instead for MonadUnliftIO support.
+      name: Control.Exception.handleJust
+      within: []
+    - message: Use UnliftIO.Exception.try instead for MonadUnliftIO support.
+      name: Control.Exception.try
+      within: []
+    - message: Use UnliftIO.Exception.tryJust instead for MonadUnliftIO support.
+      name: Control.Exception.tryJust
+      within: []
+    - message: Use UnliftIO.Exception.bracket instead for MonadUnliftIO support.
+      name: Control.Exception.bracket
+      within: []
+    - message: Use UnliftIO.Exception.bracket_ instead for MonadUnliftIO support.
+      name: Control.Exception.bracket_
+      within: []
+    - message: Use UnliftIO.Exception.bracketOnError instead for MonadUnliftIO support.
+      name: Control.Exception.bracketOnError
+      within: []
+    - message: Use UnliftIO.Exception.finally instead for MonadUnliftIO support.
+      name: Control.Exception.finally
+      within: []
+    - message: Use UnliftIO.Exception.onException instead for MonadUnliftIO support.
+      name: Control.Exception.onException
+      within: []
+    - message: Use UnliftIO.Exception.mask instead for MonadUnliftIO support.
+      name: Control.Exception.mask
+      within: []
+    - message: Use UnliftIO.Exception.mask_ instead for MonadUnliftIO support.
+      name: Control.Exception.mask_
+      within: []
+    - message: Use UnliftIO.Exception.uninterruptibleMask instead for MonadUnliftIO support.
+      name: Control.Exception.uninterruptibleMask
+      within: []
+    - message: Use UnliftIO.Exception.uninterruptibleMask_ instead for MonadUnliftIO support.
+      name: Control.Exception.uninterruptibleMask_
+      within: []
+    - message: Use UnliftIO.Exception.evaluate instead for MonadUnliftIO support.
+      name: Control.Exception.evaluate
+      within: []
+- functions:
+    - message: Use UnliftIO.MVar.withMVar instead for MonadUnliftIO support.
+      name: Control.Concurrent.MVar.withMVar
+      within: []
+    - message: Use UnliftIO.MVar.withMVarMasked instead for MonadUnliftIO support.
+      name: Control.Concurrent.MVar.withMVarMasked
+      within: []
+    - message: Use UnliftIO.MVar.modifyMVar instead for MonadUnliftIO support.
+      name: Control.Concurrent.MVar.modifyMVar
+      within: []
+    - message: Use UnliftIO.MVar.modifyMVar_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.MVar.modifyMVar_
+      within: []
+    - message: Use UnliftIO.MVar.modifyMVarMasked instead for MonadUnliftIO support.
+      name: Control.Concurrent.MVar.modifyMVarMasked
+      within: []
+    - message: Use UnliftIO.MVar.modifyMVarMasked_ instead for MonadUnliftIO support.
+      name: Control.Concurrent.MVar.modifyMVarMasked_
+      within: []
+- functions:
+    - message: Use UnliftIO.Timeout.timeout instead for MonadUnliftIO support.
+      name: System.Timeout.timeout
+      within: []
+- functions:
+    - message: Use UnliftIO.Temporary.withSystemTempFile instead for MonadUnliftIO support.
+      name: System.IO.Temp.withSystemTempFile
+      within: []
+    - message: Use UnliftIO.Temporary.withSystemTempDirectory instead for MonadUnliftIO support.
+      name: System.IO.Temp.withSystemTempDirectory
+      within: []
+    - message: Use UnliftIO.Temporary.withTempFile instead for MonadUnliftIO support.
+      name: System.IO.Temp.withTempFile
+      within: []
+    - message: Use UnliftIO.Temporary.withTempDirectory instead for MonadUnliftIO support.
+      name: System.IO.Temp.withTempDirectory
+      within: []
+- functions:
+    - message: Use UnliftIO.STM.atomically instead for MonadIO support.
+      name: Control.Concurrent.STM.atomically
+      within: []
+    - message: Use UnliftIO.STM.newTVarIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newTVarIO
+      within: []
+    - message: Use UnliftIO.STM.readTVarIO instead for MonadIO support.
+      name: Control.Concurrent.STM.readTVarIO
+      within: []
+    - message: Use UnliftIO.STM.registerDelay instead for MonadIO support.
+      name: Control.Concurrent.STM.registerDelay
+      within: []
+    - message: Use UnliftIO.STM.mkWeakTVar instead for MonadIO support.
+      name: Control.Concurrent.STM.mkWeakTVar
+      within: []
+    - message: Use UnliftIO.STM.newTMVarIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newTMVarIO
+      within: []
+    - message: Use UnliftIO.STM.newEmptyTMVarIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newEmptyTMVarIO
+      within: []
+    - message: Use UnliftIO.STM.mkWeakTMVar instead for MonadIO support.
+      name: Control.Concurrent.STM.mkWeakTMVar
+      within: []
+    - message: Use UnliftIO.STM.newTChanIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newTChanIO
+      within: []
+    - message: Use UnliftIO.STM.newBroadcastTChanIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newBroadcastTChanIO
+      within: []
+    - message: Use UnliftIO.STM.newTQueueIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newTQueueIO
+      within: []
+    - message: Use UnliftIO.STM.newTBQueueIO instead for MonadIO support.
+      name: Control.Concurrent.STM.newTBQueueIO
+      within: []
+- functions:
+    - message: Use UnliftIO.IO.withFile instead for MonadIO support.
+      name: System.IO.withFile
+      within: []
+    - message: Use UnliftIO.IO.withBinaryFile instead for MonadIO support.
+      name: System.IO.withBinaryFile
+      within: []
+    - message: Use UnliftIO.IO.openFile instead for MonadIO support.
+      name: System.IO.openFile
+      within: []
+    - message: Use UnliftIO.IO.hClose instead for MonadIO support.
+      name: System.IO.hClose
+      within: []
+    - message: Use UnliftIO.IO.hFlush instead for MonadIO support.
+      name: System.IO.hFlush
+      within: []
+    - message: Use UnliftIO.IO.hFileSize instead for MonadIO support.
+      name: System.IO.hFileSize
+      within: []
+    - message: Use UnliftIO.IO.hSetFileSize instead for MonadIO support.
+      name: System.IO.hSetFileSize
+      within: []
+    - message: Use UnliftIO.IO.hIsEOF instead for MonadIO support.
+      name: System.IO.hIsEOF
+      within: []
+    - message: Use UnliftIO.IO.hSetBuffering instead for MonadIO support.
+      name: System.IO.hSetBuffering
+      within: []
+    - message: Use UnliftIO.IO.hGetBuffering instead for MonadIO support.
+      name: System.IO.hGetBuffering
+      within: []
+    - message: Use UnliftIO.IO.hSeek instead for MonadIO support.
+      name: System.IO.hSeek
+      within: []
+    - message: Use UnliftIO.IO.hTell instead for MonadIO support.
+      name: System.IO.hTell
+      within: []
+    - message: Use UnliftIO.IO.hIsOpen instead for MonadIO support.
+      name: System.IO.hIsOpen
+      within: []
+    - message: Use UnliftIO.IO.hIsClosed instead for MonadIO support.
+      name: System.IO.hIsClosed
+      within: []
+    - message: Use UnliftIO.IO.hIsReadable instead for MonadIO support.
+      name: System.IO.hIsReadable
+      within: []
+    - message: Use UnliftIO.IO.hIsWritable instead for MonadIO support.
+      name: System.IO.hIsWritable
+      within: []
+    - message: Use UnliftIO.IO.hIsSeekable instead for MonadIO support.
+      name: System.IO.hIsSeekable
+      within: []
+    - message: Use UnliftIO.IO.hIsTerminalDevice instead for MonadIO support.
+      name: System.IO.hIsTerminalDevice
+      within: []
+    - message: Use UnliftIO.IO.hSetEcho instead for MonadIO support.
+      name: System.IO.hSetEcho
+      within: []
+    - message: Use UnliftIO.IO.hGetEcho instead for MonadIO support.
+      name: System.IO.hGetEcho
+      within: []
+    - message: Use UnliftIO.IO.hWaitForInput instead for MonadIO support.
+      name: System.IO.hWaitForInput
+      within: []
+    - message: Use UnliftIO.IO.hReady instead for MonadIO support.
+      name: System.IO.hReady
+      within: []
+- functions:
+    - message: Use UnliftIO.IORef.newIORef instead for MonadIO support.
+      name: Data.IORef.newIORef
+      within: []
+    - message: Use UnliftIO.IORef.readIORef instead for MonadIO support.
+      name: Data.IORef.readIORef
+      within: []
+    - message: Use UnliftIO.IORef.writeIORef instead for MonadIO support.
+      name: Data.IORef.writeIORef
+      within: []
+    - message: Use UnliftIO.IORef.modifyIORef instead for MonadIO support.
+      name: Data.IORef.modifyIORef
+      within: []
+    - message: "Use UnliftIO.IORef.modifyIORef' instead for MonadIO support."
+      name: "Data.IORef.modifyIORef'"
+      within: []
+    - message: Use UnliftIO.IORef.atomicModifyIORef instead for MonadIO support.
+      name: Data.IORef.atomicModifyIORef
+      within: []
+    - message: "Use UnliftIO.IORef.atomicModifyIORef' instead for MonadIO support."
+      name: "Data.IORef.atomicModifyIORef'"
+      within: []
+    - message: Use UnliftIO.IORef.mkWeakIORef instead for MonadIO support.
+      name: Data.IORef.mkWeakIORef
+      within: []
+- functions:
+    - message: Use UnliftIO.Chan.newChan instead for MonadIO support.
+      name: Control.Concurrent.Chan.newChan
+      within: []
+    - message: Use UnliftIO.Chan.writeChan instead for MonadIO support.
+      name: Control.Concurrent.Chan.writeChan
+      within: []
+    - message: Use UnliftIO.Chan.readChan instead for MonadIO support.
+      name: Control.Concurrent.Chan.readChan
+      within: []
+    - message: Use UnliftIO.Chan.dupChan instead for MonadIO support.
+      name: Control.Concurrent.Chan.dupChan
+      within: []
+    - message: Use UnliftIO.Chan.getChanContents instead for MonadIO support.
+      name: Control.Concurrent.Chan.getChanContents
+      within: []
+    - message: Use UnliftIO.Chan.writeList2Chan instead for MonadIO support.
+      name: Control.Concurrent.Chan.writeList2Chan
+      within: []
+- functions:
+    - message: Use UnliftIO.QSem.newQSem instead for MonadIO support.
+      name: Control.Concurrent.QSem.newQSem
+      within: []
+    - message: Use UnliftIO.QSem.waitQSem instead for MonadIO support.
+      name: Control.Concurrent.QSem.waitQSem
+      within: []
+    - message: Use UnliftIO.QSem.signalQSem instead for MonadIO support.
+      name: Control.Concurrent.QSem.signalQSem
+      within: []
+- functions:
+    - message: Use UnliftIO.QSemN.newQSemN instead for MonadIO support.
+      name: Control.Concurrent.QSemN.newQSemN
+      within: []
+    - message: Use UnliftIO.QSemN.waitQSemN instead for MonadIO support.
+      name: Control.Concurrent.QSemN.waitQSemN
+      within: []
+    - message: Use UnliftIO.QSemN.signalQSemN instead for MonadIO support.
+      name: Control.Concurrent.QSemN.signalQSemN
+      within: []
+- functions:
+    - message: Use UnliftIO.Directory.createDirectory instead for MonadIO support.
+      name: System.Directory.createDirectory
+      within: []
+    - message: Use UnliftIO.Directory.createDirectoryIfMissing instead for MonadIO support.
+      name: System.Directory.createDirectoryIfMissing
+      within: []
+    - message: Use UnliftIO.Directory.createFileLink instead for MonadIO support.
+      name: System.Directory.createFileLink
+      within: []
+    - message: Use UnliftIO.Directory.createDirectoryLink instead for MonadIO support.
+      name: System.Directory.createDirectoryLink
+      within: []
+    - message: Use UnliftIO.Directory.removeDirectoryLink instead for MonadIO support.
+      name: System.Directory.removeDirectoryLink
+      within: []
+    - message: Use UnliftIO.Directory.getSymbolicLinkTarget instead for MonadIO support.
+      name: System.Directory.getSymbolicLinkTarget
+      within: []
+    - message: Use UnliftIO.Directory.removeDirectory instead for MonadIO support.
+      name: System.Directory.removeDirectory
+      within: []
+    - message: Use UnliftIO.Directory.removeDirectoryRecursive instead for MonadIO support.
+      name: System.Directory.removeDirectoryRecursive
+      within: []
+    - message: Use UnliftIO.Directory.removePathForcibly instead for MonadIO support.
+      name: System.Directory.removePathForcibly
+      within: []
+    - message: Use UnliftIO.Directory.renameDirectory instead for MonadIO support.
+      name: System.Directory.renameDirectory
+      within: []
+    - message: Use UnliftIO.Directory.listDirectory instead for MonadIO support.
+      name: System.Directory.listDirectory
+      within: []
+    - message: Use UnliftIO.Directory.getDirectoryContents instead for MonadIO support.
+      name: System.Directory.getDirectoryContents
+      within: []
+    - message: Use UnliftIO.Directory.getCurrentDirectory instead for MonadIO support.
+      name: System.Directory.getCurrentDirectory
+      within: []
+    - message: Use UnliftIO.Directory.setCurrentDirectory instead for MonadIO support.
+      name: System.Directory.setCurrentDirectory
+      within: []
+    - message: Use UnliftIO.Directory.withCurrentDirectory instead for MonadIO support.
+      name: System.Directory.withCurrentDirectory
+      within: []
+    - message: Use UnliftIO.Directory.getHomeDirectory instead for MonadIO support.
+      name: System.Directory.getHomeDirectory
+      within: []
+    - message: Use UnliftIO.Directory.getXdgDirectory instead for MonadIO support.
+      name: System.Directory.getXdgDirectory
+      within: []
+    - message: Use UnliftIO.Directory.getXdgDirectoryList instead for MonadIO support.
+      name: System.Directory.getXdgDirectoryList
+      within: []
+    - message: Use UnliftIO.Directory.getAppUserDataDirectory instead for MonadIO support.
+      name: System.Directory.getAppUserDataDirectory
+      within: []
+    - message: Use UnliftIO.Directory.getUserDocumentsDirectory instead for MonadIO support.
+      name: System.Directory.getUserDocumentsDirectory
+      within: []
+    - message: Use UnliftIO.Directory.getTemporaryDirectory instead for MonadIO support.
+      name: System.Directory.getTemporaryDirectory
+      within: []
+    - message: Use UnliftIO.Directory.removeFile instead for MonadIO support.
+      name: System.Directory.removeFile
+      within: []
+    - message: Use UnliftIO.Directory.renameFile instead for MonadIO support.
+      name: System.Directory.renameFile
+      within: []
+    - message: Use UnliftIO.Directory.renamePath instead for MonadIO support.
+      name: System.Directory.renamePath
+      within: []
+    - message: Use UnliftIO.Directory.copyFile instead for MonadIO support.
+      name: System.Directory.copyFile
+      within: []
+    - message: Use UnliftIO.Directory.copyFileWithMetadata instead for MonadIO support.
+      name: System.Directory.copyFileWithMetadata
+      within: []
+    - message: Use UnliftIO.Directory.canonicalizePath instead for MonadIO support.
+      name: System.Directory.canonicalizePath
+      within: []
+    - message: Use UnliftIO.Directory.makeAbsolute instead for MonadIO support.
+      name: System.Directory.makeAbsolute
+      within: []
+    - message: Use UnliftIO.Directory.makeRelativeToCurrentDirectory instead for MonadIO support.
+      name: System.Directory.makeRelativeToCurrentDirectory
+      within: []
+    - message: Use UnliftIO.Directory.findExecutable instead for MonadIO support.
+      name: System.Directory.findExecutable
+      within: []
+    - message: Use UnliftIO.Directory.findExecutables instead for MonadIO support.
+      name: System.Directory.findExecutables
+      within: []
+    - message: Use UnliftIO.Directory.findExecutablesInDirectories instead for MonadIO support.
+      name: System.Directory.findExecutablesInDirectories
+      within: []
+    - message: Use UnliftIO.Directory.findFile instead for MonadIO support.
+      name: System.Directory.findFile
+      within: []
+    - message: Use UnliftIO.Directory.findFiles instead for MonadIO support.
+      name: System.Directory.findFiles
+      within: []
+    - message: Use UnliftIO.Directory.findFileWith instead for MonadIO support.
+      name: System.Directory.findFileWith
+      within: []
+    - message: Use UnliftIO.Directory.findFilesWith instead for MonadIO support.
+      name: System.Directory.findFilesWith
+      within: []
+    - message: Use UnliftIO.Directory.getFileSize instead for MonadIO support.
+      name: System.Directory.getFileSize
+      within: []
+    - message: Use UnliftIO.Directory.doesPathExist instead for MonadIO support.
+      name: System.Directory.doesPathExist
+      within: []
+    - message: Use UnliftIO.Directory.doesFileExist instead for MonadIO support.
+      name: System.Directory.doesFileExist
+      within: []
+    - message: Use UnliftIO.Directory.doesDirectoryExist instead for MonadIO support.
+      name: System.Directory.doesDirectoryExist
+      within: []
+    - message: Use UnliftIO.Directory.pathIsSymbolicLink instead for MonadIO support.
+      name: System.Directory.pathIsSymbolicLink
+      within: []
+    - message: Use UnliftIO.Directory.getPermissions instead for MonadIO support.
+      name: System.Directory.getPermissions
+      within: []
+    - message: Use UnliftIO.Directory.setPermissions instead for MonadIO support.
+      name: System.Directory.setPermissions
+      within: []
+    - message: Use UnliftIO.Directory.copyPermissions instead for MonadIO support.
+      name: System.Directory.copyPermissions
+      within: []
+    - message: Use UnliftIO.Directory.getAccessTime instead for MonadIO support.
+      name: System.Directory.getAccessTime
+      within: []
+    - message: Use UnliftIO.Directory.getModificationTime instead for MonadIO support.
+      name: System.Directory.getModificationTime
+      within: []
+    - message: Use UnliftIO.Directory.setAccessTime instead for MonadIO support.
+      name: System.Directory.setAccessTime
+      within: []
+    - message: Use UnliftIO.Directory.setModificationTime instead for MonadIO support.
+      name: System.Directory.setModificationTime
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.peekCString instead for MonadIO support.
+      name: Foreign.C.String.peekCString
+      within: []
+    - message: Use UnliftIO.Foreign.peekCStringLen instead for MonadIO support.
+      name: Foreign.C.String.peekCStringLen
+      within: []
+    - message: Use UnliftIO.Foreign.newCString instead for MonadIO support.
+      name: Foreign.C.String.newCString
+      within: []
+    - message: Use UnliftIO.Foreign.newCStringLen instead for MonadIO support.
+      name: Foreign.C.String.newCStringLen
+      within: []
+    - message: Use UnliftIO.Foreign.withCString instead for MonadIO support.
+      name: Foreign.C.String.withCString
+      within: []
+    - message: Use UnliftIO.Foreign.withCStringLen instead for MonadIO support.
+      name: Foreign.C.String.withCStringLen
+      within: []
+    - message: Use UnliftIO.Foreign.peekCAString instead for MonadIO support.
+      name: Foreign.C.String.peekCAString
+      within: []
+    - message: Use UnliftIO.Foreign.peekCAStringLen instead for MonadIO support.
+      name: Foreign.C.String.peekCAStringLen
+      within: []
+    - message: Use UnliftIO.Foreign.newCAString instead for MonadIO support.
+      name: Foreign.C.String.newCAString
+      within: []
+    - message: Use UnliftIO.Foreign.newCAStringLen instead for MonadIO support.
+      name: Foreign.C.String.newCAStringLen
+      within: []
+    - message: Use UnliftIO.Foreign.withCAString instead for MonadIO support.
+      name: Foreign.C.String.withCAString
+      within: []
+    - message: Use UnliftIO.Foreign.withCAStringLen instead for MonadIO support.
+      name: Foreign.C.String.withCAStringLen
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.throwErrno instead for MonadIO support.
+      name: Foreign.C.Error.throwErrno
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIf instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIf
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIf_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIf_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfRetry instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfRetry
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfRetry_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfRetry_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfMinus1 instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfMinus1
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfMinus1_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfMinus1_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfMinus1Retry instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfMinus1Retry
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfMinus1Retry_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfMinus1Retry_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfNull instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfNull
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfNullRetry instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfNullRetry
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfRetryMayBlock instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfRetryMayBlock
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfRetryMayBlock_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfRetryMayBlock_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfMinus1RetryMayBlock instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfMinus1RetryMayBlock
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfMinus1RetryMayBlock_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfMinus1RetryMayBlock_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoIfNullRetryMayBlock instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoIfNullRetryMayBlock
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoPath instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoPath
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoPathIf instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoPathIf
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoPathIf_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoPathIf_
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoPathIfNull instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoPathIfNull
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoPathIfMinus1 instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoPathIfMinus1
+      within: []
+    - message: Use UnliftIO.Foreign.throwErrnoPathIfMinus1_ instead for MonadIO support.
+      name: Foreign.C.Error.throwErrnoPathIfMinus1_
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.peek instead for MonadIO support.
+      name: Foreign.Storable.peek
+      within: []
+    - message: Use UnliftIO.Foreign.poke instead for MonadIO support.
+      name: Foreign.Storable.poke
+      within: []
+    - message: Use UnliftIO.Foreign.peekByteOff instead for MonadIO support.
+      name: Foreign.Storable.peekByteOff
+      within: []
+    - message: Use UnliftIO.Foreign.pokeByteOff instead for MonadIO support.
+      name: Foreign.Storable.pokeByteOff
+      within: []
+    - message: Use UnliftIO.Foreign.peekElemOff instead for MonadIO support.
+      name: Foreign.Storable.peekElemOff
+      within: []
+    - message: Use UnliftIO.Foreign.pokeElemOff instead for MonadIO support.
+      name: Foreign.Storable.pokeElemOff
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.alloca instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.alloca
+      within: []
+    - message: Use UnliftIO.Foreign.allocaBytes instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.allocaBytes
+      within: []
+    - message: Use UnliftIO.Foreign.allocaBytesAligned instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.allocaBytesAligned
+      within: []
+    - message: Use UnliftIO.Foreign.malloc instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.malloc
+      within: []
+    - message: Use UnliftIO.Foreign.mallocBytes instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.mallocBytes
+      within: []
+    - message: Use UnliftIO.Foreign.calloc instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.calloc
+      within: []
+    - message: Use UnliftIO.Foreign.callocBytes instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.callocBytes
+      within: []
+    - message: Use UnliftIO.Foreign.realloc instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.realloc
+      within: []
+    - message: Use UnliftIO.Foreign.reallocBytes instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.reallocBytes
+      within: []
+    - message: Use UnliftIO.Foreign.free instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.free
+      within: []
+    - message: Use UnliftIO.Foreign.finalizerFree instead for MonadIO support.
+      name: Foreign.Marshal.Alloc.finalizerFree
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.peekArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.peekArray
+      within: []
+    - message: Use UnliftIO.Foreign.peekArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.peekArray0
+      within: []
+    - message: Use UnliftIO.Foreign.pokeArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.pokeArray
+      within: []
+    - message: Use UnliftIO.Foreign.pokeArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.pokeArray0
+      within: []
+    - message: Use UnliftIO.Foreign.newArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.newArray
+      within: []
+    - message: Use UnliftIO.Foreign.newArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.newArray0
+      within: []
+    - message: Use UnliftIO.Foreign.withArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.withArray
+      within: []
+    - message: Use UnliftIO.Foreign.withArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.withArray0
+      within: []
+    - message: Use UnliftIO.Foreign.withArrayLen instead for MonadIO support.
+      name: Foreign.Marshal.Array.withArrayLen
+      within: []
+    - message: Use UnliftIO.Foreign.withArrayLen0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.withArrayLen0
+      within: []
+    - message: Use UnliftIO.Foreign.copyArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.copyArray
+      within: []
+    - message: Use UnliftIO.Foreign.moveArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.moveArray
+      within: []
+    - message: Use UnliftIO.Foreign.lengthArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.lengthArray0
+      within: []
+    - message: Use UnliftIO.Foreign.allocaArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.allocaArray
+      within: []
+    - message: Use UnliftIO.Foreign.allocaArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.allocaArray0
+      within: []
+    - message: Use UnliftIO.Foreign.mallocArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.mallocArray
+      within: []
+    - message: Use UnliftIO.Foreign.mallocArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.mallocArray0
+      within: []
+    - message: Use UnliftIO.Foreign.callocArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.callocArray
+      within: []
+    - message: Use UnliftIO.Foreign.callocArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.callocArray0
+      within: []
+    - message: Use UnliftIO.Foreign.reallocArray instead for MonadIO support.
+      name: Foreign.Marshal.Array.reallocArray
+      within: []
+    - message: Use UnliftIO.Foreign.reallocArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Array.reallocArray0
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.with instead for MonadIO support.
+      name: Foreign.Marshal.Utils.with
+      within: []
+    - message: Use UnliftIO.Foreign.new instead for MonadIO support.
+      name: Foreign.Marshal.Utils.new
+      within: []
+    - message: Use UnliftIO.Foreign.fromBool instead for MonadIO support.
+      name: Foreign.Marshal.Utils.fromBool
+      within: []
+    - message: Use UnliftIO.Foreign.toBool instead for MonadIO support.
+      name: Foreign.Marshal.Utils.toBool
+      within: []
+    - message: Use UnliftIO.Foreign.maybeNew instead for MonadIO support.
+      name: Foreign.Marshal.Utils.maybeNew
+      within: []
+    - message: Use UnliftIO.Foreign.maybeWith instead for MonadIO support.
+      name: Foreign.Marshal.Utils.maybeWith
+      within: []
+    - message: Use UnliftIO.Foreign.maybePeek instead for MonadIO support.
+      name: Foreign.Marshal.Utils.maybePeek
+      within: []
+    - message: Use UnliftIO.Foreign.withMany instead for MonadIO support.
+      name: Foreign.Marshal.Utils.withMany
+      within: []
+    - message: Use UnliftIO.Foreign.copyBytes instead for MonadIO support.
+      name: Foreign.Marshal.Utils.copyBytes
+      within: []
+    - message: Use UnliftIO.Foreign.moveBytes instead for MonadIO support.
+      name: Foreign.Marshal.Utils.moveBytes
+      within: []
+    - message: Use UnliftIO.Foreign.fillBytes instead for MonadIO support.
+      name: Foreign.Marshal.Utils.fillBytes
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.withPool instead for MonadIO support.
+      name: Foreign.Marshal.Pool.withPool
+      within: []
+    - message: Use UnliftIO.Foreign.pooledMalloc instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledMalloc
+      within: []
+    - message: Use UnliftIO.Foreign.pooledMallocBytes instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledMallocBytes
+      within: []
+    - message: Use UnliftIO.Foreign.pooledRealloc instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledRealloc
+      within: []
+    - message: Use UnliftIO.Foreign.pooledReallocBytes instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledReallocBytes
+      within: []
+    - message: Use UnliftIO.Foreign.pooledMallocArray instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledMallocArray
+      within: []
+    - message: Use UnliftIO.Foreign.pooledMallocArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledMallocArray0
+      within: []
+    - message: Use UnliftIO.Foreign.pooledReallocArray instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledReallocArray
+      within: []
+    - message: Use UnliftIO.Foreign.pooledReallocArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledReallocArray0
+      within: []
+    - message: Use UnliftIO.Foreign.pooledNew instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledNew
+      within: []
+    - message: Use UnliftIO.Foreign.pooledNewArray instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledNewArray
+      within: []
+    - message: Use UnliftIO.Foreign.pooledNewArray0 instead for MonadIO support.
+      name: Foreign.Marshal.Pool.pooledNewArray0
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.newForeignPtr instead for MonadIO support.
+      name: Foreign.ForeignPtr.newForeignPtr
+      within: []
+    - message: Use UnliftIO.Foreign.newForeignPtr_ instead for MonadIO support.
+      name: Foreign.ForeignPtr.newForeignPtr_
+      within: []
+    - message: Use UnliftIO.Foreign.addForeignPtrFinalizer instead for MonadIO support.
+      name: Foreign.ForeignPtr.addForeignPtrFinalizer
+      within: []
+    - message: Use UnliftIO.Foreign.withForeignPtr instead for MonadIO support.
+      name: Foreign.ForeignPtr.withForeignPtr
+      within: []
+    - message: Use UnliftIO.Foreign.finalizeForeignPtr instead for MonadIO support.
+      name: Foreign.ForeignPtr.finalizeForeignPtr
+      within: []
+    - message: Use UnliftIO.Foreign.touchForeignPtr instead for MonadIO support.
+      name: Foreign.ForeignPtr.touchForeignPtr
+      within: []
+    - message: Use UnliftIO.Foreign.mallocForeignPtr instead for MonadIO support.
+      name: Foreign.ForeignPtr.mallocForeignPtr
+      within: []
+    - message: Use UnliftIO.Foreign.mallocForeignPtrBytes instead for MonadIO support.
+      name: Foreign.ForeignPtr.mallocForeignPtrBytes
+      within: []
+    - message: Use UnliftIO.Foreign.mallocForeignPtrArray instead for MonadIO support.
+      name: Foreign.ForeignPtr.mallocForeignPtrArray
+      within: []
+    - message: Use UnliftIO.Foreign.mallocForeignPtrArray0 instead for MonadIO support.
+      name: Foreign.ForeignPtr.mallocForeignPtrArray0
+      within: []
+    - message: Use UnliftIO.Foreign.newGHCForeignPtr instead for MonadIO support.
+      name: Foreign.ForeignPtr.newGHCForeignPtr
+      within: []
+    - message: Use UnliftIO.Foreign.addGHCForeignPtrFinalizer instead for MonadIO support.
+      name: Foreign.ForeignPtr.addGHCForeignPtrFinalizer
+      within: []
+- functions:
+    - message: Use UnliftIO.Foreign.newStablePtr instead for MonadIO support.
+      name: Foreign.StablePtr.newStablePtr
+      within: []
+    - message: Use UnliftIO.Foreign.deRefStablePtr instead for MonadIO support.
+      name: Foreign.StablePtr.deRefStablePtr
+      within: []
+    - message: Use UnliftIO.Foreign.freeStablePtr instead for MonadIO support.
+      name: Foreign.StablePtr.freeStablePtr
+      within: []
+- functions:
+    - message: "Partial: throws on missing key. Use Data.HashMap.Strict.lookup or Data.HashMap.Strict.!? instead"
+      name: "Data.HashMap.Strict.!"
+      within: []
+- functions:
+    - message: "Partial: throws on missing key. Use Data.HashMap.Lazy.lookup or Data.HashMap.Lazy.!? instead"
+      name: "Data.HashMap.Lazy.!"
+      within: []
+- functions:
+    - message: Breaks type safety. Only for very specific use cases.
+      name: unsafePerformIO
+      within: []
+    - message: Even more dangerous than unsafePerformIO.
+      name: unsafeDupablePerformIO
+      within: []
+    - message: Creates lazy IO. Avoid.
+      name: unsafeInterleaveIO
+      within: []
+    - message: Can cause segfaults. Avoid.
+      name: unsafeCoerce
+      within: []
+    - message: Unsafe version of fixIO. Avoid.
+      name: unsafeFixIO
+      within: []
+- functions:
+    - message: "Partial: throws on out-of-bounds. Use (!?) for safe indexing."
+      name: "Data.Vector.!"
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons or (!?) 0 instead."
+      name: Data.Vector.head
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc or check null first."
+      name: Data.Vector.last
+      within: []
+    - message: "Partial: throws exception on out-of-bounds regardless of Monad (M is for evaluation control, not error handling). Use (!?) for safe indexing."
+      name: Data.Vector.indexM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use uncons or check null first."
+      name: Data.Vector.headM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use unsnoc or check null first."
+      name: Data.Vector.lastM
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc for safe init."
+      name: Data.Vector.init
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons for safe tail."
+      name: Data.Vector.tail
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.//
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.update
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.update_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.accum
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.accumulate
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.accumulate_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.backpermute
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl with explicit initial value."
+      name: Data.Vector.foldl1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl' with explicit initial value."
+      name: "Data.Vector.foldl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr with explicit initial value."
+      name: Data.Vector.foldr1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr' with explicit initial value."
+      name: "Data.Vector.foldr1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.maximum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.maximumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.minimum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.minimumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.minIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.minIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.maxIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.maxIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM with explicit initial value."
+      name: Data.Vector.fold1M
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM' with explicit initial value."
+      name: "Data.Vector.fold1M'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM_ with explicit initial value."
+      name: Data.Vector.fold1M_
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM'_ with explicit initial value."
+      name: "Data.Vector.fold1M'_"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl with explicit initial value."
+      name: Data.Vector.scanl1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl' with explicit initial value."
+      name: "Data.Vector.scanl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr with explicit initial value."
+      name: Data.Vector.scanr1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr' with explicit initial value."
+      name: "Data.Vector.scanr1'"
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use (!?) for safe indexing."
+      name: "Data.Vector.Generic.!"
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Generic.head
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc or check null first."
+      name: Data.Vector.Generic.last
+      within: []
+    - message: "Partial: throws exception on out-of-bounds regardless of Monad (M is for evaluation control, not error handling). Use (!?) for safe indexing."
+      name: Data.Vector.Generic.indexM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use uncons or check null first."
+      name: Data.Vector.Generic.headM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use unsnoc or check null first."
+      name: Data.Vector.Generic.lastM
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc for safe init."
+      name: Data.Vector.Generic.init
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons for safe tail."
+      name: Data.Vector.Generic.tail
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.//
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.update
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.update_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.accum
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.accumulate
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.accumulate_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Generic.backpermute
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl with explicit initial value."
+      name: Data.Vector.Generic.foldl1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl' with explicit initial value."
+      name: "Data.Vector.Generic.foldl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr with explicit initial value."
+      name: Data.Vector.Generic.foldr1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr' with explicit initial value."
+      name: "Data.Vector.Generic.foldr1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Generic.maximum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Generic.maximumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Generic.minimum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Generic.minimumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Generic.minIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Generic.minIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Generic.maxIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Generic.maxIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM with explicit initial value."
+      name: Data.Vector.Generic.fold1M
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM' with explicit initial value."
+      name: "Data.Vector.Generic.fold1M'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM_ with explicit initial value."
+      name: Data.Vector.Generic.fold1M_
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM'_ with explicit initial value."
+      name: "Data.Vector.Generic.fold1M'_"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl with explicit initial value."
+      name: Data.Vector.Generic.scanl1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl' with explicit initial value."
+      name: "Data.Vector.Generic.scanl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr with explicit initial value."
+      name: Data.Vector.Generic.scanr1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr' with explicit initial value."
+      name: "Data.Vector.Generic.scanr1'"
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use (!?) for safe indexing."
+      name: "Data.Vector.Primitive.!"
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Primitive.head
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc or check null first."
+      name: Data.Vector.Primitive.last
+      within: []
+    - message: "Partial: throws exception on out-of-bounds regardless of Monad (M is for evaluation control, not error handling). Use (!?) for safe indexing."
+      name: Data.Vector.Primitive.indexM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use uncons or check null first."
+      name: Data.Vector.Primitive.headM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use unsnoc or check null first."
+      name: Data.Vector.Primitive.lastM
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc for safe init."
+      name: Data.Vector.Primitive.init
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons for safe tail."
+      name: Data.Vector.Primitive.tail
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.//
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.update
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.update_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.accum
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.accumulate
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.accumulate_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Primitive.backpermute
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl with explicit initial value."
+      name: Data.Vector.Primitive.foldl1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl' with explicit initial value."
+      name: "Data.Vector.Primitive.foldl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr with explicit initial value."
+      name: Data.Vector.Primitive.foldr1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr' with explicit initial value."
+      name: "Data.Vector.Primitive.foldr1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Primitive.maximum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Primitive.maximumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Primitive.minimum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Primitive.minimumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Primitive.minIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Primitive.minIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Primitive.maxIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Primitive.maxIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM with explicit initial value."
+      name: Data.Vector.Primitive.fold1M
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM' with explicit initial value."
+      name: "Data.Vector.Primitive.fold1M'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM_ with explicit initial value."
+      name: Data.Vector.Primitive.fold1M_
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM'_ with explicit initial value."
+      name: "Data.Vector.Primitive.fold1M'_"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl with explicit initial value."
+      name: Data.Vector.Primitive.scanl1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl' with explicit initial value."
+      name: "Data.Vector.Primitive.scanl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr with explicit initial value."
+      name: Data.Vector.Primitive.scanr1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr' with explicit initial value."
+      name: "Data.Vector.Primitive.scanr1'"
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use (!?) for safe indexing."
+      name: "Data.Vector.Storable.!"
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Storable.head
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc or check null first."
+      name: Data.Vector.Storable.last
+      within: []
+    - message: "Partial: throws exception on out-of-bounds regardless of Monad (M is for evaluation control, not error handling). Use (!?) for safe indexing."
+      name: Data.Vector.Storable.indexM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use uncons or check null first."
+      name: Data.Vector.Storable.headM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use unsnoc or check null first."
+      name: Data.Vector.Storable.lastM
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc for safe init."
+      name: Data.Vector.Storable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons for safe tail."
+      name: Data.Vector.Storable.tail
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.//
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.update
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.update_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.accum
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.accumulate
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.accumulate_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Storable.backpermute
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl with explicit initial value."
+      name: Data.Vector.Storable.foldl1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl' with explicit initial value."
+      name: "Data.Vector.Storable.foldl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr with explicit initial value."
+      name: Data.Vector.Storable.foldr1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr' with explicit initial value."
+      name: "Data.Vector.Storable.foldr1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Storable.maximum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Storable.maximumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Storable.minimum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Storable.minimumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Storable.minIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Storable.minIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Storable.maxIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Storable.maxIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM with explicit initial value."
+      name: Data.Vector.Storable.fold1M
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM' with explicit initial value."
+      name: "Data.Vector.Storable.fold1M'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM_ with explicit initial value."
+      name: Data.Vector.Storable.fold1M_
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM'_ with explicit initial value."
+      name: "Data.Vector.Storable.fold1M'_"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl with explicit initial value."
+      name: Data.Vector.Storable.scanl1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl' with explicit initial value."
+      name: "Data.Vector.Storable.scanl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr with explicit initial value."
+      name: Data.Vector.Storable.scanr1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr' with explicit initial value."
+      name: "Data.Vector.Storable.scanr1'"
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use (!?) for safe indexing."
+      name: "Data.Vector.Strict.!"
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Strict.head
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc or check null first."
+      name: Data.Vector.Strict.last
+      within: []
+    - message: "Partial: throws exception on out-of-bounds regardless of Monad (M is for evaluation control, not error handling). Use (!?) for safe indexing."
+      name: Data.Vector.Strict.indexM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use uncons or check null first."
+      name: Data.Vector.Strict.headM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use unsnoc or check null first."
+      name: Data.Vector.Strict.lastM
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc for safe init."
+      name: Data.Vector.Strict.init
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons for safe tail."
+      name: Data.Vector.Strict.tail
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.//
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.update
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.update_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.accum
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.accumulate
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.accumulate_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Strict.backpermute
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl with explicit initial value."
+      name: Data.Vector.Strict.foldl1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl' with explicit initial value."
+      name: "Data.Vector.Strict.foldl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr with explicit initial value."
+      name: Data.Vector.Strict.foldr1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr' with explicit initial value."
+      name: "Data.Vector.Strict.foldr1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Strict.maximum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Strict.maximumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Strict.minimum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Strict.minimumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Strict.minIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Strict.minIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Strict.maxIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Strict.maxIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM with explicit initial value."
+      name: Data.Vector.Strict.fold1M
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM' with explicit initial value."
+      name: "Data.Vector.Strict.fold1M'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM_ with explicit initial value."
+      name: Data.Vector.Strict.fold1M_
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM'_ with explicit initial value."
+      name: "Data.Vector.Strict.fold1M'_"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl with explicit initial value."
+      name: Data.Vector.Strict.scanl1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl' with explicit initial value."
+      name: "Data.Vector.Strict.scanl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr with explicit initial value."
+      name: Data.Vector.Strict.scanr1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr' with explicit initial value."
+      name: "Data.Vector.Strict.scanr1'"
+      within: []
+    - message: "Partial: throws on out-of-bounds. Use (!?) for safe indexing."
+      name: "Data.Vector.Unboxed.!"
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Unboxed.head
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc or check null first."
+      name: Data.Vector.Unboxed.last
+      within: []
+    - message: "Partial: throws exception on out-of-bounds regardless of Monad (M is for evaluation control, not error handling). Use (!?) for safe indexing."
+      name: Data.Vector.Unboxed.indexM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use uncons or check null first."
+      name: Data.Vector.Unboxed.headM
+      within: []
+    - message: "Partial: throws exception on empty vector regardless of Monad (M is for evaluation control, not error handling). Use unsnoc or check null first."
+      name: Data.Vector.Unboxed.lastM
+      within: []
+    - message: "Partial: throws on empty vector. Use unsnoc for safe init."
+      name: Data.Vector.Unboxed.init
+      within: []
+    - message: "Partial: throws on empty vector. Use uncons for safe tail."
+      name: Data.Vector.Unboxed.tail
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.//
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.update
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.update_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.accum
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.accumulate
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.accumulate_
+      within: []
+    - message: "Partial: throws on out-of-bounds indices. Validate indices against length, or use modify with bounds checking."
+      name: Data.Vector.Unboxed.backpermute
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl with explicit initial value."
+      name: Data.Vector.Unboxed.foldl1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldl' with explicit initial value."
+      name: "Data.Vector.Unboxed.foldl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr with explicit initial value."
+      name: Data.Vector.Unboxed.foldr1
+      within: []
+    - message: "Partial: throws on empty vector. Use foldr' with explicit initial value."
+      name: "Data.Vector.Unboxed.foldr1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Unboxed.maximum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Unboxed.maximumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Unboxed.minimum
+      within: []
+    - message: "Partial: throws on empty vector. Use fold with explicit initial value."
+      name: Data.Vector.Unboxed.minimumBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Unboxed.minIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Unboxed.minIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Unboxed.maxIndex
+      within: []
+    - message: "Partial: throws on empty vector. Use indexed fold with Maybe result."
+      name: Data.Vector.Unboxed.maxIndexBy
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM with explicit initial value."
+      name: Data.Vector.Unboxed.fold1M
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM' with explicit initial value."
+      name: "Data.Vector.Unboxed.fold1M'"
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM_ with explicit initial value."
+      name: Data.Vector.Unboxed.fold1M_
+      within: []
+    - message: "Partial: throws on empty vector. Use foldM'_ with explicit initial value."
+      name: "Data.Vector.Unboxed.fold1M'_"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl with explicit initial value."
+      name: Data.Vector.Unboxed.scanl1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanl' with explicit initial value."
+      name: "Data.Vector.Unboxed.scanl1'"
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr with explicit initial value."
+      name: Data.Vector.Unboxed.scanr1
+      within: []
+    - message: "Partial: throws on empty vector. Use scanr' with explicit initial value."
+      name: "Data.Vector.Unboxed.scanr1'"
+      within: []
+- functions:
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!) or (!?) instead."
+      name: Data.Vector.unsafeIndex
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.unsafeHead
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!?) instead."
+      name: Data.Vector.unsafeIndexM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.unsafeHeadM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.unsafeLastM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc instead."
+      name: Data.Vector.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons instead."
+      name: Data.Vector.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (//) instead."
+      name: Data.Vector.unsafeUpd
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update instead."
+      name: Data.Vector.unsafeUpdate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update_ instead."
+      name: Data.Vector.unsafeUpdate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum instead."
+      name: Data.Vector.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate instead."
+      name: Data.Vector.unsafeAccumulate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate_ instead."
+      name: Data.Vector.unsafeAccumulate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use backpermute instead."
+      name: Data.Vector.unsafeBackpermute
+      within: []
+    - message: "Unsafe: the mutable vector may not be used after this. Use freeze for safety."
+      name: Data.Vector.unsafeFreeze
+      within: []
+    - message: "Unsafe: the immutable vector may not be used after this. Use thaw for safety."
+      name: Data.Vector.unsafeThaw
+      within: []
+    - message: "Unsafe: no length checking. Use copy for safety."
+      name: Data.Vector.unsafeCopy
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!) or (!?) instead."
+      name: Data.Vector.Generic.unsafeIndex
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Generic.unsafeHead
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Generic.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!?) instead."
+      name: Data.Vector.Generic.unsafeIndexM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Generic.unsafeHeadM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Generic.unsafeLastM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Generic.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc instead."
+      name: Data.Vector.Generic.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons instead."
+      name: Data.Vector.Generic.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Generic.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Generic.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (//) instead."
+      name: Data.Vector.Generic.unsafeUpd
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update instead."
+      name: Data.Vector.Generic.unsafeUpdate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update_ instead."
+      name: Data.Vector.Generic.unsafeUpdate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum instead."
+      name: Data.Vector.Generic.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate instead."
+      name: Data.Vector.Generic.unsafeAccumulate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate_ instead."
+      name: Data.Vector.Generic.unsafeAccumulate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use backpermute instead."
+      name: Data.Vector.Generic.unsafeBackpermute
+      within: []
+    - message: "Unsafe: the mutable vector may not be used after this. Use freeze for safety."
+      name: Data.Vector.Generic.unsafeFreeze
+      within: []
+    - message: "Unsafe: the immutable vector may not be used after this. Use thaw for safety."
+      name: Data.Vector.Generic.unsafeThaw
+      within: []
+    - message: "Unsafe: no length checking. Use copy for safety."
+      name: Data.Vector.Generic.unsafeCopy
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!) or (!?) instead."
+      name: Data.Vector.Primitive.unsafeIndex
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Primitive.unsafeHead
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Primitive.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!?) instead."
+      name: Data.Vector.Primitive.unsafeIndexM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Primitive.unsafeHeadM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Primitive.unsafeLastM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Primitive.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc instead."
+      name: Data.Vector.Primitive.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons instead."
+      name: Data.Vector.Primitive.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Primitive.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Primitive.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (//) instead."
+      name: Data.Vector.Primitive.unsafeUpd
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update instead."
+      name: Data.Vector.Primitive.unsafeUpdate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update_ instead."
+      name: Data.Vector.Primitive.unsafeUpdate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum instead."
+      name: Data.Vector.Primitive.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate instead."
+      name: Data.Vector.Primitive.unsafeAccumulate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate_ instead."
+      name: Data.Vector.Primitive.unsafeAccumulate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use backpermute instead."
+      name: Data.Vector.Primitive.unsafeBackpermute
+      within: []
+    - message: "Unsafe: the mutable vector may not be used after this. Use freeze for safety."
+      name: Data.Vector.Primitive.unsafeFreeze
+      within: []
+    - message: "Unsafe: the immutable vector may not be used after this. Use thaw for safety."
+      name: Data.Vector.Primitive.unsafeThaw
+      within: []
+    - message: "Unsafe: no length checking. Use copy for safety."
+      name: Data.Vector.Primitive.unsafeCopy
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!) or (!?) instead."
+      name: Data.Vector.Storable.unsafeIndex
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Storable.unsafeHead
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Storable.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!?) instead."
+      name: Data.Vector.Storable.unsafeIndexM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Storable.unsafeHeadM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Storable.unsafeLastM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Storable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc instead."
+      name: Data.Vector.Storable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons instead."
+      name: Data.Vector.Storable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Storable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Storable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (//) instead."
+      name: Data.Vector.Storable.unsafeUpd
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update instead."
+      name: Data.Vector.Storable.unsafeUpdate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update_ instead."
+      name: Data.Vector.Storable.unsafeUpdate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum instead."
+      name: Data.Vector.Storable.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate instead."
+      name: Data.Vector.Storable.unsafeAccumulate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate_ instead."
+      name: Data.Vector.Storable.unsafeAccumulate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use backpermute instead."
+      name: Data.Vector.Storable.unsafeBackpermute
+      within: []
+    - message: "Unsafe: the mutable vector may not be used after this. Use freeze for safety."
+      name: Data.Vector.Storable.unsafeFreeze
+      within: []
+    - message: "Unsafe: the immutable vector may not be used after this. Use thaw for safety."
+      name: Data.Vector.Storable.unsafeThaw
+      within: []
+    - message: "Unsafe: no length checking. Use copy for safety."
+      name: Data.Vector.Storable.unsafeCopy
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!) or (!?) instead."
+      name: Data.Vector.Strict.unsafeIndex
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Strict.unsafeHead
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Strict.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!?) instead."
+      name: Data.Vector.Strict.unsafeIndexM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Strict.unsafeHeadM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Strict.unsafeLastM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Strict.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc instead."
+      name: Data.Vector.Strict.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons instead."
+      name: Data.Vector.Strict.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Strict.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Strict.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (//) instead."
+      name: Data.Vector.Strict.unsafeUpd
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update instead."
+      name: Data.Vector.Strict.unsafeUpdate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update_ instead."
+      name: Data.Vector.Strict.unsafeUpdate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum instead."
+      name: Data.Vector.Strict.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate instead."
+      name: Data.Vector.Strict.unsafeAccumulate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate_ instead."
+      name: Data.Vector.Strict.unsafeAccumulate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use backpermute instead."
+      name: Data.Vector.Strict.unsafeBackpermute
+      within: []
+    - message: "Unsafe: the mutable vector may not be used after this. Use freeze for safety."
+      name: Data.Vector.Strict.unsafeFreeze
+      within: []
+    - message: "Unsafe: the immutable vector may not be used after this. Use thaw for safety."
+      name: Data.Vector.Strict.unsafeThaw
+      within: []
+    - message: "Unsafe: no length checking. Use copy for safety."
+      name: Data.Vector.Strict.unsafeCopy
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!) or (!?) instead."
+      name: Data.Vector.Unboxed.unsafeIndex
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Unboxed.unsafeHead
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Unboxed.unsafeLast
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (!?) instead."
+      name: Data.Vector.Unboxed.unsafeIndexM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons or (!?) 0 instead."
+      name: Data.Vector.Unboxed.unsafeHeadM
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc or check null first."
+      name: Data.Vector.Unboxed.unsafeLastM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Unboxed.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use unsnoc instead."
+      name: Data.Vector.Unboxed.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Use uncons instead."
+      name: Data.Vector.Unboxed.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Unboxed.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Unboxed.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use (//) instead."
+      name: Data.Vector.Unboxed.unsafeUpd
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update instead."
+      name: Data.Vector.Unboxed.unsafeUpdate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update_ instead."
+      name: Data.Vector.Unboxed.unsafeUpdate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum instead."
+      name: Data.Vector.Unboxed.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate instead."
+      name: Data.Vector.Unboxed.unsafeAccumulate
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accumulate_ instead."
+      name: Data.Vector.Unboxed.unsafeAccumulate_
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use backpermute instead."
+      name: Data.Vector.Unboxed.unsafeBackpermute
+      within: []
+    - message: "Unsafe: the mutable vector may not be used after this. Use freeze for safety."
+      name: Data.Vector.Unboxed.unsafeFreeze
+      within: []
+    - message: "Unsafe: the immutable vector may not be used after this. Use thaw for safety."
+      name: Data.Vector.Unboxed.unsafeThaw
+      within: []
+    - message: "Unsafe: no length checking. Use copy for safety."
+      name: Data.Vector.Unboxed.unsafeCopy
+      within: []
+- functions:
+    - message: "Partial: throws on empty vector. Use unsafeInit only if you've verified non-empty."
+      name: Data.Vector.Mutable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeTail only if you've verified non-empty."
+      name: Data.Vector.Mutable.tail
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeInit only if you've verified non-empty."
+      name: Data.Vector.Generic.Mutable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeTail only if you've verified non-empty."
+      name: Data.Vector.Generic.Mutable.tail
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeInit only if you've verified non-empty."
+      name: Data.Vector.Primitive.Mutable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeTail only if you've verified non-empty."
+      name: Data.Vector.Primitive.Mutable.tail
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeInit only if you've verified non-empty."
+      name: Data.Vector.Storable.Mutable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeTail only if you've verified non-empty."
+      name: Data.Vector.Storable.Mutable.tail
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeInit only if you've verified non-empty."
+      name: Data.Vector.Strict.Mutable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeTail only if you've verified non-empty."
+      name: Data.Vector.Strict.Mutable.tail
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeInit only if you've verified non-empty."
+      name: Data.Vector.Unboxed.Mutable.init
+      within: []
+    - message: "Partial: throws on empty vector. Use unsafeTail only if you've verified non-empty."
+      name: Data.Vector.Unboxed.Mutable.tail
+      within: []
+- functions:
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Mutable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Mutable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Mutable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Mutable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Mutable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use read instead."
+      name: Data.Vector.Mutable.unsafeRead
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use write instead."
+      name: Data.Vector.Mutable.unsafeWrite
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modify instead."
+      name: Data.Vector.Mutable.unsafeModify
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modifyM instead."
+      name: Data.Vector.Mutable.unsafeModifyM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use swap instead."
+      name: Data.Vector.Mutable.unsafeSwap
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use exchange instead."
+      name: Data.Vector.Mutable.unsafeExchange
+      within: []
+    - message: "Unsafe: no length/overlap checking. Use copy for safety."
+      name: Data.Vector.Mutable.unsafeCopy
+      within: []
+    - message: "Unsafe: no length checking. Use move for safety."
+      name: Data.Vector.Mutable.unsafeMove
+      within: []
+    - message: "Unsafe: no non-negative check. Use grow for safety."
+      name: Data.Vector.Mutable.unsafeGrow
+      within: []
+    - message: "Unsafe: elements are uninitialized and may cause exceptions. Use new or replicate instead."
+      name: Data.Vector.Mutable.unsafeNew
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Generic.Mutable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Generic.Mutable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Generic.Mutable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Generic.Mutable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Generic.Mutable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use read instead."
+      name: Data.Vector.Generic.Mutable.unsafeRead
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use write instead."
+      name: Data.Vector.Generic.Mutable.unsafeWrite
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modify instead."
+      name: Data.Vector.Generic.Mutable.unsafeModify
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modifyM instead."
+      name: Data.Vector.Generic.Mutable.unsafeModifyM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use swap instead."
+      name: Data.Vector.Generic.Mutable.unsafeSwap
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use exchange instead."
+      name: Data.Vector.Generic.Mutable.unsafeExchange
+      within: []
+    - message: "Unsafe: no length/overlap checking. Use copy for safety."
+      name: Data.Vector.Generic.Mutable.unsafeCopy
+      within: []
+    - message: "Unsafe: no length checking. Use move for safety."
+      name: Data.Vector.Generic.Mutable.unsafeMove
+      within: []
+    - message: "Unsafe: no non-negative check. Use grow for safety."
+      name: Data.Vector.Generic.Mutable.unsafeGrow
+      within: []
+    - message: "Unsafe: elements are uninitialized and may cause exceptions. Use new or replicate instead."
+      name: Data.Vector.Generic.Mutable.unsafeNew
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Primitive.Mutable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Primitive.Mutable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Primitive.Mutable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Primitive.Mutable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Primitive.Mutable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use read instead."
+      name: Data.Vector.Primitive.Mutable.unsafeRead
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use write instead."
+      name: Data.Vector.Primitive.Mutable.unsafeWrite
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modify instead."
+      name: Data.Vector.Primitive.Mutable.unsafeModify
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modifyM instead."
+      name: Data.Vector.Primitive.Mutable.unsafeModifyM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use swap instead."
+      name: Data.Vector.Primitive.Mutable.unsafeSwap
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use exchange instead."
+      name: Data.Vector.Primitive.Mutable.unsafeExchange
+      within: []
+    - message: "Unsafe: no length/overlap checking. Use copy for safety."
+      name: Data.Vector.Primitive.Mutable.unsafeCopy
+      within: []
+    - message: "Unsafe: no length checking. Use move for safety."
+      name: Data.Vector.Primitive.Mutable.unsafeMove
+      within: []
+    - message: "Unsafe: no non-negative check. Use grow for safety."
+      name: Data.Vector.Primitive.Mutable.unsafeGrow
+      within: []
+    - message: "Unsafe: elements are uninitialized and may cause exceptions. Use new or replicate instead."
+      name: Data.Vector.Primitive.Mutable.unsafeNew
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Storable.Mutable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Storable.Mutable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Storable.Mutable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Storable.Mutable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Storable.Mutable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use read instead."
+      name: Data.Vector.Storable.Mutable.unsafeRead
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use write instead."
+      name: Data.Vector.Storable.Mutable.unsafeWrite
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modify instead."
+      name: Data.Vector.Storable.Mutable.unsafeModify
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modifyM instead."
+      name: Data.Vector.Storable.Mutable.unsafeModifyM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use swap instead."
+      name: Data.Vector.Storable.Mutable.unsafeSwap
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use exchange instead."
+      name: Data.Vector.Storable.Mutable.unsafeExchange
+      within: []
+    - message: "Unsafe: no length/overlap checking. Use copy for safety."
+      name: Data.Vector.Storable.Mutable.unsafeCopy
+      within: []
+    - message: "Unsafe: no length checking. Use move for safety."
+      name: Data.Vector.Storable.Mutable.unsafeMove
+      within: []
+    - message: "Unsafe: no non-negative check. Use grow for safety."
+      name: Data.Vector.Storable.Mutable.unsafeGrow
+      within: []
+    - message: "Unsafe: elements are uninitialized and may cause exceptions. Use new or replicate instead."
+      name: Data.Vector.Storable.Mutable.unsafeNew
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Strict.Mutable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Strict.Mutable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Strict.Mutable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Strict.Mutable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Strict.Mutable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use read instead."
+      name: Data.Vector.Strict.Mutable.unsafeRead
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use write instead."
+      name: Data.Vector.Strict.Mutable.unsafeWrite
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modify instead."
+      name: Data.Vector.Strict.Mutable.unsafeModify
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modifyM instead."
+      name: Data.Vector.Strict.Mutable.unsafeModifyM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use swap instead."
+      name: Data.Vector.Strict.Mutable.unsafeSwap
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use exchange instead."
+      name: Data.Vector.Strict.Mutable.unsafeExchange
+      within: []
+    - message: "Unsafe: no length/overlap checking. Use copy for safety."
+      name: Data.Vector.Strict.Mutable.unsafeCopy
+      within: []
+    - message: "Unsafe: no length checking. Use move for safety."
+      name: Data.Vector.Strict.Mutable.unsafeMove
+      within: []
+    - message: "Unsafe: no non-negative check. Use grow for safety."
+      name: Data.Vector.Strict.Mutable.unsafeGrow
+      within: []
+    - message: "Unsafe: elements are uninitialized and may cause exceptions. Use new or replicate instead."
+      name: Data.Vector.Strict.Mutable.unsafeNew
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use slice instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeSlice
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Unboxed.Mutable.unsafeInit
+      within: []
+    - message: "Unsafe: no empty check, may cause segfaults. Verify non-empty first."
+      name: Data.Vector.Unboxed.Mutable.unsafeTail
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use take instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeTake
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use drop instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeDrop
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use read instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeRead
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use write instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeWrite
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modify instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeModify
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use modifyM instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeModifyM
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use swap instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeSwap
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use exchange instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeExchange
+      within: []
+    - message: "Unsafe: no length/overlap checking. Use copy for safety."
+      name: Data.Vector.Unboxed.Mutable.unsafeCopy
+      within: []
+    - message: "Unsafe: no length checking. Use move for safety."
+      name: Data.Vector.Unboxed.Mutable.unsafeMove
+      within: []
+    - message: "Unsafe: no non-negative check. Use grow for safety."
+      name: Data.Vector.Unboxed.Mutable.unsafeGrow
+      within: []
+    - message: "Unsafe: elements are uninitialized and may cause exceptions. Use new or replicate instead."
+      name: Data.Vector.Unboxed.Mutable.unsafeNew
+      within: []
+    - message: "Unsafe: no non-negative check. Use growFront for safety."
+      name: Data.Vector.Generic.Mutable.unsafeGrowFront
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use accum for safety."
+      name: Data.Vector.Generic.Mutable.unsafeAccum
+      within: []
+    - message: "Unsafe: no bounds checking, may cause segfaults. Use update for safety."
+      name: Data.Vector.Generic.Mutable.unsafeUpdate
+      within: []
+    - message: "Unsafe: type cast without memory safety guarantees. Ensure correct memory layout."
+      name: Data.Vector.Primitive.Mutable.unsafeCast
+      within: []
+    - message: "Unsafe: coerces vector type without safety checks."
+      name: Data.Vector.Primitive.Mutable.unsafeCoerceMVector
+      within: []
+    - message: "Unsafe: type cast without memory safety guarantees. Ensure correct memory layout."
+      name: Data.Vector.Storable.Mutable.unsafeCast
+      within: []
+    - message: "Unsafe: coerces vector type without safety checks."
+      name: Data.Vector.Storable.Mutable.unsafeCoerceMVector
+      within: []
+    - message: "Unsafe: creates vector from raw pointer without validation."
+      name: Data.Vector.Storable.Mutable.unsafeFromForeignPtr
+      within: []
+    - message: "Unsafe: creates vector from raw pointer without validation."
+      name: Data.Vector.Storable.Mutable.unsafeFromForeignPtr0
+      within: []
+    - message: "Unsafe: extracts raw pointer, vector may not be used safely after."
+      name: Data.Vector.Storable.Mutable.unsafeToForeignPtr
+      within: []
+    - message: "Unsafe: extracts raw pointer, vector may not be used safely after."
+      name: Data.Vector.Storable.Mutable.unsafeToForeignPtr0
+      within: []
+    - message: "Unsafe: passes raw pointer to IO action without safety guarantees."
+      name: Data.Vector.Storable.Mutable.unsafeWith
+      within: []
+- functions:
+    - message: "Discards error info. Use decodeEither' or decodeThrow instead."
+      name: Data.Yaml.decode
+      within: []
+    - message: Discards error info. Use decodeFileEither or decodeFileThrow instead.
+      name: Data.Yaml.decodeFile
+      within: []
+- functions:
+    - message: "Deprecated. Use decodeEither' instead for ParseException details."
+      name: Data.Yaml.decodeEither
+      within: []
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,39 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Haskell Package Versioning Policy](https://pvp.haskell.org/).
+
+## [Unreleased]
+
+## [1.0.0.1] - 2026-01-01
+
+### Changed
+
+- Move `-j` (parallel compilation) option from `himari.cabal` ghc-options to `cabal.project` to fix Hackage upload compatibility
+
+## [1.0.0.0] - 2026-01-01
+
+### Added
+
+- `Himari` module that re-exports all submodules
+- `Himari.Prelude` module as a custom Prelude
+- `Himari.Char` module with `digitToIntMay`, `intToDigitMay`, `chrMay`
+- `Himari.Env` module with `Himari` newtype, `runHimari`, `liftHimari`, `mapHimari`
+- `Himari.Env.Simple` module with `SimpleEnv`, `runSimpleEnv`, `runSimpleEnvWith`
+- `Himari.Logger` module with `HasLogAction` type class and `LogAction` type alias
+- Re-exports from `Control.Lens`, `Control.Monad.*`, `Data.*`, `UnliftIO` in Prelude
+- Re-exports from `safe`, `aeson`, `pretty-simple`, `monad-logger`, `typed-process` in Prelude
+- Common type exports: `ByteString`, `Text`, `Vector`, `Map`, `HashMap`, etc.
+- Bundled `.hlint.yaml` as `data-files` with comprehensive rules managed in Dhall
+- HLint rules for partial function warnings in base, containers, text, bytestring, vector
+- HLint rules for unsafe function warnings in primitive, UnliftIO
+- HLint rules preferring UnliftIO over base IO modules
+- HLint rules preferring typed-process over System.Process
+- HLint rules preferring `convert` from convertible
+- HLint rules preferring `pTrace*` over `Debug.Trace`
+- HLint rules for qualified import naming conventions
+- HLint rules for aeson, lens, mtl, yaml, and more
+- Support for GHC 9.10.2, 9.10.3, and 9.12.2
+- GHC2024 as the default language with `NoImplicitPrelude` extension
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,83 @@
+# himari
+
+A standard library for Haskell to replace rio
+
+## 注意
+
+> [!IMPORTANT]
+> himariはrioとは完全に同じように使えるわけではありません。
+> ここで主な注意点を挙げます。
+
+### 重大なランタイムの非互換性
+
+#### ログの出力先の変更
+
+rioは基本的に標準出力にログを出力しますが、
+himariはデフォルトのガイドラインに従うと標準エラー出力にログを出力します。
+
+ログは標準エラー出力に出すべきだと考えているためです。
+
+変更したい時は出力先を`stderr`から`stdout`などに変更することで簡単に変更可能です。
+
+### 部分関数への対処方法の違い
+
+rioは部分関数を独自のモジュールでexportして提供していますが、
+himariはそのままオリジナルのモジュールを使ってもらいます。
+
+よってhimariは部分関数を除去していません。
+
+なのでhimariはhlintのルールで警告を出すことで対処しています。
+
+プロジェクトルートにある[.hlint.yaml](./.hlint.yaml)ファイルを、
+あなたのプロジェクトにコピーしてください。
+
+## 背景
+
+私は、
+[commercialhaskell/rio: A standard library for Haskell](https://github.com/commercialhaskell/rio)
+の思想が好みで長く使っています。
+
+しかしrioの好みではない点もいくつかあります。
+単純に質の問題であれば私がコントリビュートすれば良いのですが、
+非互換な選択である部分が多いため、
+それは受け入れられないだろうと考えて、
+rioに似たライブラリであるhimariを作成することにしました。
+
+## 目標
+
+### 依存関係が大きくなることを恐れない
+
+rioは依存関係を小さくしようと考えているのか、
+[lens: Lenses, Folds and Traversals](https://hackage.haskell.org/package/lens)
+ではなく、
+[microlens: A tiny lens library with no dependencies](https://hackage.haskell.org/package/microlens)
+を採用しています。
+
+しかし実際のライブラリでは本家のlensに依存していることも多く、
+結局使おうとしてコンフリクトすることが多いです。
+
+Haskellは静的にビルドする言語なので、
+依存関係が多いことはあまり怖くありません。
+
+使うとは限らない依存関係もドシドシimportしてしまいます。
+
+バージョンごとの依存関係の解決が大変なのはNixなどのパッケージマネージャのレイヤーで解決することにします。
+
+### なるべく一行で済ませたい
+
+himariは基本的には以下の一行で代替Preludeを提供することを目指します。
+
+```haskell
+import Himari
+```
+
+色々と書くのは面倒ですからね。
+これで衝突しない範囲はたくさんimportしてしまいます。
+
+同じシンボル名をexportしていて衝突してしまうものは仕方がないのでqualified importを使ってもらいます。
+
+### なるべく独自のシンボルを定義しない
+
+himariはrioで言う`RIO.Text`のような独自のシンボルを定義することをなるべく避けます。
+LLMのコーディングエージェントに独自のシンボルを使うことを守ってもらうのが難しいからです。
+しばしばオリジナルのシンボルをimportしてしまいます。
diff --git a/himari.cabal b/himari.cabal
new file mode 100644
--- /dev/null
+++ b/himari.cabal
@@ -0,0 +1,115 @@
+cabal-version: 3.0
+name: himari
+version: 1.0.0.1
+synopsis: A standard library for Haskell as an alternative to rio
+description:
+  A standard library for Haskell inspired by rio.
+  .
+  Unlike rio, himari uses the full lens library instead of microlens,
+  and provides hlint rules to warn against partial functions
+  instead of providing safe wrapper modules.
+  .
+  See the README at <https://github.com/ncaq/himari#readme> for more information.
+
+homepage: https://github.com/ncaq/himari
+bug-reports: https://github.com/ncaq/himari/issues
+license: Apache-2.0
+license-file: LICENSE
+author: ncaq
+maintainer: ncaq@ncaq.net
+copyright: ncaq
+category: Control
+build-type: Simple
+data-files: .hlint.yaml
+extra-doc-files:
+  CHANGELOG.md
+  README.md
+
+tested-with:
+  ghc ==9.10.2
+  ghc ==9.10.3
+  ghc ==9.12.2
+
+source-repository head
+  type: git
+  location: https://github.com/ncaq/himari.git
+
+common basic
+  ghc-options:
+    -Wall
+    -Wcompat
+    -Widentities
+    -Wincomplete-record-updates
+    -Wincomplete-uni-patterns
+    -Wpartial-fields
+    -Wredundant-constraints
+
+  default-language: GHC2024
+  default-extensions:
+    NoImplicitPrelude
+
+  build-depends:
+    aeson ^>=2.2.3.0,
+    aeson-pretty ^>=0.8.10,
+    base >=4.19.2.0 && <4.22,
+    bytestring ^>=0.12.2.0,
+    containers ^>=0.7,
+    convertible ^>=1.1.1.1,
+    deepseq ^>=1.5.0.0,
+    deriving-aeson ^>=0.2.10,
+    exceptions ^>=0.10.9,
+    filepath ^>=1.5.4.0,
+    hashable ^>=1.5.0.0,
+    lens ^>=5.3.5,
+    monad-logger ^>=0.3.42,
+    mtl ^>=2.3.1,
+    pretty-simple ^>=4.1.3,
+    primitive ^>=0.9.1.0,
+    safe ^>=0.3.21,
+    text ^>=2.1.2,
+    time ^>=1.12.2,
+    typed-process ^>=0.2.13.0,
+    unliftio ^>=0.2.25.1,
+    unordered-containers ^>=0.2.20,
+    vector ^>=0.13.2.0,
+
+library
+  import: basic
+  hs-source-dirs: src
+  -- cabal-gild: discover ./src
+  exposed-modules:
+    Himari
+    Himari.Char
+    Himari.Env
+    Himari.Env.Simple
+    Himari.Logger
+    Himari.Prelude
+
+test-suite himari-test
+  import: basic
+  type: exitcode-stdio-1.0
+  hs-source-dirs: test
+  main-is: Main.hs
+  ghc-options:
+    -threaded
+    -rtsopts
+    -with-rtsopts=-N
+
+  build-depends:
+    QuickCheck ^>=2.15.0.1,
+    himari,
+    sydtest ^>=0.18.0.0,
+
+  build-tool-depends:
+    hlint:hlint ^>=3.10
+
+  -- cabal-gild: discover ./test --exclude=**/Main.hs
+  other-modules:
+    Himari.CharSpec
+    Himari.Env.SimpleSpec
+    Himari.Title
+    HlintBaseSpec
+    HlintSamples.BasePartial
+    HlintSamples.UnliftioPreference
+    HlintUnliftioSpec
+    TitleSpec
diff --git a/src/Himari.hs b/src/Himari.hs
new file mode 100644
--- /dev/null
+++ b/src/Himari.hs
@@ -0,0 +1,8 @@
+-- | Custom Prelude library providing a comprehensive set of commonly used modules and utilities.
+module Himari (module Export) where
+
+import Himari.Char as Export
+import Himari.Env as Export
+import Himari.Env.Simple as Export
+import Himari.Logger as Export
+import Himari.Prelude as Export
diff --git a/src/Himari/Char.hs b/src/Himari/Char.hs
new file mode 100644
--- /dev/null
+++ b/src/Himari/Char.hs
@@ -0,0 +1,88 @@
+-- | Safe alternatives to partial functions from "Data.Char".
+module Himari.Char
+  ( digitToIntMay
+  , intToDigitMay
+  , chrMay
+  ) where
+
+import Data.Char qualified as C
+import Himari.Prelude
+
+-- | Safe version of "Data.Char".'digitToInt'.
+--
+-- Converts a hexadecimal digit character to the corresponding 'Int' value.
+-- Accepts decimal digits (@\'0\'@-@\'9\'@), lowercase hex digits (@\'a\'@-@\'f\'@),
+-- and uppercase hex digits (@\'A\'@-@\'F\'@).
+--
+-- Returns 'Nothing' for characters outside the valid range,
+-- instead of throwing an exception like "Data.Char".'digitToInt'.
+--
+-- >>> digitToIntMay '0'
+-- Just 0
+-- >>> digitToIntMay '9'
+-- Just 9
+-- >>> digitToIntMay 'a'
+-- Just 10
+-- >>> digitToIntMay 'F'
+-- Just 15
+-- >>> digitToIntMay 'g'
+-- Nothing
+-- >>> digitToIntMay ' '
+-- Nothing
+digitToIntMay :: C.Char -> Maybe Int
+digitToIntMay c
+  | C.isHexDigit c = Just (C.digitToInt c {- HLINT ignore "Avoid restricted function" -})
+  | otherwise = Nothing
+
+-- | Safe version of "Data.Char".'intToDigit'.
+--
+-- Converts an 'Int' in the range 0..15 to the corresponding
+-- single hexadecimal digit 'Char' (using lowercase @\'a\'@-@\'f\'@ for 10-15).
+--
+-- Returns 'Nothing' for values outside the valid range,
+-- instead of throwing an exception like "Data.Char".'intToDigit'.
+--
+-- >>> intToDigitMay 0
+-- Just '0'
+-- >>> intToDigitMay 10
+-- Just 'a'
+-- >>> intToDigitMay 15
+-- Just 'f'
+-- >>> intToDigitMay (-1)
+-- Nothing
+-- >>> intToDigitMay 16
+-- Nothing
+intToDigitMay :: Int -> Maybe C.Char
+intToDigitMay n
+  | 0 <= n, n <= 15 = Just (C.intToDigit n {- HLINT ignore "Avoid restricted function" -})
+  | otherwise = Nothing
+
+-- | Safe version of "Data.Char".'chr'.
+--
+-- Converts an 'Int' to a Unicode 'Char'.
+-- Valid code points are 0 to 0x10FFFF, excluding the surrogate range
+-- 0xD800 to 0xDFFF.
+--
+-- Returns 'Nothing' for invalid code points,
+-- instead of throwing an exception like "Data.Char".'chr'.
+--
+-- >>> chrMay 65
+-- Just 'A'
+-- >>> chrMay 0x3042
+-- Just '\12354'
+-- >>> chrMay 0x10FFFF
+-- Just '\1114111'
+-- >>> chrMay (-1)
+-- Nothing
+-- >>> chrMay 0x110000
+-- Nothing
+-- >>> chrMay 0xD800
+-- Nothing
+-- >>> chrMay 0xDFFF
+-- Nothing
+chrMay :: Int -> Maybe C.Char
+chrMay n
+  | n < 0 = Nothing
+  | 0x10FFFF < n = Nothing
+  | 0xD800 <= n, n <= 0xDFFF = Nothing -- surrogate range
+  | otherwise = Just (C.chr n {- HLINT ignore "Avoid restricted function" -})
diff --git a/src/Himari/Env.hs b/src/Himari/Env.hs
new file mode 100644
--- /dev/null
+++ b/src/Himari/Env.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE TypeFamilies #-}
+
+-- | Core environment monad for Himari.
+module Himari.Env
+  ( Himari (..)
+  , runHimari
+  , liftHimari
+  , mapHimari
+  ) where
+
+import Himari.Prelude
+
+-- | The Reader + IO monad.
+-- It is nearly equal to @RIO@ from the rio package.
+newtype Himari env a = Himari
+  { unHimari :: ReaderT env IO a
+  }
+  deriving newtype (Applicative, Functor, Monad, MonadIO, MonadReader env, MonadThrow, MonadUnliftIO)
+
+instance (Semigroup a) => Semigroup (Himari env a) where
+  (<>) = liftA2 (<>)
+
+instance (Monoid a) => Monoid (Himari env a) where
+  mempty = pure mempty
+
+instance PrimMonad (Himari env) where
+  type PrimState (Himari env) = PrimState IO
+  primitive = Himari . ReaderT . const . primitive
+
+-- | Given an environment, runs the action that requires it in IO.
+runHimari :: (MonadIO m) => env -> Himari env a -> m a
+runHimari env (Himari (ReaderT f)) = liftIO (f env)
+
+-- | Abstract `Himari` to an arbitrary `MonadReader` instance, which can handle IO.
+liftHimari :: (MonadIO m, MonadReader env m) => Himari env a -> m a
+liftHimari rio = do
+  env <- ask
+  runHimari env rio
+
+-- | Lift one Himari env to another.
+mapHimari :: (outer -> inner) -> Himari inner a -> Himari outer a
+mapHimari f m = do
+  outer <- ask
+  runHimari (f outer) m
diff --git a/src/Himari/Env/Simple.hs b/src/Himari/Env/Simple.hs
new file mode 100644
--- /dev/null
+++ b/src/Himari/Env/Simple.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE NoFieldSelectors #-}
+
+-- | 基本的な環境を提供するモジュール。
+-- 単純に実行だけをしたい場合、これで十分結果を手に入れられることが多いです。
+module Himari.Env.Simple
+  ( SimpleEnv
+  , runSimpleEnv
+  , runSimpleEnvWith
+  ) where
+
+import Himari.Env
+import Himari.Logger
+import Himari.Prelude
+
+-- | シンプルにロガーなどを持って解決するためのコンテキスト。
+newtype SimpleEnv = SimpleEnv
+  { logAction :: LogAction
+  -- ^ ログフレームワークに渡すための関数。
+  -- デフォルトではmonad-loggerによって標準エラー出力にログを出力する。
+  }
+  deriving (Generic)
+
+makeFieldsId ''SimpleEnv
+
+instance MonadLogger (Himari SimpleEnv) where
+  monadLoggerLog loc src level msg = do
+    logAction' <- view logAction
+    liftIO . logAction' loc src level $ toLogStr msg
+
+-- | `SimpleEnv`をデフォルト設定で実行する。
+runSimpleEnv :: (MonadIO m) => Himari SimpleEnv a -> m a
+runSimpleEnv = runSimpleEnvWith $ defaultOutput stderr
+
+-- | `SimpleEnv`をカスタム出力で実行します。
+runSimpleEnvWith
+  :: (MonadIO m)
+  => LogAction
+  -- ^ ログの出力方法。例えば`defaultOutput stdout`にすれば標準出力にログが出力されます。
+  -> Himari SimpleEnv a
+  -- ^ 実行したいアクション。
+  -> m a
+runSimpleEnvWith logAction' = runHimari (SimpleEnv logAction')
diff --git a/src/Himari/Logger.hs b/src/Himari/Logger.hs
new file mode 100644
--- /dev/null
+++ b/src/Himari/Logger.hs
@@ -0,0 +1,18 @@
+{-# LANGUAGE FunctionalDependencies #-}
+
+-- | Logger utilities for Himari.
+module Himari.Logger
+  ( HasLogAction (..)
+  , LogAction
+  ) where
+
+import Himari.Prelude
+
+-- | ログ出力を行う能力があることを検査するための型クラス。
+-- lensと互換性を持たせているので適切にフィールド名を設定してTemplate Haskellで生成すれば自動で実装されます。
+class HasLogAction s a | s -> a where
+  logAction :: Lens' s a
+
+-- | ログ出力を行う関数の型。
+-- 出力をカスタムしたい場合、このシグネチャに合わせた関数を作成するとやりやすい。
+type LogAction = Loc -> LogSource -> LogLevel -> LogStr -> IO ()
diff --git a/src/Himari/Prelude.hs b/src/Himari/Prelude.hs
new file mode 100644
--- /dev/null
+++ b/src/Himari/Prelude.hs
@@ -0,0 +1,195 @@
+-- | Alternative to "Prelude".
+module Himari.Prelude
+  ( module Export
+  -- Type only re-exports.
+  , ByteString
+  , StrictByteString
+  , LazyByteString
+  , ShortByteString
+  , HashMap
+  , HashSet
+  , IntMap
+  , IntSet
+  , List
+  , NonEmpty
+  , Map
+  , Seq
+  , Set
+  , StrictText
+  , Text
+  , LazyText
+  , Tree
+  , MVector
+  , Vector
+  ) where
+
+import Control.Applicative as Export
+import Control.Category as Export hiding (id, (.))
+import Control.DeepSeq as Export
+import Control.Lens as Export
+import Control.Monad as Export
+import Control.Monad.Cont as Export
+import Control.Monad.Logger as Export
+import Control.Monad.Primitive as Export
+import Control.Monad.Reader as Export
+import Control.Monad.ST as Export
+import Control.Monad.State.Strict as Export
+import Control.Monad.Writer.CPS as Export
+import Data.Bifoldable as Export
+import Data.Bifunctor as Export
+import Data.Bitraversable as Export
+import Data.Bool as Export
+import Data.Convertible as Export
+import Data.Either as Export
+import Data.Eq as Export
+import Data.Foldable as Export
+import Data.Function as Export
+import Data.Hashable as Export
+import Data.Maybe as Export
+import Data.Monoid as Export
+import Data.Ord as Export
+import Data.Ratio as Export
+import Data.String as Export
+import Data.Time as Export
+import Data.Traversable as Export
+import Data.Tuple as Export
+import Data.Void as Export
+import Data.Word as Export
+import Debug.Pretty.Simple as Export
+import GHC.Generics as Export hiding (from, to)
+import System.FilePath as Export hiding ((<.>))
+import System.Process.Typed as Export
+import Text.Pretty.Simple as Export
+import Text.Show as Export
+import UnliftIO as Export
+import Prelude as Export
+
+-- 部分関数ではない代替関数を提供してくれるsafeライブラリからシンボルを持ってきます。
+-- 必要なのは部分関数ではない関数なので、部分関数はいらないのでhidingします。
+-- `Safe.Foldable`の方がより汎用的なので、そちらを優先してコンフリクトするものはhidingします。
+import Safe as Export hiding
+  ( abort
+  , assertNote
+  , at
+  , atNote
+  , cycleNote
+  , elemIndexJust
+  , elemIndexJustNote
+  , findIndexJust
+  , findIndexJustNote
+  , findJust
+  , findJustDef
+  , findJustNote
+  , foldl1Def
+  , foldl1May
+  , foldl1Note
+  , foldl1Note'
+  , foldr1Def
+  , foldr1May
+  , foldr1Note
+  , fromJustNote
+  , headErr
+  , headNote
+  , indexNote
+  , initNote
+  , lastNote
+  , lookupJust
+  , lookupJustNote
+  , maximumBound
+  , maximumBoundBy
+  , maximumBounded
+  , maximumByDef
+  , maximumByMay
+  , maximumByNote
+  , maximumDef
+  , maximumMay
+  , maximumNote
+  , minimumBound
+  , minimumBoundBy
+  , minimumBounded
+  , minimumByDef
+  , minimumByMay
+  , minimumByNote
+  , minimumDef
+  , minimumMay
+  , minimumNote
+  , predNote
+  , readNote
+  , scanl1Note
+  , scanr1Note
+  , succNote
+  , tailErr
+  , tailNote
+  , toEnumNote
+  )
+import Safe.Exact as Export hiding
+  ( dropExact
+  , dropExactNote
+  , splitAtExact
+  , splitAtExactNote
+  , takeExact
+  , takeExactNote
+  , zip3Exact
+  , zip3ExactNote
+  , zipExact
+  , zipExactNote
+  , zipWith3Exact
+  , zipWith3ExactNote
+  , zipWithExact
+  , zipWithExactNote
+  )
+import Safe.Foldable as Export hiding
+  ( findJust
+  , findJustNote
+  , foldl1Note
+  , foldr1Note
+  , maximumByNote
+  , maximumNote
+  , minimumByNote
+  , minimumNote
+  )
+
+-- aeson系には被りそうな関数名が多いので、hidingしたり、シンボルを個別importします。
+import Data.Aeson as Export hiding
+  ( decode
+  , decode'
+  , decodeFileStrict
+  , decodeFileStrict'
+  , decodeStrict
+  , decodeStrict'
+  , decodeStrictText
+  , eitherDecode'
+  , eitherDecodeFileStrict'
+  , eitherDecodeStrict'
+  , throwDecode'
+  , throwDecodeStrict'
+  , (.=)
+  )
+import Data.Aeson.Encode.Pretty as Export
+  ( encodePretty
+  , encodePretty'
+  , encodePrettyToTextBuilder
+  , encodePrettyToTextBuilder'
+  )
+import Data.Aeson.QQ.Simple as Export
+import Deriving.Aeson as Export
+
+-- Type only.
+
+import Control.Monad.Catch as Export (MonadCatch, MonadMask, MonadThrow)
+import Data.ByteString (ByteString, StrictByteString)
+import Data.ByteString.Lazy (LazyByteString)
+import Data.ByteString.Short (ShortByteString)
+import Data.HashMap.Strict (HashMap)
+import Data.HashSet (HashSet)
+import Data.IntMap.Strict (IntMap)
+import Data.IntSet (IntSet)
+import Data.List (List)
+import Data.List.NonEmpty (NonEmpty)
+import Data.Map.Strict (Map)
+import Data.Sequence (Seq)
+import Data.Set (Set)
+import Data.Text (StrictText, Text)
+import Data.Text.Lazy (LazyText)
+import Data.Tree (Tree)
+import Data.Vector (MVector, Vector)
diff --git a/test/Himari/CharSpec.hs b/test/Himari/CharSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Himari/CharSpec.hs
@@ -0,0 +1,208 @@
+module Himari.CharSpec (spec) where
+
+import Data.Char (chr, digitToInt, intToDigit, isHexDigit, ord, toUpper)
+import Himari hiding (elements)
+import Test.QuickCheck
+import Test.Syd
+
+spec :: Spec
+spec = do
+  describe "digitToIntMay" $ do
+    describe "boundary values" $ do
+      it "returns Just 0 for '0'" $ do
+        digitToIntMay '0' `shouldBe` Just 0
+
+      it "returns Just 9 for '9'" $ do
+        digitToIntMay '9' `shouldBe` Just 9
+
+      it "returns Just 10 for 'a'" $ do
+        digitToIntMay 'a' `shouldBe` Just 10
+
+      it "returns Just 10 for 'A'" $ do
+        digitToIntMay 'A' `shouldBe` Just 10
+
+      it "returns Just 15 for 'f'" $ do
+        digitToIntMay 'f' `shouldBe` Just 15
+
+      it "returns Just 15 for 'F'" $ do
+        digitToIntMay 'F' `shouldBe` Just 15
+
+      it "returns Nothing for 'g'" $ do
+        digitToIntMay 'g' `shouldBe` Nothing
+
+      it "returns Nothing for 'G'" $ do
+        digitToIntMay 'G' `shouldBe` Nothing
+
+      it "returns Nothing for ' '" $ do
+        digitToIntMay ' ' `shouldBe` Nothing
+
+    describe "all valid hex digits" $ do
+      it "returns Just for all decimal digits" $ do
+        forM_ ['0' .. '9'] $ \c ->
+          digitToIntMay c `shouldSatisfy` isJust
+
+      it "returns Just for all lowercase hex letters" $ do
+        forM_ ['a' .. 'f'] $ \c ->
+          digitToIntMay c `shouldSatisfy` isJust
+
+      it "returns Just for all uppercase hex letters" $ do
+        forM_ ['A' .. 'F'] $ \c ->
+          digitToIntMay c `shouldSatisfy` isJust
+
+      it "matches digitToInt for all valid characters" $ do
+        let validChars = ['0' .. '9'] <> ['a' .. 'f'] <> ['A' .. 'F']
+        forM_ validChars $ \c ->
+          digitToIntMay c `shouldBe` Just (digitToInt c {- HLINT ignore "Avoid restricted function" -})
+
+    describe "QuickCheck properties" $ do
+      it "returns Just for hex digit characters" $ do
+        property . forAll (elements (['0' .. '9'] <> ['a' .. 'f'] <> ['A' .. 'F'])) $ \c ->
+          isJust (digitToIntMay c)
+
+      it "returns Nothing for non-hex characters" $ do
+        property . forAll (elements (['g' .. 'z'] <> ['G' .. 'Z'] <> [' ', '!', '@', '#'])) $ \c ->
+          isNothing (digitToIntMay c)
+
+      it "matches digitToInt for all valid hex digit inputs" $ do
+        property . forAll (elements (['0' .. '9'] <> ['a' .. 'f'] <> ['A' .. 'F'])) $ \c ->
+          digitToIntMay c == Just (digitToInt c {- HLINT ignore "Avoid restricted function" -})
+
+      it "agrees with isHexDigit on validity" $ do
+        property $ \c ->
+          isJust (digitToIntMay c) == isHexDigit c
+
+      it "returns values in range 0-15 for valid inputs" $ do
+        property . forAll (elements (['0' .. '9'] <> ['a' .. 'f'] <> ['A' .. 'F'])) $ \c ->
+          case digitToIntMay c of
+            Just n -> n >= 0 && n <= 15
+            Nothing -> False
+
+      it "lowercase and uppercase give same result" $ do
+        property . forAll (elements ['a' .. 'f']) $ \c ->
+          digitToIntMay c == digitToIntMay (toUpper c)
+
+  describe "intToDigitMay" $ do
+    describe "boundary values" $ do
+      it "returns Just '0' for 0" $ do
+        intToDigitMay 0 `shouldBe` Just '0'
+
+      it "returns Just 'f' for 15" $ do
+        intToDigitMay 15 `shouldBe` Just 'f'
+
+      it "returns Nothing for -1" $ do
+        intToDigitMay (-1) `shouldBe` Nothing
+
+      it "returns Nothing for 16" $ do
+        intToDigitMay 16 `shouldBe` Nothing
+
+    describe "all valid values (0-15)" $ do
+      it "returns Just for all values in range" $ do
+        let validRange = [0 .. 15]
+        forM_ validRange $ \n ->
+          intToDigitMay n `shouldSatisfy` isJust
+
+      it "matches intToDigit for all valid values" $ do
+        let validRange = [0 .. 15]
+        forM_ validRange $ \n ->
+          intToDigitMay n `shouldBe` Just (intToDigit n {- HLINT ignore "Avoid restricted function" -})
+
+    describe "QuickCheck properties" $ do
+      it "returns Just for values in range 0-15" $ do
+        property . forAll (choose (0, 15)) $ \n ->
+          isJust (intToDigitMay n)
+
+      it "returns Nothing for negative values" $ do
+        property . forAll (choose (-1000, -1)) $ \n ->
+          isNothing (intToDigitMay n)
+
+      it "returns Nothing for values greater than 15" $ do
+        property . forAll (choose (16, 1000)) $ \n ->
+          isNothing (intToDigitMay n)
+
+      it "matches intToDigit for all valid inputs" $ do
+        property . forAll (choose (0, 15)) $ \n ->
+          intToDigitMay n == Just (intToDigit n {- HLINT ignore "Avoid restricted function" -})
+
+      it "produces lowercase hex digits for 10-15" $ do
+        property . forAll (choose (10, 15)) $ \n ->
+          case intToDigitMay n of
+            Just c -> c `elem` ['a' .. 'f']
+            Nothing -> False
+
+      it "produces decimal digits for 0-9" $ do
+        property . forAll (choose (0, 9)) $ \n ->
+          case intToDigitMay n of
+            Just c -> c `elem` ['0' .. '9']
+            Nothing -> False
+
+  describe "chrMay" $ do
+    describe "boundary values" $ do
+      it "returns Just for 0 (NUL)" $ do
+        chrMay 0 `shouldBe` Just '\0'
+
+      it "returns Just 'A' for 65" $ do
+        chrMay 65 `shouldBe` Just 'A'
+
+      it "returns Just for max valid code point (0x10FFFF)" $ do
+        chrMay 0x10FFFF `shouldBe` Just '\x10FFFF'
+
+      it "returns Nothing for -1" $ do
+        chrMay (-1) `shouldBe` Nothing
+
+      it "returns Nothing for 0x110000 (beyond max)" $ do
+        chrMay 0x110000 `shouldBe` Nothing
+
+      it "returns Nothing for surrogate start (0xD800)" $ do
+        chrMay 0xD800 `shouldBe` Nothing
+
+      it "returns Nothing for surrogate end (0xDFFF)" $ do
+        chrMay 0xDFFF `shouldBe` Nothing
+
+      it "returns Nothing for surrogate middle (0xDC00)" $ do
+        chrMay 0xDC00 `shouldBe` Nothing
+
+    describe "valid ranges" $ do
+      it "returns Just for code points before surrogate range" $ do
+        chrMay 0xD7FF `shouldSatisfy` isJust
+
+      it "returns Just for code points after surrogate range" $ do
+        chrMay 0xE000 `shouldSatisfy` isJust
+
+      it "returns Just for common characters" $ do
+        forM_ [('a', 97), ('z', 122), ('0', 48), ('9', 57)] $ \(expected, n) ->
+          chrMay n `shouldBe` Just expected
+
+    describe "QuickCheck properties" $ do
+      it "returns Just for valid BMP code points (excluding surrogates)" $ do
+        property . forAll (choose (0, 0xD7FF)) $ \n ->
+          isJust (chrMay n)
+
+      it "returns Just for valid code points after surrogates" $ do
+        property . forAll (choose (0xE000, 0x10FFFF)) $ \n ->
+          isJust (chrMay n)
+
+      it "returns Nothing for surrogate range" $ do
+        property . forAll (choose (0xD800, 0xDFFF)) $ \n ->
+          isNothing (chrMay n)
+
+      it "returns Nothing for negative values" $ do
+        property . forAll (choose (-1000, -1)) $ \n ->
+          isNothing (chrMay n)
+
+      it "returns Nothing for values beyond max code point" $ do
+        property . forAll (choose (0x110000, 0x200000)) $ \n ->
+          isNothing (chrMay n)
+
+      it "matches chr for all valid inputs" $ do
+        property . forAll (choose (0, 0xD7FF)) $ \n ->
+          chrMay n == Just (chr n {- HLINT ignore "Avoid restricted function" -})
+
+      it "is inverse of ord for valid characters" $ do
+        property $ \c ->
+          chrMay (ord c) == Just c
+
+      it "never throws an exception for any Int value" $ do
+        withMaxSuccess 10000 . property $ \n ->
+          case chrMay n of
+            Just _ -> True
+            Nothing -> True
diff --git a/test/Himari/Env/SimpleSpec.hs b/test/Himari/Env/SimpleSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Himari/Env/SimpleSpec.hs
@@ -0,0 +1,92 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+module Himari.Env.SimpleSpec (spec) where
+
+import Himari
+import Test.Syd
+
+spec :: Spec
+spec = do
+  describe "logging" $ do
+    it
+      "outputs debug level logs"
+      (runSimpleEnv $ $(logDebug) "debug message" :: IO ())
+
+    it
+      "outputs info level logs"
+      (runSimpleEnv $ $(logInfo) "info message" :: IO ())
+
+    it
+      "outputs warning level logs"
+      (runSimpleEnv $ $(logWarn) "warning message" :: IO ())
+
+    it
+      "outputs error level logs"
+      (runSimpleEnv $ $(logError) "error message" :: IO ())
+
+    it
+      "handles multiple log calls"
+      ( runSimpleEnv
+          ( do
+              $(logInfo) "first log"
+              $(logInfo) "second log"
+              $(logDebug) "third log"
+          )
+          :: IO ()
+      )
+
+    it "works with monadic composition" $ do
+      result <- runSimpleEnv $ do
+        $(logInfo) "starting computation"
+        let x = 20 :: Int
+        $(logDebug) ("intermediate value: " <> convert (show x))
+        let y = x + 22
+        $(logInfo) "computation complete"
+        pure y
+      result `shouldBe` 42
+
+    it
+      "supports monad-logger functions"
+      ( runSimpleEnv
+          ( do
+              logInfoN "using logInfoN"
+              logDebugN "using logDebugN"
+              logWarnN "using logWarnN"
+          )
+          :: IO ()
+      )
+
+  describe "custom log output" $ do
+    it "can capture log messages" $ do
+      chan <- newTChanIO :: IO (TChan Text)
+      let customLogOutput _loc _src _level msg = do
+            let msgText = convert (fromLogStr msg)
+            atomically $ writeTChan chan msgText
+      runSimpleEnvWith customLogOutput $ do
+        $(logInfo) "custom output test"
+      message <- atomically $ readTChan chan
+      message `shouldBe` "custom output test"
+
+    it "captures log level information" $ do
+      chan <- newTChanIO :: IO (TChan (Text, LogLevel))
+      let customLogOutput _loc _src level msg = do
+            let msgText = convert (fromLogStr msg)
+            atomically $ writeTChan chan (msgText, level)
+      runSimpleEnvWith customLogOutput $ do
+        $(logError) "error log"
+        $(logWarn) "warning log"
+      msg1 <- atomically $ readTChan chan
+      msg2 <- atomically $ readTChan chan
+      [msg1, msg2] `shouldBe` [("error log", LevelError), ("warning log", LevelWarn)]
+
+  describe "basic execution" $ do
+    it "executes actions successfully" $ do
+      result <- runSimpleEnv $ pure (42 :: Int)
+      result `shouldBe` 42
+
+    it "can access and use the environment" $ do
+      result <- runSimpleEnv $ do
+        $(logInfo) "computing result"
+        pure (10 + 32 :: Int)
+      result `shouldBe` 42
diff --git a/test/Himari/Title.hs b/test/Himari/Title.hs
new file mode 100644
--- /dev/null
+++ b/test/Himari/Title.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Himari.Title
+  ( titleComponents
+  , generateAllCombinations
+  , renderTitle
+  , printAllTitle
+  ) where
+
+import Data.List.NonEmpty qualified as NE
+import Data.Text qualified as T
+import Data.Text.IO qualified as T
+import Himari
+
+-- | ヒマリの肩書き要素。
+-- 順番は固定。
+-- `NonEmpty`で表現することで、最低1つは要素があることを保証。
+titleComponents :: NonEmpty Text
+titleComponents = "超" NE.:| ["天才", "清楚系", "病弱", "美少女", "ハッカー"]
+
+-- | 全ての組み合わせを生成。
+-- `NonEmpty`の部分列を生成。
+generateAllCombinations :: [NonEmpty Text]
+generateAllCombinations = nonEmptySubsequences titleComponents
+ where
+  -- NonEmptyの空でない部分列を全て生成（順番は保持）
+  nonEmptySubsequences :: NonEmpty a -> [NonEmpty a]
+  nonEmptySubsequences (x NE.:| []) = [x NE.:| []]
+  nonEmptySubsequences (x NE.:| (y : ys)) =
+    let rest = nonEmptySubsequences (y NE.:| ys)
+     in rest <> fmap (x NE.<|) rest <> [x NE.:| []]
+
+-- | 肩書きを`Text`に変換。
+renderTitle :: NonEmpty Text -> Text
+renderTitle = T.concat . NE.toList
+
+-- | 明示的に標準入出力に一行ずつ名乗りを出力。
+printAllTitle :: IO ()
+printAllTitle = mapM_ (T.putStrLn . renderTitle) generateAllCombinations
diff --git a/test/HlintBaseSpec.hs b/test/HlintBaseSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/HlintBaseSpec.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module HlintBaseSpec (spec) where
+
+import Data.Text qualified as T
+import Himari
+import Test.Syd
+
+spec :: Spec
+spec = do
+  describe "hlint base library rules" . beforeAll runHlintOnSample $ do
+    describe "Data.List partial functions" $ do
+      itWithOuter "Data.List.head should warn (partial function)" $ \output -> do
+        output `shouldSatisfy` containsWarning "headMay"
+
+    describe "NonEmpty.head should be safe" $ do
+      itWithOuter "Data.List.NonEmpty.head should NOT warn (it's safe)" $ \output -> do
+        output `shouldSatisfy` notContainsWarningAt "useNonEmptyHead"
+
+    describe "Debug.Trace functions suggest pTrace*" $ do
+      itWithOuter "Debug.Trace.trace should suggest pTrace" $ \output -> do
+        output `shouldSatisfy` containsWarningAt "trace" "pTrace"
+
+      itWithOuter "Debug.Trace.traceShow should suggest pTraceShow" $ \output -> do
+        output `shouldSatisfy` containsWarningAt "traceShow" "pTraceShow"
+
+      itWithOuter "Debug.Trace.traceM should suggest pTraceM" $ \output -> do
+        output `shouldSatisfy` containsWarningAt "traceM" "pTraceM"
+
+runHlintOnSample :: IO Text
+runHlintOnSample = do
+  (exitCode, stdoutOutput, stderrOutput) <-
+    readProcess
+      $ proc "hlint" ["test/HlintSamples/BasePartial.hs"]
+  pure $ case exitCode of
+    ExitSuccess -> convert stdoutOutput
+    ExitFailure _ -> convert stdoutOutput <> convert stderrOutput
+
+containsWarning :: Text -> Text -> Bool
+containsWarning expectedMsg output = expectedMsg `T.isInfixOf` output
+
+containsWarningAt :: Text -> Text -> Text -> Bool
+containsWarningAt funcName expectedMsg output =
+  let msgAndFunc = funcName `T.isInfixOf` output && expectedMsg `T.isInfixOf` output
+   in msgAndFunc
+
+notContainsWarningAt :: Text -> Text -> Bool
+notContainsWarningAt funcName output =
+  let linesWithFunc =
+        filter (T.isInfixOf funcName) (T.lines output)
+   in null linesWithFunc
diff --git a/test/HlintSamples/BasePartial.hs b/test/HlintSamples/BasePartial.hs
new file mode 100644
--- /dev/null
+++ b/test/HlintSamples/BasePartial.hs
@@ -0,0 +1,31 @@
+{-# OPTIONS_GHC -Wno-x-partial #-}
+
+-- Sample file to test base library hlint rules
+-- This file intentionally uses partial functions to test hlint rules
+module HlintSamples.BasePartial where
+
+import Data.List qualified as L
+import Data.List.NonEmpty qualified as NE
+import Debug.Trace (trace, traceM, traceShow)
+import Himari
+
+-- These should trigger warnings
+useHead :: [Int] -> Int
+useHead = head
+
+useHeadQualified :: [Int] -> Int
+useHeadQualified = L.head
+
+-- This should NOT trigger a warning (NonEmpty.head is safe)
+useNonEmptyHead :: NonEmpty Int -> Int
+useNonEmptyHead = NE.head
+
+-- Debug.Trace should trigger warnings
+useTrace :: Int -> Int
+useTrace x = trace "debug" x
+
+useTraceShow :: (Show a) => a -> a
+useTraceShow x = traceShow x x
+
+useTraceM :: IO ()
+useTraceM = traceM "debug"
diff --git a/test/HlintSamples/UnliftioPreference.hs b/test/HlintSamples/UnliftioPreference.hs
new file mode 100644
--- /dev/null
+++ b/test/HlintSamples/UnliftioPreference.hs
@@ -0,0 +1,32 @@
+-- This file contains code patterns that should trigger hlint warnings
+-- for preferring unliftio functions over standard library functions.
+module HlintSamples.UnliftioPreference where
+
+import Control.Concurrent.MVar qualified as MVar
+import Control.Exception qualified as Exception
+import Himari
+import System.Timeout qualified as Timeout
+
+-- Control.Exception functions (should warn)
+badCatch :: IO ()
+badCatch = Exception.catch (pure ()) (\(_ :: Exception.SomeException) -> pure ())
+
+badBracket :: IO ()
+badBracket = Exception.bracket (pure ()) (const (pure ())) (const (pure ()))
+
+badFinally :: IO ()
+badFinally = Exception.finally (pure ()) (pure ())
+
+badTry :: IO (Either Exception.SomeException ())
+badTry = Exception.try (pure ())
+
+-- Control.Concurrent.MVar functions (should warn)
+badWithMVar :: MVar.MVar () -> IO ()
+badWithMVar mv = MVar.withMVar mv pure
+
+badModifyMVar :: MVar.MVar () -> IO ()
+badModifyMVar mv = MVar.modifyMVar_ mv pure
+
+-- System.Timeout functions (should warn)
+badTimeout :: IO (Maybe ())
+badTimeout = Timeout.timeout 1000 (pure ())
diff --git a/test/HlintUnliftioSpec.hs b/test/HlintUnliftioSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/HlintUnliftioSpec.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module HlintUnliftioSpec (spec) where
+
+import Data.Text qualified as T
+import Himari
+import Test.Syd
+
+spec :: Spec
+spec = do
+  describe "hlint unliftio preference rules" . beforeAll runHlintOnSample $ do
+    itWithOuter "Control.Exception.catch should warn to use UnliftIO.Exception" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.Exception.catch"
+
+    itWithOuter "Control.Exception.bracket should warn to use UnliftIO.Exception" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.Exception.bracket"
+
+    itWithOuter "Control.Exception.finally should warn to use UnliftIO.Exception" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.Exception.finally"
+
+    itWithOuter "Control.Exception.try should warn to use UnliftIO.Exception" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.Exception.try"
+
+    itWithOuter "Control.Concurrent.MVar.withMVar should warn to use UnliftIO.MVar" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.MVar.withMVar"
+
+    itWithOuter "Control.Concurrent.MVar.modifyMVar_ should warn to use UnliftIO.MVar" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.MVar.modifyMVar_"
+
+    itWithOuter "System.Timeout.timeout should warn to use UnliftIO.Timeout" $ \output -> do
+      output `shouldSatisfy` containsWarning "UnliftIO.Timeout.timeout"
+
+runHlintOnSample :: IO Text
+runHlintOnSample = do
+  (exitCode, stdoutOutput, stderrOutput) <-
+    readProcess
+      $ proc "hlint" ["test/HlintSamples/UnliftioPreference.hs"]
+  pure $ case exitCode of
+    ExitSuccess -> convert stdoutOutput
+    ExitFailure _ -> convert stdoutOutput <> convert stderrOutput
+
+containsWarning :: Text -> Text -> Bool
+containsWarning expectedMsg output = expectedMsg `T.isInfixOf` output
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,17 @@
+module Main (main) where
+
+import Himari
+import Himari.CharSpec qualified as CharSpec
+import Himari.Env.SimpleSpec qualified as SimpleSpec
+import HlintBaseSpec qualified
+import HlintUnliftioSpec qualified
+import Test.Syd
+import TitleSpec qualified
+
+main :: IO ()
+main = sydTest $ do
+  describe "Char" CharSpec.spec
+  describe "Simple" SimpleSpec.spec
+  describe "Title" TitleSpec.spec
+  describe "HlintUnliftio" HlintUnliftioSpec.spec
+  describe "HlintBase" HlintBaseSpec.spec
diff --git a/test/TitleSpec.hs b/test/TitleSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/TitleSpec.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module TitleSpec (spec) where
+
+import Data.List.NonEmpty qualified as NE
+import Himari
+import Himari.Title
+import Test.Syd
+
+spec :: Spec
+spec = do
+  describe "titleComponents" $ do
+    it "最初の要素が「超」であること" $ do
+      NE.head titleComponents `shouldBe` "超"
+
+    it "6つの要素を持つこと" $ do
+      length titleComponents `shouldBe` 6
+
+  describe "generateAllCombinations" $ do
+    it "空でないリストを生成すること" $ do
+      generateAllCombinations `shouldNotSatisfy` null
+
+    it "各組み合わせが空でないこと" $ do
+      any null generateAllCombinations `shouldBe` False
+
+  describe "renderTitle" $ do
+    it "単一要素の肩書きを正しく変換すること" $ do
+      renderTitle ("超" NE.:| []) `shouldBe` "超"
+
+    it "複数要素の肩書きを連結すること" $ do
+      renderTitle ("超" NE.:| ["天才"]) `shouldBe` "超天才"
+
+    it "全要素を連結すること" $ do
+      renderTitle titleComponents `shouldBe` "超天才清楚系病弱美少女ハッカー"
