diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
 # Changelog
 
+## 0.7.0.0 — 2026-06-05
+
+### Changed
+
+- Require `shibuya-core ^>=0.7.0.0`. `Envelope` now carries a
+  `headers :: Maybe Headers` field; `consumerRecordToEnvelope` populates it
+  with every Kafka header verbatim (ordered, duplicates preserved) via
+  `headersToList`. A record with no headers yields `Just []`. The parsed W3C
+  trace headers continue to appear in `traceContext` and now also appear
+  verbatim in `headers`.
+
 ## 0.6.0.0 — 2026-05-31
 
 ### Breaking Changes
diff --git a/shibuya-kafka-adapter.cabal b/shibuya-kafka-adapter.cabal
--- a/shibuya-kafka-adapter.cabal
+++ b/shibuya-kafka-adapter.cabal
@@ -1,6 +1,6 @@
 cabal-version:   3.12
 name:            shibuya-kafka-adapter
-version:         0.6.0.0
+version:         0.7.0.0
 synopsis:        Kafka adapter for the Shibuya queue processing framework
 description:
   A Shibuya adapter that integrates with Apache Kafka via kafka-effectful
@@ -61,7 +61,7 @@
     , hw-kafka-client                        >=5.3       && <6
     , hw-kafka-streamly                      ^>=0.2
     , kafka-effectful                        ^>=0.3.0.0
-    , shibuya-core                           ^>=0.6.0.0
+    , shibuya-core                           ^>=0.7.0.0
     , stm                                    ^>=2.5
     , streamly                               ^>=0.11
     , streamly-core                          ^>=0.3
@@ -108,7 +108,7 @@
     , kafka-effectful
     , process
     , random
-    , shibuya-core                           ^>=0.6.0.0
+    , shibuya-core                           ^>=0.7.0.0
     , shibuya-kafka-adapter
     , stm
     , streamly
diff --git a/src/Shibuya/Adapter/Kafka/Convert.hs b/src/Shibuya/Adapter/Kafka/Convert.hs
--- a/src/Shibuya/Adapter/Kafka/Convert.hs
+++ b/src/Shibuya/Adapter/Kafka/Convert.hs
@@ -40,6 +40,10 @@
 * @partition@: @Just (show partitionId)@
 * @enqueuedAt@: converted from Kafka timestamp if available
 * @traceContext@: extracted from @traceparent@/@tracestate@ headers
+* @headers@: every Kafka header verbatim (ordered, duplicates
+  preserved) via @headersToList@; @Just []@ when the record carried
+  no headers. The W3C trace headers appear here in addition to their
+  parsed form in @traceContext@.
 * @attempt@: 'Nothing' (Kafka does not expose a redelivery counter)
 * @attributes@: kafka-typed OTel attributes (system, partition,
   offset). The framework's @processOne@ adds these to its
@@ -60,6 +64,7 @@
         , partition = Just (Text.pack (show (unPartitionId cr.crPartition)))
         , enqueuedAt = timestampToUTCTime cr.crTimestamp
         , traceContext = extractTraceHeaders cr.crHeaders
+        , headers = Just (headersToList cr.crHeaders)
         , attempt = Nothing
         , attributes = kafkaSpanAttributes cr.crPartition cr.crOffset
         , payload = cr.crValue
diff --git a/test/Shibuya/Adapter/Kafka/ConvertTest.hs b/test/Shibuya/Adapter/Kafka/ConvertTest.hs
--- a/test/Shibuya/Adapter/Kafka/ConvertTest.hs
+++ b/test/Shibuya/Adapter/Kafka/ConvertTest.hs
@@ -87,6 +87,15 @@
             cr = mkRecord (TopicName "t") (PartitionId 0) (Offset 0) NoTimestamp hdrs Nothing Nothing
             env = consumerRecordToEnvelope cr
         assertEqual "traceContext" (Just [("traceparent", "00-abc-def-01")]) env.traceContext
+    , testCase "headers surfaced verbatim (order and duplicates preserved)" $ do
+        let raw = [("schema-id", "42"), ("x-tag", "a"), ("x-tag", "b")]
+            cr = mkRecord (TopicName "t") (PartitionId 0) (Offset 0) NoTimestamp (headersFromList raw) Nothing Nothing
+            env = consumerRecordToEnvelope cr
+        assertEqual "headers" (Just raw) env.headers
+    , testCase "empty headers surface as Just []" $ do
+        let cr = mkRecord (TopicName "t") (PartitionId 0) (Offset 0) NoTimestamp mempty Nothing Nothing
+            env = consumerRecordToEnvelope cr
+        assertEqual "headers" (Just []) env.headers
     , testCase "attributes carry messaging.system=kafka" $ do
         let cr = mkRecord (TopicName "orders") (PartitionId 2) (Offset 42) NoTimestamp mempty Nothing Nothing
             env = consumerRecordToEnvelope cr
