diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,37 @@
 # Changelog
 
+## 0.13.0.0 — 2026-08-09
+
+Driven by the `pgmq-hs` 0.5 release. The adapter remains paired with
+`shibuya-core 0.8.0.1`, and its own public function and record signatures are unchanged.
+
+### Breaking Changes
+
+- Requires `pgmq-core ^>=0.5`, `pgmq-effectful ^>=0.5`, and `pgmq-hasql ^>=0.5` in
+  the library, plus `pgmq-migration ^>=0.5` in the test stanza, up from the 0.4 family.
+- The re-exported `parseQueueName` now accepts only non-empty names of at most 47
+  lowercase ASCII letters, digits, or underscores (`[a-z0-9_]{1,47}`). Operators must
+  detect and transactionally remediate mixed-case `pgmq.meta` rows before rollout; see
+  [Installing the PGMQ schema](../docs/user/pgmq-getting-started.md#before-upgrading-to-pgmq--05).
+
+### Reliability
+
+- `mkLease` handles pgmq-hs 0.5's `Maybe Message` visibility-timeout result. When a
+  message was deleted, archived, or popped before extension reached it, `leaseExtend`
+  returns normally and leaves the last confirmed visibility deadline unchanged. A live
+  row still advances that deadline from the value PostgreSQL returns.
+- The existing bounded retry wrapper inherits pgmq-effectful 0.5's broader transient
+  SQLSTATE classification: serialization failures, deadlocks, lock-unavailable errors,
+  server shutdown/recovery, and class 53 resource errors are now eligible for retry.
+- The test harness and downstream components inherit pgmq-migration 0.5's notification
+  crash-safety migration, which fails open after crash recovery truncates the unlogged
+  throttle table so insert notifications continue until reconciliation restores it.
+
+### Tests
+
+- Added a PostgreSQL-backed regression for extending a lease after its message is deleted
+  and a public-boundary regression for lowercase, uppercase, and empty queue names.
+
 ## 0.12.0.0 — 2026-07-14
 
 Driven by the `pgmq-hs` 0.4 release. Still paired with `shibuya-core 0.8.0.1`
diff --git a/shibuya-pgmq-adapter.cabal b/shibuya-pgmq-adapter.cabal
--- a/shibuya-pgmq-adapter.cabal
+++ b/shibuya-pgmq-adapter.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.12
 name: shibuya-pgmq-adapter
-version: 0.12.0.0
+version: 0.13.0.0
 synopsis: PGMQ adapter for the Shibuya queue processing framework
 description:
   A Shibuya adapter that integrates with pgmq (PostgreSQL Message Queue)
@@ -46,9 +46,9 @@
     hasql ^>=1.10,
     hasql-pool ^>=1.4,
     hasql-transaction ^>=1.2,
-    pgmq-core ^>=0.4,
-    pgmq-effectful ^>=0.4,
-    pgmq-hasql ^>=0.4,
+    pgmq-core ^>=0.5,
+    pgmq-effectful ^>=0.5,
+    pgmq-hasql ^>=0.5,
     shibuya-core ^>=0.8.0.1,
     stm ^>=2.5,
     streamly ^>=0.11,
@@ -113,10 +113,10 @@
     hasql-transaction ^>=1.2,
     hspec ^>=2.11,
     pg-migrate ^>=1.1,
-    pgmq-core ^>=0.4,
-    pgmq-effectful ^>=0.4,
-    pgmq-hasql ^>=0.4,
-    pgmq-migration ^>=0.4,
+    pgmq-core ^>=0.5,
+    pgmq-effectful ^>=0.5,
+    pgmq-hasql ^>=0.5,
+    pgmq-migration ^>=0.5,
     quickcheck-instances ^>=0.3,
     random,
     shibuya-core ^>=0.8.0.1,
diff --git a/src/Shibuya/Adapter/Pgmq/Internal.hs b/src/Shibuya/Adapter/Pgmq/Internal.hs
--- a/src/Shibuya/Adapter/Pgmq/Internal.hs
+++ b/src/Shibuya/Adapter/Pgmq/Internal.hs
@@ -202,7 +202,9 @@
                     messageId = msg.messageId,
                     visibilityTime = target
                   }
-          liftIO $ writeIORef lastVtRef updated.visibilityTime
+          case updated of
+            Nothing -> pure ()
+            Just updatedMessage -> liftIO $ writeIORef lastVtRef updatedMessage.visibilityTime
       }
 
 -- | Create an AckHandle for a message.
diff --git a/test/Shibuya/Adapter/Pgmq/ConfigSpec.hs b/test/Shibuya/Adapter/Pgmq/ConfigSpec.hs
--- a/test/Shibuya/Adapter/Pgmq/ConfigSpec.hs
+++ b/test/Shibuya/Adapter/Pgmq/ConfigSpec.hs
@@ -1,6 +1,8 @@
 module Shibuya.Adapter.Pgmq.ConfigSpec (spec) where
 
-import Pgmq.Types (parseQueueName, parseRoutingKey)
+import Data.Either (isLeft, isRight)
+import Pgmq.Types (parseRoutingKey)
+import Shibuya.Adapter.Pgmq (parseQueueName)
 import Shibuya.Adapter.Pgmq.Config
 import Test.Hspec
 
@@ -12,6 +14,7 @@
   validateConfigSpec
   deadLetterTargetSpec
   smartConstructorSpec
+  queueNameBoundarySpec
 
 -- | Tests for defaultConfig
 defaultConfigSpec :: Spec
@@ -173,3 +176,10 @@
     it "sets includeMetadata correctly" $ do
       let config = topicDeadLetter routingKey False
       config.includeMetadata `shouldBe` False
+
+queueNameBoundarySpec :: Spec
+queueNameBoundarySpec = describe "parseQueueName" $ do
+  it "accepts lowercase names and rejects uppercase and empty names" $ do
+    parseQueueName "orders" `shouldSatisfy` isRight
+    parseQueueName "Orders" `shouldSatisfy` isLeft
+    parseQueueName "" `shouldSatisfy` isLeft
diff --git a/test/Shibuya/Adapter/Pgmq/IntegrationSpec.hs b/test/Shibuya/Adapter/Pgmq/IntegrationSpec.hs
--- a/test/Shibuya/Adapter/Pgmq/IntegrationSpec.hs
+++ b/test/Shibuya/Adapter/Pgmq/IntegrationSpec.hs
@@ -26,9 +26,12 @@
 import Shibuya.Adapter.Pgmq.Config
   ( PgmqAdapterConfig (..),
     PollingConfig (..),
+    defaultConfig,
     defaultPollRetryConfig,
   )
 import Shibuya.Adapter.Pgmq.Convert (pgmqMessageToEnvelope)
+import Shibuya.Adapter.Pgmq.Internal (mkLease)
+import Shibuya.Core.Lease (Lease (..))
 import Shibuya.Core.Types (Envelope (..))
 import System.Environment (lookupEnv)
 import Test.Hspec
@@ -236,6 +239,44 @@
             }
       pure $ Vector.length msgs
     count `shouldBe` 1
+
+  it "lease extension is a no-op after the message is deleted" $ \TestFixture {pool, queueName, dlqName = _} -> do
+    runPgmqSession pool $ do
+      _ <-
+        Sessions.sendMessage $
+          SendMessage
+            { queueName = queueName,
+              messageBody = MessageBody (String "lease-race-test"),
+              delay = Just 0
+            }
+      pure ()
+
+    runAdapterIO pool $ do
+      msgs <-
+        PgmqEff.readMessage $
+          ReadMessage
+            { queueName = queueName,
+              delay = 30,
+              batchSize = Just 1,
+              conditional = Nothing
+            }
+      case Vector.uncons msgs of
+        Just (msg, _) -> do
+          lease <- mkLease (defaultConfig queueName) msg
+          _ <- PgmqEff.deleteMessage (MessageQuery queueName msg.messageId)
+          lease.leaseExtend 30
+        Nothing -> liftIO $ expectationFailure "Expected one message to construct a lease"
+
+    remaining <-
+      runPgmqSession pool $
+        Sessions.readMessage $
+          ReadMessage
+            { queueName = queueName,
+              delay = 30,
+              batchSize = Just 1,
+              conditional = Nothing
+            }
+    Vector.length remaining `shouldBe` 0
 
 -- | Retry handling tests (simulating AckRetry behavior)
 retryHandlingSpec :: SpecWith TestFixture
