Subject: [PATCH 05/21] wip: add exact tiled frame runtime

From: Justin Youens <[email-masked]>
Date: Sat, 15 Aug 2026 08:20:44 -0500

---
 CMakeLists.txt                        |   7 +-
 src/backend/drm/AtomicSubmit.hpp      |  70 +++
 src/backend/drm/PageFlipBarrier.cpp   |  96 +++
 src/backend/drm/PageFlipBarrier.hpp   |  79 +++
 src/backend/drm/TiledOutputBridge.cpp |  46 +-
 src/backend/drm/TiledOutputBridge.hpp |  26 +-
 src/backend/drm/TiledRuntime.cpp      | 155 +++++
 src/backend/drm/TiledRuntime.hpp      | 854 ++++++++++++++++++++++++++
 tests/AtomicSubmit.cpp                | 121 ++++
 tests/PageFlipBarrier.cpp             | 172 ++++++
 tests/TiledOutputBridge.cpp           |  22 +-
 tests/TiledRuntime.cpp                | 794 ++++++++++++++++++++++++
 tests/TiledVisibility.cmake           |   2 +-
 13 files changed, 2424 insertions(+), 20 deletions(-)
 create mode 100644 src/backend/drm/AtomicSubmit.hpp
 create mode 100644 src/backend/drm/PageFlipBarrier.cpp
 create mode 100644 src/backend/drm/PageFlipBarrier.hpp
 create mode 100644 src/backend/drm/TiledRuntime.cpp
 create mode 100644 src/backend/drm/TiledRuntime.hpp
 create mode 100644 tests/AtomicSubmit.cpp
 create mode 100644 tests/PageFlipBarrier.cpp
 create mode 100644 tests/TiledRuntime.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 04cab199928989de3561f6db4d563332a3eaf16b..4ed2cf1f69da2d97da20689c29f6735ab7592f12 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,12 +64,14 @@ set(AQUAMARINE_TILED_PRIVATE_SOURCES
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/DRMIncarnations.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/PlaneFormats.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/PlaneViewport.cpp"
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/PageFlipBarrier.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/Tile.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TileModes.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledBackendState.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledCrtcAllocator.cpp"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledDRMIntegration.cpp"
-    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledOutputBridge.cpp")
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledOutputBridge.cpp"
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/backend/drm/TiledRuntime.cpp")
 list(REMOVE_ITEM SRCFILES ${AQUAMARINE_TILED_PRIVATE_SOURCES})
 
 add_library(aquamarine_tiled_private STATIC ${AQUAMARINE_TILED_PRIVATE_SOURCES})
@@ -209,6 +211,9 @@ addTiledPrivateTest(planeFormats "tests/PlaneFormats.cpp")
 addTiledPrivateTest(planeViewport "tests/PlaneViewport.cpp")
 addTiledPrivateTest(tiledCrtcAllocator "tests/TiledCrtcAllocator.cpp")
 addTiledPrivateTest(tiledOutputBridge "tests/TiledOutputBridge.cpp")
+addTiledPrivateTest(atomicSubmit "tests/AtomicSubmit.cpp")
+addTiledPrivateTest(pageFlipBarrier "tests/PageFlipBarrier.cpp")
+addTiledPrivateTest(tiledRuntime "tests/TiledRuntime.cpp")
 
 add_test(
   NAME tiledVisibility
diff --git a/src/backend/drm/AtomicSubmit.hpp b/src/backend/drm/AtomicSubmit.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b1a6e3c9b9a35a905a70d77b2df879ef4bc716f6
--- /dev/null
+++ b/src/backend/drm/AtomicSubmit.hpp
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <cerrno>
+#include <cstdint>
+#include <functional>
+#include <limits>
+#include <type_traits>
+#include <utility>
+#include <xf86drmMode.h>
+
+namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): established project namespace
+
+    struct SAtomicSubmitResult {
+        int      returnCode = 0;
+        int      error      = 0;
+
+        explicit operator bool() const noexcept {
+            return returnCode == 0;
+        }
+    };
+
+    // Normalizes both errno-style (-1) and direct-negative error returns. A
+    // failure never reports error zero, overflows INT_MIN, or leaks a positive
+    // return value into the errno field.
+    [[nodiscard, gnu::visibility("hidden")]] constexpr int normalizeDRMCallError(int returnCode, int capturedErrno) noexcept {
+        if (returnCode == 0)
+            return 0;
+        if (returnCode > 0)
+            return EIO;
+        if (returnCode == -1)
+            return capturedErrno > 0 ? capturedErrno : EIO;
+
+        const int64_t MAGNITUDE = -static_cast<int64_t>(returnCode);
+        return MAGNITUDE > std::numeric_limits<int>::max() ? EIO : static_cast<int>(MAGNITUDE);
+    }
+
+    // Keep the event identity numeric until the libdrm call boundary. This lets
+    // grouped commits use immutable transaction IDs without pointer ownership.
+    // The linearizer runs immediately after errno capture and before result
+    // normalization; it must be noexcept and is the caller's acceptance point.
+    template <typename FSubmit, typename FLinearize>
+    [[nodiscard, gnu::visibility("hidden")]] SAtomicSubmitResult
+    submitAtomicRequest(int drmFD, drmModeAtomicReqPtr request, uint32_t flags, uintptr_t userData, FSubmit&& submit,
+                        FLinearize&& linearize) noexcept(std::is_nothrow_invocable_r_v<int, FSubmit&&, int, drmModeAtomicReqPtr, uint32_t, void*> &&
+                                                         std::is_nothrow_invocable_v<FLinearize&&, int>) {
+        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr): required libdrm opaque-token boundary
+        void* const OPAQUE_USER_DATA = userData == 0 ? nullptr : reinterpret_cast<void*>(userData);
+        errno                        = 0;
+        const int RETURN_CODE        = std::invoke(std::forward<FSubmit>(submit), drmFD, request, flags, OPAQUE_USER_DATA);
+        const int CALL_ERRNO         = errno;
+        std::invoke(std::forward<FLinearize>(linearize), RETURN_CODE);
+        return {.returnCode = RETURN_CODE, .error = normalizeDRMCallError(RETURN_CODE, CALL_ERRNO)};
+    }
+
+    template <typename FSubmit>
+    [[nodiscard, gnu::visibility("hidden")]] SAtomicSubmitResult
+    submitAtomicRequest(int drmFD, drmModeAtomicReqPtr request, uint32_t flags, uintptr_t userData,
+                        FSubmit&& submit) noexcept(std::is_nothrow_invocable_r_v<int, FSubmit&&, int, drmModeAtomicReqPtr, uint32_t, void*>) {
+        // Keep this legacy production caller independent from the private
+        // linearizer overload so a non-hidden translation unit cannot emit its
+        // callback/lambda machinery into the dynamic ABI.
+        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr): required libdrm opaque-token boundary
+        void* const OPAQUE_USER_DATA = userData == 0 ? nullptr : reinterpret_cast<void*>(userData);
+        errno                        = 0;
+        const int RETURN_CODE        = std::forward<FSubmit>(submit)(drmFD, request, flags, OPAQUE_USER_DATA);
+        const int CALL_ERRNO         = errno;
+        return {.returnCode = RETURN_CODE, .error = normalizeDRMCallError(RETURN_CODE, CALL_ERRNO)};
+    }
+
+}
diff --git a/src/backend/drm/PageFlipBarrier.cpp b/src/backend/drm/PageFlipBarrier.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90f2e38246d09f3171dd4a542324d1b36a5f1d13
--- /dev/null
+++ b/src/backend/drm/PageFlipBarrier.cpp
@@ -0,0 +1,96 @@
+#include "PageFlipBarrier.hpp"
+
+#include <algorithm>
+
+using namespace Aquamarine::NDRM;
+
+CPageFlipBarrier::CPageFlipBarrier(uint64_t transactionId, uint64_t topologyGeneration, std::span<const uint32_t> expectedCrtcs) :
+    m_transactionId(transactionId), m_topologyGeneration(topologyGeneration), m_expectedCrtcs(expectedCrtcs.begin(), expectedCrtcs.end()) {
+    std::ranges::sort(m_expectedCrtcs);
+    m_received.reserve(m_expectedCrtcs.size());
+
+    m_valid = m_transactionId != 0 && m_topologyGeneration != 0 && !m_expectedCrtcs.empty() && std::ranges::find(m_expectedCrtcs, 0U) == m_expectedCrtcs.end() &&
+        std::ranges::adjacent_find(m_expectedCrtcs) == m_expectedCrtcs.end();
+}
+
+ePageFlipBarrierResult CPageFlipBarrier::record(uint64_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept {
+    if (!m_valid)
+        return ePageFlipBarrierResult::INVALID;
+    if (transactionId != m_transactionId)
+        return ePageFlipBarrierResult::STALE_TRANSACTION;
+    if (m_cancelled)
+        return ePageFlipBarrierResult::CANCELLED;
+    if (m_complete)
+        return ePageFlipBarrierResult::ALREADY_COMPLETE;
+
+    const auto EXPECTED = std::ranges::lower_bound(m_expectedCrtcs, crtcId);
+    if (EXPECTED == m_expectedCrtcs.end() || *EXPECTED != crtcId)
+        return ePageFlipBarrierResult::UNEXPECTED_CRTC;
+
+    const auto RECEIVED = std::ranges::lower_bound(m_received, crtcId, {}, &SPageFlipEvidence::crtcId);
+    if (RECEIVED != m_received.end() && RECEIVED->crtcId == crtcId)
+        return ePageFlipBarrierResult::DUPLICATE_EVENT;
+    if (m_received.size() >= m_received.capacity())
+        return ePageFlipBarrierResult::INVALID;
+
+    m_received.insert(RECEIVED, {.crtcId = crtcId, .sequence = sequence, .timestampNs = timestampNs});
+    if (m_received.size() != m_expectedCrtcs.size())
+        return ePageFlipBarrierResult::RECORDED;
+
+    m_complete = true;
+    return ePageFlipBarrierResult::COMPLETED;
+}
+
+ePageFlipBarrierResult CPageFlipBarrier::cancel() noexcept {
+    if (!m_valid)
+        return ePageFlipBarrierResult::INVALID;
+    if (m_complete)
+        return ePageFlipBarrierResult::ALREADY_COMPLETE;
+
+    m_cancelled = true;
+    return ePageFlipBarrierResult::CANCELLED;
+}
+
+bool CPageFlipBarrier::valid() const noexcept {
+    return m_valid;
+}
+
+bool CPageFlipBarrier::complete() const noexcept {
+    return m_complete;
+}
+
+bool CPageFlipBarrier::cancelled() const noexcept {
+    return m_cancelled;
+}
+
+uint64_t CPageFlipBarrier::transactionId() const noexcept {
+    return m_transactionId;
+}
+
+uint64_t CPageFlipBarrier::topologyGeneration() const noexcept {
+    return m_topologyGeneration;
+}
+
+const std::vector<uint32_t>& CPageFlipBarrier::expectedCrtcs() const noexcept {
+    return m_expectedCrtcs;
+}
+
+const std::vector<SPageFlipEvidence>& CPageFlipBarrier::received() const noexcept {
+    return m_received;
+}
+
+size_t CPageFlipBarrier::receivedCapacity() const noexcept {
+    return m_received.capacity();
+}
+
+std::optional<SPageFlipTiming> CPageFlipBarrier::timing() const noexcept {
+    if (!m_complete)
+        return std::nullopt;
+
+    const auto [EARLIEST, LATEST] = std::ranges::minmax_element(m_received, {}, &SPageFlipEvidence::timestampNs);
+    return SPageFlipTiming{
+        .earliestTimestampNs = EARLIEST->timestampNs,
+        .latestTimestampNs   = LATEST->timestampNs,
+        .skewNs              = LATEST->timestampNs - EARLIEST->timestampNs,
+    };
+}
diff --git a/src/backend/drm/PageFlipBarrier.hpp b/src/backend/drm/PageFlipBarrier.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..25d4af405fc4fb7cf135f64b6e01bb51e8fdbedd
--- /dev/null
+++ b/src/backend/drm/PageFlipBarrier.hpp
@@ -0,0 +1,79 @@
+#pragma once
+
+#include <cstddef>
+#include <cstdint>
+#include <optional>
+#include <span>
+#include <vector>
+
+namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): established project namespace
+
+    struct SPageFlipEvidence {
+        uint32_t crtcId      = 0;
+        uint32_t sequence    = 0;
+        uint64_t timestampNs = 0;
+
+        bool     operator==(const SPageFlipEvidence&) const = default;
+    };
+
+    struct SPageFlipTiming {
+        uint64_t earliestTimestampNs = 0;
+        uint64_t latestTimestampNs   = 0;
+        uint64_t skewNs              = 0;
+
+        bool     operator==(const SPageFlipTiming&) const = default;
+    };
+
+    enum class ePageFlipBarrierResult : uint8_t {
+        INVALID = 0,
+        RECORDED,
+        COMPLETED,
+        STALE_TRANSACTION,
+        UNEXPECTED_CRTC,
+        DUPLICATE_EVENT,
+        ALREADY_COMPLETE,
+        CANCELLED,
+    };
+
+    class CPageFlipBarrier {
+      public:
+        // The definition is immutable after construction. The barrier is pinned
+        // to its runtime slot so authority and constructor-reserved capacity
+        // cannot be duplicated or lost through copying/moving. Invalid values
+        // create an inert barrier whose record/cancel operations return INVALID.
+        CPageFlipBarrier(uint64_t transactionId, uint64_t topologyGeneration, std::span<const uint32_t> expectedCrtcs);
+        CPageFlipBarrier(const CPageFlipBarrier&)            = delete;
+        CPageFlipBarrier& operator=(const CPageFlipBarrier&) = delete;
+        CPageFlipBarrier(CPageFlipBarrier&&)                 = delete;
+        CPageFlipBarrier& operator=(CPageFlipBarrier&&)      = delete;
+
+        // COMPLETED is returned exactly once, for the final distinct expected
+        // CRTC event. Later events return ALREADY_COMPLETE.
+        [[nodiscard]] ePageFlipBarrierResult record(uint64_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept;
+        // Cancellation is idempotent and cannot transition the barrier to complete.
+        [[nodiscard]] ePageFlipBarrierResult cancel() noexcept;
+
+        [[nodiscard]] bool                   valid() const noexcept;
+        [[nodiscard]] bool                   complete() const noexcept;
+        [[nodiscard]] bool                   cancelled() const noexcept;
+        [[nodiscard]] uint64_t               transactionId() const noexcept;
+        [[nodiscard]] uint64_t               topologyGeneration() const noexcept;
+        // Both collections are sorted by CRTC ID, independent of input/event order.
+        [[nodiscard]] const std::vector<uint32_t>&          expectedCrtcs() const noexcept;
+        [[nodiscard]] const std::vector<SPageFlipEvidence>& received() const noexcept;
+        // Recording never grows beyond this constructor-reserved capacity.
+        [[nodiscard]] size_t receivedCapacity() const noexcept;
+        // Timing exists only after completion. Skew is latest - earliest.
+        [[nodiscard]] std::optional<SPageFlipTiming> timing() const noexcept;
+
+      private:
+        uint64_t                       m_transactionId      = 0;
+        uint64_t                       m_topologyGeneration = 0;
+        std::vector<uint32_t>          m_expectedCrtcs;
+        std::vector<SPageFlipEvidence> m_received;
+        bool                           m_valid     = false;
+        bool                           m_complete  = false;
+        bool                           m_cancelled = false;
+    };
+
+}
diff --git a/src/backend/drm/TiledOutputBridge.cpp b/src/backend/drm/TiledOutputBridge.cpp
index e46831de54f2edec5346795533fc3a1ce44904dc..8b0b3f8c1c7eeacb953f65223ab712168c59e3e5 100644
--- a/src/backend/drm/TiledOutputBridge.cpp
+++ b/src/backend/drm/TiledOutputBridge.cpp
@@ -206,9 +206,15 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
         }
 
         static CGroupProjection group(eGroupProjection projection, PScanGroupDefinition scanDefinition, CSharedPointer<const CGroupDefinition> allocationDefinition,
-                                      PScanModeDefinition modeDefinition, CSharedPointer<const CModeSet> modeSet, CSharedPointer<const CPlan> plan,
-                                      std::optional<size_t> allocationIndex) {
-            return CGroupProjection{projection,     std::move(scanDefinition), std::move(allocationDefinition), std::move(modeDefinition), std::move(modeSet), std::move(plan),
+                                      PScanModeDefinition modeDefinition, CSharedPointer<const CModeSet> modeSet, POutputDefinitionIdentity definitionIdentity,
+                                      CSharedPointer<const CPlan> plan, std::optional<size_t> allocationIndex) {
+            return CGroupProjection{projection,
+                                    std::move(scanDefinition),
+                                    std::move(allocationDefinition),
+                                    std::move(modeDefinition),
+                                    std::move(modeSet),
+                                    std::move(definitionIdentity),
+                                    std::move(plan),
                                     allocationIndex};
         }
 
@@ -257,7 +263,7 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
                 if (TOPOLOGY.kind == NTiling::eTileGroupKind::DRIVER_UNIFIED) {
                     if (allocationByScanDefinition.contains(DEFINITION.impl_) || findExactModes(SCAN, DEFINITION))
                         return {.error = eBuildError::INVALID_PROJECTION};
-                    groups.push_back(group(eGroupProjection::DRIVER_UNIFIED, DEFINITION, {}, {}, {}, plan, std::nullopt));
+                    groups.push_back(group(eGroupProjection::DRIVER_UNIFIED, DEFINITION, {}, {}, {}, {}, plan, std::nullopt));
                     projectionByDefinition.emplace(DEFINITION.impl_, eGroupProjection::DRIVER_UNIFIED);
                     continue;
                 }
@@ -273,20 +279,26 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
                 const auto& PLAN_GROUP = plan->groups().at(ALLOCATION->second);
                 const auto  PROJECTION =
                     PLAN_GROUP.status() == NTiledCrtcAllocator::eGroupStatus::ALLOCATED ? eGroupProjection::MULTI_STREAM_ALLOCATED : eGroupProjection::MULTI_STREAM_FALLBACK;
-                CSharedPointer<const CModeSet> reusable;
-                if (const auto* PRIOR = reusableGroup(previous, DEFINITION); PRIOR && PRIOR->modeSet()) {
-                    if (sameOwner(PRIOR->modeDefinition(), *MODES)) {
-                        reusable = PRIOR->modeSet();
-                    } else if (equivalentModes(*PRIOR->modeSet(), *MODES)) {
-                        reusable = PRIOR->modeSet();
-                    }
+                const auto*               PRIOR      = reusableGroup(previous, DEFINITION);
+                const bool                EQUIVALENT = PRIOR && PRIOR->modeSet() && equivalentModes(*PRIOR->modeSet(), *MODES);
+
+                POutputDefinitionIdentity definitionIdentity;
+                if (EQUIVALENT && PRIOR->definitionIdentity()) {
+                    definitionIdentity = PRIOR->definitionIdentity();
+                } else {
+                    CSharedPointer<COutputDefinitionIdentity> freshIdentity{new COutputDefinitionIdentity{}};
+                    definitionIdentity = std::move(freshIdentity);
                 }
 
+                CSharedPointer<const CModeSet> reusable;
+                if (EQUIVALENT)
+                    reusable = PRIOR->modeSet();
+
                 auto modes =
                     sameOwner(reusable ? reusable->definition() : PScanModeDefinition{}, *MODES) && modeOwnersMatchDefinition(*reusable) ? reusable : modeSet(*MODES, reusable);
                 if (!modes)
                     return {.error = eBuildError::INVALID_PROJECTION};
-                groups.push_back(group(PROJECTION, DEFINITION, PLAN_GROUP.definition(), *MODES, std::move(modes), plan, ALLOCATION->second));
+                groups.push_back(group(PROJECTION, DEFINITION, PLAN_GROUP.definition(), *MODES, std::move(modes), std::move(definitionIdentity), plan, ALLOCATION->second));
                 projectionByDefinition.emplace(DEFINITION.impl_, PROJECTION);
             }
 
@@ -385,10 +397,10 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
     }
 
     CGroupProjection::CGroupProjection(eGroupProjection projection, PScanGroupDefinition scanDefinition, CSharedPointer<const CGroupDefinition> allocationDefinition,
-                                       PScanModeDefinition modeDefinition, CSharedPointer<const CModeSet> modeSet, CSharedPointer<const CPlan> plan,
-                                       std::optional<size_t> allocationIndex) :
+                                       PScanModeDefinition modeDefinition, CSharedPointer<const CModeSet> modeSet, POutputDefinitionIdentity definitionIdentity,
+                                       CSharedPointer<const CPlan> plan, std::optional<size_t> allocationIndex) :
         m_projection(projection), m_scanDefinition(std::move(scanDefinition)), m_allocationDefinition(std::move(allocationDefinition)), m_modeDefinition(std::move(modeDefinition)),
-        m_modeSet(std::move(modeSet)), m_plan(std::move(plan)), m_allocationIndex(allocationIndex) {}
+        m_modeSet(std::move(modeSet)), m_definitionIdentity(std::move(definitionIdentity)), m_plan(std::move(plan)), m_allocationIndex(allocationIndex) {}
 
     eGroupProjection CGroupProjection::projection() const {
         return m_projection;
@@ -410,6 +422,10 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
         return m_modeSet;
     }
 
+    const POutputDefinitionIdentity& CGroupProjection::definitionIdentity() const {
+        return m_definitionIdentity;
+    }
+
     std::optional<std::reference_wrapper<const CGroupAllocation>> CGroupProjection::allocation() const {
         if (!m_plan || !m_allocationIndex || *m_allocationIndex >= m_plan->groups().size())
             return std::nullopt;
diff --git a/src/backend/drm/TiledOutputBridge.hpp b/src/backend/drm/TiledOutputBridge.hpp
index 5b2aea360bc4e592a73ddcd4dcb6736f5f2ad60b..ef99fc44cfa8f15f98b4113b9c5b1559f643e192 100644
--- a/src/backend/drm/TiledOutputBridge.hpp
+++ b/src/backend/drm/TiledOutputBridge.hpp
@@ -34,6 +34,27 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
     using NTiledScan::PScanModeDefinition;
 
     class COutputBridgeAssembler;
+    class COutputBridgeObservation;
+    class COutputDefinitionIdentity;
+
+    using POutputBridgeObservation  = CSharedPointer<const COutputBridgeObservation>;
+    using POutputDefinitionIdentity = CSharedPointer<const COutputDefinitionIdentity>;
+
+    // Stable identity for one validated multi-stream topology and its exact
+    // ordered logical/physical mode definition. Only the bridge may mint or
+    // reconcile this token; it deliberately carries no generation freshness.
+    class AQ_TILED_OUTPUT_BRIDGE_PRIVATE COutputDefinitionIdentity final {
+      public:
+        COutputDefinitionIdentity(const COutputDefinitionIdentity&)            = delete;
+        COutputDefinitionIdentity(COutputDefinitionIdentity&&)                 = delete;
+        COutputDefinitionIdentity& operator=(const COutputDefinitionIdentity&) = delete;
+        COutputDefinitionIdentity& operator=(COutputDefinitionIdentity&&)      = delete;
+
+      private:
+        COutputDefinitionIdentity() = default;
+
+        friend class COutputBridgeAssembler;
+    };
 
     struct AQ_TILED_OUTPUT_BRIDGE_PRIVATE SModeBinding {
         CSharedPointer<SOutputMode> outputMode;
@@ -96,17 +117,20 @@ namespace Aquamarine::NDRM::NTiledOutputBridge { // NOLINT(readability-identifie
         [[nodiscard]] const CSharedPointer<const CGroupDefinition>&                 allocationDefinition() const;
         [[nodiscard]] const PScanModeDefinition&                                    modeDefinition() const;
         [[nodiscard]] const CSharedPointer<const CModeSet>&                         modeSet() const;
+        [[nodiscard]] const POutputDefinitionIdentity&                              definitionIdentity() const;
         [[nodiscard]] std::optional<std::reference_wrapper<const CGroupAllocation>> allocation() const;
 
       private:
         CGroupProjection(eGroupProjection projection, PScanGroupDefinition scanDefinition, CSharedPointer<const CGroupDefinition> allocationDefinition,
-                         PScanModeDefinition modeDefinition, CSharedPointer<const CModeSet> modeSet, CSharedPointer<const CPlan> plan, std::optional<size_t> allocationIndex);
+                         PScanModeDefinition modeDefinition, CSharedPointer<const CModeSet> modeSet, POutputDefinitionIdentity definitionIdentity, CSharedPointer<const CPlan> plan,
+                         std::optional<size_t> allocationIndex);
 
         eGroupProjection                       m_projection = eGroupProjection::DRIVER_UNIFIED;
         PScanGroupDefinition                   m_scanDefinition;
         CSharedPointer<const CGroupDefinition> m_allocationDefinition;
         PScanModeDefinition                    m_modeDefinition;
         CSharedPointer<const CModeSet>         m_modeSet;
+        POutputDefinitionIdentity              m_definitionIdentity;
         CSharedPointer<const CPlan>            m_plan;
         std::optional<size_t>                  m_allocationIndex;
 
diff --git a/src/backend/drm/TiledRuntime.cpp b/src/backend/drm/TiledRuntime.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ecb6781f404b2a89b86e53dafff501d900a3ca1
--- /dev/null
+++ b/src/backend/drm/TiledRuntime.cpp
@@ -0,0 +1,155 @@
+#include "TiledRuntime.hpp"
+
+#include <algorithm>
+
+using namespace Aquamarine::NDRM;
+
+CTiledFlipReservationRegistry::~CTiledFlipReservationRegistry() noexcept {
+    if (!readyForDestruction())
+        std::terminate();
+}
+
+STiledFlipReservationResult CTiledFlipReservationRegistry::reserveAll(const STiledFlipRoute& route) {
+    if (m_shutdown)
+        return {.error = eTiledReservationError::SHUTDOWN};
+
+    if (!route.valid())
+        return {.error = eTiledReservationError::INVALID_ROUTE};
+
+    if (m_transactions.contains(route.transactionId))
+        return {.error = eTiledReservationError::TOKEN_CONFLICT};
+
+    if (std::ranges::any_of(m_crtcSlots, [&route](const auto& entry) { return entry.second.retiredTransaction == route.transactionId; }))
+        return {.error = eTiledReservationError::RETIRED_TOKEN};
+
+    for (const auto CRTC_ID : route.crtcIds) {
+        const auto SLOT = m_crtcSlots.find(CRTC_ID);
+        if (SLOT != m_crtcSlots.end() && SLOT->second.activeTransaction != 0)
+            return {.error = eTiledReservationError::CRTC_CONFLICT};
+    }
+
+    if (m_nextCookie == 0)
+        m_nextCookie = 1;
+    const STiledFlipReservation RESERVATION(route.transactionId, m_nextCookie, route.generation, route.crtcIds.size());
+
+    // Build complete successor maps first. A logical conflict or allocation
+    // failure therefore leaves the live registry unchanged.
+    auto transactions = m_transactions;
+    auto crtcSlots    = m_crtcSlots;
+    transactions.emplace(route.transactionId, SReservationRecord{.reservation = RESERVATION, .crtcIds = route.crtcIds});
+    for (const auto CRTC_ID : route.crtcIds)
+        crtcSlots[CRTC_ID].activeTransaction = route.transactionId;
+
+    m_transactions.swap(transactions);
+    m_crtcSlots.swap(crtcSlots);
+    ++m_nextCookie;
+    return {.reservation = RESERVATION};
+}
+
+bool CTiledFlipReservationRegistry::matches(const STiledFlipReservation& reservation, const STiledFlipRoute& route) const noexcept {
+    const auto RECORD = m_transactions.find(reservation.m_transactionId);
+    return RECORD != m_transactions.end() && RECORD->second.reservation == reservation && route.transactionId == reservation.m_transactionId &&
+        route.generation == reservation.m_generation && route.crtcIds == RECORD->second.crtcIds;
+}
+
+bool CTiledFlipReservationRegistry::accept(const STiledFlipReservation& reservation) noexcept {
+    const auto RECORD = m_transactions.find(reservation.m_transactionId);
+    if (RECORD == m_transactions.end() || RECORD->second.reservation != reservation || RECORD->second.state != eTiledReservationState::RESERVED)
+        return false;
+
+    RECORD->second.state = eTiledReservationState::IN_FLIGHT;
+    m_everAccepted       = true;
+    return true;
+}
+
+bool CTiledFlipReservationRegistry::rollback(const STiledFlipReservation& reservation) noexcept {
+    const auto RECORD = m_transactions.find(reservation.m_transactionId);
+    if (RECORD == m_transactions.end() || RECORD->second.reservation != reservation || RECORD->second.state != eTiledReservationState::RESERVED)
+        return false;
+
+    for (const auto CRTC_ID : RECORD->second.crtcIds) {
+        const auto SLOT = m_crtcSlots.find(CRTC_ID);
+        if (SLOT != m_crtcSlots.end() && SLOT->second.activeTransaction == reservation.m_transactionId)
+            SLOT->second.activeTransaction = 0;
+    }
+    m_transactions.erase(RECORD);
+    return true;
+}
+
+bool CTiledFlipReservationRegistry::quiesce(const STiledFlipReservation& reservation) noexcept {
+    const auto RECORD = m_transactions.find(reservation.m_transactionId);
+    if (RECORD == m_transactions.end() || RECORD->second.reservation != reservation || RECORD->second.state == eTiledReservationState::RESERVED)
+        return false;
+    if (RECORD->second.state == eTiledReservationState::QUIESCED)
+        return true;
+
+    RECORD->second.state = eTiledReservationState::QUIESCED;
+    return true;
+}
+
+bool CTiledFlipReservationRegistry::retire(const STiledFlipReservation& reservation) noexcept {
+    const auto RECORD = m_transactions.find(reservation.m_transactionId);
+    if (RECORD == m_transactions.end() || RECORD->second.reservation != reservation || RECORD->second.state == eTiledReservationState::RESERVED)
+        return false;
+
+    for (const auto CRTC_ID : RECORD->second.crtcIds) {
+        const auto SLOT = m_crtcSlots.find(CRTC_ID);
+        if (SLOT == m_crtcSlots.end() || SLOT->second.activeTransaction != reservation.m_transactionId)
+            return false;
+    }
+
+    for (const auto CRTC_ID : RECORD->second.crtcIds) {
+        auto& SLOT              = m_crtcSlots.find(CRTC_ID)->second;
+        SLOT.activeTransaction  = 0;
+        SLOT.retiredTransaction = reservation.m_transactionId;
+    }
+    m_transactions.erase(RECORD);
+    return true;
+}
+
+eTiledRouteEventResult CTiledFlipReservationRegistry::routeEvent(uintptr_t transactionId, uint32_t crtcId) const noexcept {
+    if (transactionId == 0 || crtcId == 0)
+        return eTiledRouteEventResult::NOT_OWNED;
+
+    const auto RECORD = m_transactions.find(transactionId);
+    if (RECORD != m_transactions.end()) {
+        if (!std::ranges::binary_search(RECORD->second.crtcIds, crtcId))
+            return eTiledRouteEventResult::UNEXPECTED_CRTC;
+        return RECORD->second.state == eTiledReservationState::RESERVED ? eTiledRouteEventResult::RESERVED : eTiledRouteEventResult::ROUTABLE;
+    }
+
+    const auto SLOT = m_crtcSlots.find(crtcId);
+    if (SLOT != m_crtcSlots.end() && (SLOT->second.activeTransaction != 0 || SLOT->second.retiredTransaction == transactionId))
+        return eTiledRouteEventResult::STALE_TOKEN;
+
+    return eTiledRouteEventResult::NOT_OWNED;
+}
+
+std::optional<eTiledReservationState> CTiledFlipReservationRegistry::state(const STiledFlipReservation& reservation) const noexcept {
+    const auto RECORD = m_transactions.find(reservation.m_transactionId);
+    if (RECORD == m_transactions.end() || RECORD->second.reservation != reservation)
+        return std::nullopt;
+    return RECORD->second.state;
+}
+
+size_t CTiledFlipReservationRegistry::transactionCount() const noexcept {
+    return m_transactions.size();
+}
+
+size_t CTiledFlipReservationRegistry::claimedCrtcCount() const noexcept {
+    return static_cast<size_t>(std::ranges::count_if(m_crtcSlots, [](const auto& entry) { return entry.second.activeTransaction != 0; }));
+}
+
+bool CTiledFlipReservationRegistry::shutdown(eTiledRegistryShutdownProof proof) noexcept {
+    if (proof != eTiledRegistryShutdownProof::DRM_DEVICE_GONE && proof != eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS)
+        return false;
+
+    m_transactions.clear();
+    m_crtcSlots.clear();
+    m_shutdown = true;
+    return true;
+}
+
+bool CTiledFlipReservationRegistry::readyForDestruction() const noexcept {
+    return m_shutdown || (!m_everAccepted && m_transactions.empty());
+}
diff --git a/src/backend/drm/TiledRuntime.hpp b/src/backend/drm/TiledRuntime.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..66160dc3aa257c0294f153ed804d4fb19980cb71
--- /dev/null
+++ b/src/backend/drm/TiledRuntime.hpp
@@ -0,0 +1,854 @@
+#pragma once
+
+#include "PageFlipBarrier.hpp"
+#include "TiledOutputBridge.hpp"
+
+#include <algorithm>
+#include <concepts>
+#include <cstddef>
+#include <cstdint>
+#include <exception>
+#include <map>
+#include <optional>
+#include <span>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): established project namespace
+
+    // This source-private state machine consumes event routes and retains
+    // ownership; it is not a production KMS adapter. TiledAtomic still emits
+    // ALLOW_MODESET requests with fresh MODE_ID blobs, so ordinary per-frame
+    // grouped page flips, group disable/restore, and live property integration
+    // remain explicit runtime blockers.
+
+    enum class eTiledRuntimeState : uint8_t {
+        STAGED = 0,
+        PUBLISHED_DISABLED,
+        PUBLISHED_IDLE,
+        PUBLISHED_IN_FLIGHT,
+        QUIESCED,
+        TEARDOWN,
+    };
+
+    enum class eTiledQuiesceReason : uint8_t {
+        NONE = 0,
+        INCOMPLETE_SCAN,
+        INVALID_TOPOLOGY,
+        SESSION_INACTIVE,
+        OUTPUT_DISABLED,
+        CRTC_REASSIGNED,
+        EVENT_TIMEOUT,
+        EVENT_INVARIANT,
+        BACKEND_TEARDOWN,
+    };
+
+    enum class eTiledReservationState : uint8_t {
+        RESERVED = 0,
+        IN_FLIGHT,
+        QUIESCED,
+    };
+
+    enum class eTiledReservationError : uint8_t {
+        NONE = 0,
+        INVALID_ROUTE,
+        SHUTDOWN,
+        TOKEN_CONFLICT,
+        RETIRED_TOKEN,
+        CRTC_CONFLICT,
+    };
+
+    enum class eTiledRegistryShutdownProof : uint8_t {
+        NONE = 0,
+        DRM_DEVICE_GONE,
+        BACKEND_NO_CALLBACKS,
+    };
+
+    enum class eTiledRouteEventResult : uint8_t {
+        NOT_OWNED = 0,
+        RESERVED,
+        ROUTABLE,
+        STALE_TOKEN,
+        UNEXPECTED_CRTC,
+    };
+
+    // Integration precondition: singular and grouped submissions must draw
+    // transactionId from the same backend-wide monotonic allocator. That
+    // allocator must never wrap or reuse a nonzero token, must report exhaustion
+    // by returning zero, and every caller must treat zero as a hard failure.
+    // The registry's bounded per-CRTC tombstones are safe only under that rule.
+    struct STiledFlipRoute {
+        uintptr_t             transactionId = 0;
+        uint64_t              generation    = 0;
+        std::vector<uint32_t> crtcIds;
+
+        // Routes are canonical snapshots. Consumers reject, rather than
+        // normalize, an out-of-order member set so the reserved slots and the
+        // barrier definition always describe the exact producer-owned route.
+        [[nodiscard]] bool valid() const noexcept {
+            return transactionId != 0 && generation != 0 && !crtcIds.empty() && std::ranges::find(crtcIds, 0U) == crtcIds.end() && std::ranges::is_sorted(crtcIds) &&
+                std::ranges::adjacent_find(crtcIds) == crtcIds.end();
+        }
+
+        bool operator==(const STiledFlipRoute&) const = default;
+    };
+
+    class CTiledFlipReservationRegistry;
+    template <typename TOwner>
+    class CTiledFrameRuntime;
+
+    struct STiledFlipReservation {
+      public:
+        STiledFlipReservation() noexcept = default;
+
+        explicit operator bool() const noexcept {
+            return m_transactionId != 0 && m_cookie != 0 && m_generation != 0 && m_memberCount != 0;
+        }
+
+        bool                    operator==(const STiledFlipReservation&) const = default;
+
+        [[nodiscard]] uintptr_t transactionId() const noexcept {
+            return m_transactionId;
+        }
+
+        [[nodiscard]] uint64_t generation() const noexcept {
+            return m_generation;
+        }
+
+        [[nodiscard]] size_t memberCount() const noexcept {
+            return m_memberCount;
+        }
+
+      private:
+        STiledFlipReservation(uintptr_t transactionId, uint64_t cookie, uint64_t generation, size_t memberCount) noexcept :
+            m_transactionId(transactionId), m_cookie(cookie), m_generation(generation), m_memberCount(memberCount) {}
+
+        uintptr_t m_transactionId = 0;
+        uint64_t  m_cookie        = 0;
+        uint64_t  m_generation    = 0;
+        size_t    m_memberCount   = 0;
+
+        friend class CTiledFlipReservationRegistry;
+        template <typename TOwner>
+        friend class CTiledFrameRuntime;
+    };
+
+    struct STiledFlipReservationResult {
+        STiledFlipReservation  reservation;
+        eTiledReservationError error = eTiledReservationError::NONE;
+
+        explicit               operator bool() const noexcept {
+            return static_cast<bool>(reservation) && error == eTiledReservationError::NONE;
+        }
+    };
+
+    // A source-private ownership registry for page-flip tokens. reserveAll()
+    // publishes either every member slot or none. RESERVED entries deliberately
+    // do not route events; the caller publishes them only after the accepted
+    // transaction has been installed in its runtime. Once any route is accepted,
+    // destroying the registry requires shutdown() with proof that callback
+    // ingress is impossible; retiring the route alone is not that proof.
+    class CTiledFlipReservationRegistry {
+      public:
+        CTiledFlipReservationRegistry()                                                = default;
+        CTiledFlipReservationRegistry(const CTiledFlipReservationRegistry&)            = delete;
+        CTiledFlipReservationRegistry& operator=(const CTiledFlipReservationRegistry&) = delete;
+        CTiledFlipReservationRegistry(CTiledFlipReservationRegistry&&)                 = delete;
+        CTiledFlipReservationRegistry& operator=(CTiledFlipReservationRegistry&&)      = delete;
+
+        ~CTiledFlipReservationRegistry() noexcept;
+
+        [[nodiscard]] STiledFlipReservationResult reserveAll(const STiledFlipRoute& route);
+        [[nodiscard]] bool                        matches(const STiledFlipReservation& reservation, const STiledFlipRoute& route) const noexcept;
+        [[nodiscard]] bool                        accept(const STiledFlipReservation& reservation) noexcept;
+        [[nodiscard]] bool                        rollback(const STiledFlipReservation& reservation) noexcept;
+        [[nodiscard]] bool                        quiesce(const STiledFlipReservation& reservation) noexcept;
+        // retire() is valid only after completion or an external retirement
+        // proof. It leaves one bounded stale-token tombstone per known CRTC.
+        [[nodiscard]] bool                                  retire(const STiledFlipReservation& reservation) noexcept;
+
+        [[nodiscard]] eTiledRouteEventResult                routeEvent(uintptr_t transactionId, uint32_t crtcId) const noexcept;
+        [[nodiscard]] std::optional<eTiledReservationState> state(const STiledFlipReservation& reservation) const noexcept;
+        [[nodiscard]] size_t                                transactionCount() const noexcept;
+        [[nodiscard]] size_t                                claimedCrtcCount() const noexcept;
+        [[nodiscard]] bool                                  shutdown(eTiledRegistryShutdownProof proof) noexcept;
+        [[nodiscard]] bool                                  readyForDestruction() const noexcept;
+
+      private:
+        struct SReservationRecord {
+            STiledFlipReservation  reservation;
+            std::vector<uint32_t>  crtcIds;
+            eTiledReservationState state = eTiledReservationState::RESERVED;
+        };
+
+        struct SCrtcSlot {
+            uintptr_t activeTransaction  = 0;
+            uintptr_t retiredTransaction = 0;
+        };
+
+        std::map<uintptr_t, SReservationRecord> m_transactions;
+        std::map<uint32_t, SCrtcSlot>           m_crtcSlots;
+        uint64_t                                m_nextCookie   = 1;
+        bool                                    m_everAccepted = false;
+        bool                                    m_shutdown     = false;
+    };
+
+    enum class eTiledRuntimePrepareError : uint8_t {
+        NONE = 0,
+        INVALID_STATE,
+        ALREADY_PREPARED,
+        INVALID_DEADLINE,
+        INVALID_FRAME,
+        INVALID_ROUTE,
+    };
+
+    enum class eTiledEventDisposition : uint8_t {
+        NO_EFFECT = 0,
+        NOT_OWNED,
+        RECORDED,
+        COMPLETED,
+        DUPLICATE,
+        STALE,
+        UNEXPECTED_CRTC,
+        ALREADY_COMPLETE,
+        QUIESCED,
+        TIMED_OUT,
+    };
+
+    enum class eTiledSuccessorResult : uint8_t {
+        STAGED = 0,
+        ADOPTED,
+        STALE_GENERATION,
+        INVALID_PLAN,
+        NON_EQUIVALENT,
+        INVALID_STATE,
+    };
+
+    enum class eTiledRetirementProof : uint8_t {
+        NONE = 0,
+        ATOMIC_DISABLE_COMPLETED,
+        DRM_DEVICE_GONE,
+        BACKEND_TEARDOWN_NO_CALLBACKS,
+    };
+
+    struct STiledMemberFrameState {
+        uint32_t crtcId           = 0;
+        uint64_t frontFramebuffer = 0;
+        uint64_t frontBuffer      = 0;
+        uint64_t backFramebuffer  = 0;
+        uint64_t backBuffer       = 0;
+        uint64_t lastFramebuffer  = 0;
+        uint64_t lastBuffer       = 0;
+
+        bool     operator==(const STiledMemberFrameState&) const = default;
+    };
+
+    struct STiledPresentationSample {
+        uintptr_t       transactionId   = 0;
+        uint64_t        generation      = 0;
+        uint32_t        primarySequence = 0;
+        uint64_t        timestampNs     = 0;
+        SPageFlipTiming timing;
+
+        bool            operator==(const STiledPresentationSample&) const = default;
+    };
+
+    struct STiledRuntimeAcceptEffects {
+        bool accepted        = false;
+        bool schedulerSubmit = false;
+    };
+
+    // Canonical tile/member order is supplied by the exact bridge allocation.
+    // This remains separate from the stable topology/mode definition because
+    // allocator routing can change without changing that definition.
+    struct STiledRuntimeMemberRoute {
+        uint32_t connectorId    = 0;
+        uint32_t crtcId         = 0;
+        uint32_t primaryPlaneId = 0;
+
+        bool     operator==(const STiledRuntimeMemberRoute&) const = default;
+    };
+
+    template <typename TOwner>
+    struct STiledRuntimePlan {
+        // Production construction is valid only for a current
+        // MULTI_STREAM_ALLOCATED bridge group and must occur synchronously
+        // inside COutputBridgeState::withCurrent().
+        uint64_t generation = 0;
+        // Every accepted generation retains the full exact installed bridge
+        // observation, including its scan/snapshot/allocation/plan chain.
+        NTiledOutputBridge::POutputBridgeObservation generationOwner;
+        // Only the bridge mints/reconciles this stable semantic identity after
+        // validating exact topology and ordered logical/physical mappings.
+        NTiledOutputBridge::POutputDefinitionIdentity definitionIdentity;
+        uint32_t                                      primaryCrtcId = 0;
+        std::vector<uint32_t>                         crtcIds;
+        std::vector<STiledRuntimeMemberRoute>         memberRoutes;
+    };
+
+    template <typename TOwner>
+    struct STiledRuntimeFrame {
+        // These IDs are source-private identity keys, not DRM object numbers.
+        // bufferId must identify the underlying IBuffer across every member so
+        // backendRelease can be deduplicated. Per-member framebuffer ownership
+        // remains distinct from the shared IBuffer owner retained for release.
+        uint64_t framebufferId = 0;
+        uint64_t bufferId      = 0;
+        TOwner   framebufferOwner;
+        TOwner   bufferOwner;
+    };
+
+    template <typename TOwner>
+    struct STiledRuntimeBufferRelease {
+        uint64_t bufferId = 0;
+        TOwner   owner;
+    };
+
+    template <typename TOwner>
+    struct STiledRuntimeMemberFrame {
+        uint32_t                   crtcId = 0;
+        STiledRuntimeFrame<TOwner> frame;
+    };
+
+    template <typename TOwner>
+    struct STiledRuntimeEffects {
+        eTiledEventDisposition                          disposition         = eTiledEventDisposition::NO_EFFECT;
+        bool                                            schedulerComplete   = false;
+        bool                                            present             = false;
+        bool                                            schedulerInvalidate = false;
+        bool                                            requestRecovery     = false;
+        bool                                            rollbackReservation = false;
+        bool                                            quiesceReservation  = false;
+        bool                                            retireReservation   = false;
+        bool                                            successorAdopted    = false;
+        uint64_t                                        successorGeneration = 0;
+        std::optional<STiledPresentationSample>         presentation;
+        std::optional<STiledFlipReservation>            reservation;
+        std::vector<STiledRuntimeBufferRelease<TOwner>> releases;
+    };
+
+    template <typename TOwner>
+    struct STiledRetirementEffects {
+        bool                                            retired             = false;
+        bool                                            retireReservation   = false;
+        bool                                            successorAdopted    = false;
+        uint64_t                                        successorGeneration = 0;
+        std::optional<STiledFlipReservation>            reservation;
+        std::vector<STiledRuntimeBufferRelease<TOwner>> releases;
+    };
+
+    template <typename TOwner>
+    struct STiledSuccessorTransition {
+        eTiledSuccessorResult        result = eTiledSuccessorResult::INVALID_STATE;
+        STiledRuntimeEffects<TOwner> effects;
+    };
+
+    // TOwner is intentionally opaque. A future DRM adapter can place strong
+    // group, mode, framebuffer, buffer, blob, and assignment owners in one
+    // source-private bundle without exposing any of those types here or in an
+    // installed header.
+    template <typename TOwner>
+    class CTiledFrameRuntime {
+      public:
+        using SPlan        = STiledRuntimePlan<TOwner>;
+        using SFrame       = STiledRuntimeFrame<TOwner>;
+        using SRelease     = STiledRuntimeBufferRelease<TOwner>;
+        using SMemberFrame = STiledRuntimeMemberFrame<TOwner>;
+        using SEffects     = STiledRuntimeEffects<TOwner>;
+        using SRetirement  = STiledRetirementEffects<TOwner>;
+        using SSuccessor   = STiledSuccessorTransition<TOwner>;
+
+        static_assert(std::is_default_constructible_v<TOwner>);
+        static_assert(std::is_copy_constructible_v<TOwner>);
+        static_assert(std::is_nothrow_move_constructible_v<TOwner>);
+        static_assert(std::is_nothrow_move_assignable_v<TOwner>);
+        static_assert(std::is_nothrow_destructible_v<TOwner>);
+        static_assert(requires(const TOwner& owner) {
+            { static_cast<bool>(owner) } -> std::same_as<bool>;
+            { owner.get() } noexcept;
+        });
+        static_assert(std::is_pointer_v<decltype(std::declval<const TOwner&>().get())>);
+        static_assert(std::is_object_v<std::remove_pointer_t<decltype(std::declval<const TOwner&>().get())>>);
+        static_assert(std::is_nothrow_move_constructible_v<SFrame>);
+        static_assert(std::is_nothrow_move_assignable_v<SFrame>);
+        static_assert(std::is_nothrow_destructible_v<SFrame>);
+
+        explicit CTiledFrameRuntime(SPlan plan) : m_activePlan(std::move(plan)) {
+            if (!normalizePlan(m_activePlan)) {
+                m_state         = eTiledRuntimeState::QUIESCED;
+                m_quiesceReason = eTiledQuiesceReason::INVALID_TOPOLOGY;
+                return;
+            }
+
+            m_members.reserve(m_activePlan.crtcIds.size());
+            m_currentFrames.reserve(m_activePlan.crtcIds.size());
+            m_lastFrames.reserve(m_activePlan.crtcIds.size());
+            for (const auto CRTC_ID : m_activePlan.crtcIds)
+                m_members.emplace_back(STiledMemberFrameState{.crtcId = CRTC_ID});
+        }
+
+        CTiledFrameRuntime(const CTiledFrameRuntime&)            = delete;
+        CTiledFrameRuntime& operator=(const CTiledFrameRuntime&) = delete;
+        CTiledFrameRuntime(CTiledFrameRuntime&&)                 = delete;
+        CTiledFrameRuntime& operator=(CTiledFrameRuntime&&)      = delete;
+
+        ~CTiledFrameRuntime() noexcept {
+            if (!readyForDestruction())
+                std::terminate();
+        }
+
+        // Once published, even an empty disabled runtime still owns a live
+        // logical plan and may receive restore/successor work. Destruction is
+        // legal only after a terminal backend/device retirement proof has
+        // transitioned it to TEARDOWN. Never-published inert state is harmless.
+        [[nodiscard]] bool readyForDestruction() const noexcept {
+            const bool EMPTY = !m_prepared && m_currentFrames.empty() && m_lastFrames.empty();
+            return EMPTY && (!m_everPublished || m_state == eTiledRuntimeState::TEARDOWN);
+        }
+
+        [[nodiscard]] bool valid() const noexcept {
+            return m_state != eTiledRuntimeState::QUIESCED || m_quiesceReason != eTiledQuiesceReason::INVALID_TOPOLOGY;
+        }
+
+        [[nodiscard]] bool publishDisabled() noexcept {
+            if (m_state != eTiledRuntimeState::STAGED)
+                return false;
+            m_state         = eTiledRuntimeState::PUBLISHED_DISABLED;
+            m_everPublished = true;
+            return true;
+        }
+
+        [[nodiscard]] bool publishIdle(std::vector<SMemberFrame> frames) {
+            if (m_state != eTiledRuntimeState::STAGED && m_state != eTiledRuntimeState::PUBLISHED_DISABLED)
+                return false;
+
+            std::ranges::sort(frames, {}, &SMemberFrame::crtcId);
+            if (frames.size() != m_activePlan.crtcIds.size())
+                return false;
+
+            std::vector<STiledMemberFrameState> members;
+            std::vector<SFrame>                 currentFrames;
+            members.reserve(frames.size());
+            currentFrames.reserve(frames.size());
+
+            for (size_t I = 0; I < frames.size(); ++I) {
+                auto& MEMBER = frames.at(I);
+                if (MEMBER.crtcId != m_activePlan.crtcIds.at(I) || MEMBER.frame.framebufferId == 0 || MEMBER.frame.bufferId == 0 ||
+                    !static_cast<bool>(MEMBER.frame.framebufferOwner) || !static_cast<bool>(MEMBER.frame.bufferOwner))
+                    return false;
+
+                members.emplace_back(STiledMemberFrameState{
+                    .crtcId           = MEMBER.crtcId,
+                    .frontFramebuffer = MEMBER.frame.framebufferId,
+                    .frontBuffer      = MEMBER.frame.bufferId,
+                });
+
+                // Keep every member's framebuffer owner. Buffer identity is
+                // deduplicated only when a backendRelease effect is produced.
+                currentFrames.emplace_back(std::move(MEMBER.frame));
+            }
+
+            m_members.swap(members);
+            m_currentFrames.swap(currentFrames);
+            m_state         = eTiledRuntimeState::PUBLISHED_IDLE;
+            m_everPublished = true;
+            return true;
+        }
+
+        [[nodiscard]] eTiledRuntimePrepareError prepare(STiledFlipRoute route, SFrame frame, uint64_t deadlineNs) {
+            if (m_state != eTiledRuntimeState::PUBLISHED_DISABLED && m_state != eTiledRuntimeState::PUBLISHED_IDLE)
+                return eTiledRuntimePrepareError::INVALID_STATE;
+            if (m_prepared)
+                return eTiledRuntimePrepareError::ALREADY_PREPARED;
+            if (!route.valid() || route.generation != m_activePlan.generation || route.crtcIds != m_activePlan.crtcIds)
+                return eTiledRuntimePrepareError::INVALID_ROUTE;
+            if (deadlineNs == 0)
+                return eTiledRuntimePrepareError::INVALID_DEADLINE;
+            if (frame.framebufferId == 0 || frame.bufferId == 0 || !static_cast<bool>(frame.framebufferOwner) || !static_cast<bool>(frame.bufferOwner))
+                return eTiledRuntimePrepareError::INVALID_FRAME;
+
+            std::vector<SRelease> releases;
+            releases.reserve(m_currentFrames.size());
+            for (const auto& CURRENT : m_currentFrames) {
+                if (CURRENT.bufferId != frame.bufferId && std::ranges::find(releases, CURRENT.bufferId, &SRelease::bufferId) == releases.end())
+                    releases.emplace_back(SRelease{.bufferId = CURRENT.bufferId, .owner = CURRENT.bufferOwner});
+            }
+
+            // Construct the transaction directly in its final runtime slot.
+            // Its nonmovable barrier is the sole event-completion authority.
+            m_prepared.emplace(std::move(route), std::move(frame), std::move(releases), deadlineNs);
+            if (!m_prepared->barrier.valid()) {
+                m_prepared.reset();
+                return eTiledRuntimePrepareError::INVALID_ROUTE;
+            }
+            return eTiledRuntimePrepareError::NONE;
+        }
+
+        [[nodiscard]] const STiledFlipRoute* preparedRoute() const noexcept {
+            return m_prepared ? &m_prepared->route : nullptr;
+        }
+
+        [[nodiscard]] bool bindReservation(const STiledFlipReservation& reservation) noexcept {
+            if (!m_prepared || m_state == eTiledRuntimeState::PUBLISHED_IN_FLIGHT || m_prepared->reservation)
+                return false;
+            if (!reservation || reservation.m_transactionId != m_prepared->route.transactionId || reservation.m_generation != m_prepared->route.generation ||
+                reservation.m_memberCount != m_prepared->route.crtcIds.size())
+                return false;
+
+            m_prepared->reservation = reservation;
+            return true;
+        }
+
+        // After a successful KMS submit, call accept() first and publish the
+        // registry reservation second. Both operations are allocation-free and
+        // noexcept; on the same event thread no page-flip can observe a partly
+        // accepted transaction.
+        [[nodiscard]] STiledRuntimeAcceptEffects accept() noexcept {
+            if (!m_prepared || !m_prepared->reservation || (m_state != eTiledRuntimeState::PUBLISHED_DISABLED && m_state != eTiledRuntimeState::PUBLISHED_IDLE))
+                return {};
+
+            for (auto& MEMBER : m_members) {
+                MEMBER.backFramebuffer = m_prepared->frame.framebufferId;
+                MEMBER.backBuffer      = m_prepared->frame.bufferId;
+            }
+
+            m_state = eTiledRuntimeState::PUBLISHED_IN_FLIGHT;
+            return {.accepted = true, .schedulerSubmit = true};
+        }
+
+        // Submit failure is the only valid rollback point. Accepted and
+        // quiesced transactions require page-flip completion or retirement
+        // proof instead.
+        [[nodiscard]] bool rollbackPrepared() noexcept {
+            if (!m_prepared || m_state == eTiledRuntimeState::PUBLISHED_IN_FLIGHT || m_state == eTiledRuntimeState::QUIESCED)
+                return false;
+            m_prepared.reset();
+            adoptSuccessor();
+            return true;
+        }
+
+        [[nodiscard]] SEffects record(uintptr_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept {
+            SEffects effects;
+
+            if (transactionId == 0) {
+                effects.disposition = eTiledEventDisposition::NOT_OWNED;
+                return effects;
+            }
+
+            if (m_state == eTiledRuntimeState::QUIESCED) {
+                effects.disposition = m_prepared && transactionId == m_prepared->route.transactionId ? eTiledEventDisposition::QUIESCED : eTiledEventDisposition::STALE;
+                return effects;
+            }
+
+            if (m_state != eTiledRuntimeState::PUBLISHED_IN_FLIGHT || !m_prepared) {
+                effects.disposition = transactionId == m_completedTransaction ? eTiledEventDisposition::ALREADY_COMPLETE : eTiledEventDisposition::NOT_OWNED;
+                return effects;
+            }
+
+            if (transactionId != m_prepared->route.transactionId) {
+                effects.disposition = eTiledEventDisposition::STALE;
+                return effects;
+            }
+
+            const auto BARRIER_RESULT = m_prepared->barrier.record(static_cast<uint64_t>(transactionId), crtcId, sequence, timestampNs);
+            switch (BARRIER_RESULT) {
+                case ePageFlipBarrierResult::RECORDED: effects.disposition = eTiledEventDisposition::RECORDED; return effects;
+                case ePageFlipBarrierResult::DUPLICATE_EVENT: effects.disposition = eTiledEventDisposition::DUPLICATE; return effects;
+                case ePageFlipBarrierResult::STALE_TRANSACTION: effects.disposition = eTiledEventDisposition::STALE; return effects;
+                case ePageFlipBarrierResult::UNEXPECTED_CRTC: {
+                    effects             = quiesce(eTiledQuiesceReason::EVENT_INVARIANT);
+                    effects.disposition = eTiledEventDisposition::UNEXPECTED_CRTC;
+                    return effects;
+                }
+                case ePageFlipBarrierResult::ALREADY_COMPLETE: effects.disposition = eTiledEventDisposition::ALREADY_COMPLETE; return effects;
+                case ePageFlipBarrierResult::CANCELLED: effects.disposition = eTiledEventDisposition::QUIESCED; return effects;
+                case ePageFlipBarrierResult::INVALID:
+                    effects             = quiesce(eTiledQuiesceReason::EVENT_INVARIANT);
+                    effects.disposition = eTiledEventDisposition::UNEXPECTED_CRTC;
+                    return effects;
+                case ePageFlipBarrierResult::COMPLETED: break;
+            }
+
+            const auto TIMING  = m_prepared->barrier.timing();
+            const auto PRIMARY = std::ranges::find(m_prepared->barrier.received(), m_activePlan.primaryCrtcId, &SPageFlipEvidence::crtcId);
+            if (!TIMING || PRIMARY == m_prepared->barrier.received().end()) {
+                effects             = quiesce(eTiledQuiesceReason::EVENT_INVARIANT);
+                effects.disposition = eTiledEventDisposition::UNEXPECTED_CRTC;
+                return effects;
+            }
+
+            effects.disposition       = eTiledEventDisposition::COMPLETED;
+            effects.schedulerComplete = true;
+            effects.present           = true;
+            effects.retireReservation = true;
+            effects.presentation      = STiledPresentationSample{
+                .transactionId   = transactionId,
+                .generation      = m_prepared->route.generation,
+                .primarySequence = PRIMARY->sequence,
+                .timestampNs     = TIMING->latestTimestampNs,
+                .timing          = *TIMING,
+            };
+            effects.reservation = m_prepared->reservation;
+            effects.releases    = std::move(m_prepared->releases);
+
+            for (auto& MEMBER : m_members) {
+                MEMBER.lastFramebuffer  = MEMBER.frontFramebuffer;
+                MEMBER.lastBuffer       = MEMBER.frontBuffer;
+                MEMBER.frontFramebuffer = MEMBER.backFramebuffer;
+                MEMBER.frontBuffer      = MEMBER.backBuffer;
+            }
+
+            // Each member's old front becomes its retained last FB. Buffer
+            // release is a separate, deduplicated effect; clearing that effect
+            // must not destroy either per-member last framebuffer owner.
+            // Both vectors reserve member count at construction. Clear retains
+            // the previous-last allocation, then swap rotates that empty
+            // allocation into currentFrames before the noexcept emplace.
+            m_lastFrames.clear();
+            m_lastFrames.swap(m_currentFrames);
+            m_currentFrames.emplace_back(std::move(m_prepared->frame));
+            m_completedTransaction = transactionId;
+            m_prepared.reset();
+            m_state = eTiledRuntimeState::PUBLISHED_IDLE;
+            adoptSuccessor(effects.successorAdopted, effects.successorGeneration);
+            return effects;
+        }
+
+        [[nodiscard]] SEffects quiesce(eTiledQuiesceReason reason) noexcept {
+            SEffects effects;
+            effects.disposition = eTiledEventDisposition::QUIESCED;
+
+            if (reason == eTiledQuiesceReason::NONE || m_state == eTiledRuntimeState::QUIESCED || m_state == eTiledRuntimeState::TEARDOWN)
+                return effects;
+
+            const bool WAS_IN_FLIGHT = m_state == eTiledRuntimeState::PUBLISHED_IN_FLIGHT;
+            if (WAS_IN_FLIGHT && m_prepared)
+                static_cast<void>(m_prepared->barrier.cancel());
+
+            if (!WAS_IN_FLIGHT && m_prepared) {
+                effects.rollbackReservation = m_prepared->reservation.has_value();
+                effects.reservation         = m_prepared->reservation;
+                m_prepared.reset();
+            }
+
+            m_state          = eTiledRuntimeState::QUIESCED;
+            m_quiesceReason  = reason;
+            m_restorePending = reason == eTiledQuiesceReason::SESSION_INACTIVE;
+
+            effects.schedulerInvalidate = WAS_IN_FLIGHT;
+            effects.requestRecovery     = true;
+            if (WAS_IN_FLIGHT && m_prepared) {
+                effects.quiesceReservation = m_prepared->reservation.has_value();
+                effects.reservation        = m_prepared->reservation;
+            }
+            return effects;
+        }
+
+        [[nodiscard]] SEffects expire(uint64_t nowNs) noexcept {
+            if (m_state != eTiledRuntimeState::PUBLISHED_IN_FLIGHT || !m_prepared || nowNs < m_prepared->deadlineNs)
+                return {};
+
+            auto effects        = quiesce(eTiledQuiesceReason::EVENT_TIMEOUT);
+            effects.disposition = eTiledEventDisposition::TIMED_OUT;
+            return effects;
+        }
+
+        [[nodiscard]] SRetirement retire(eTiledRetirementProof proof) {
+            SRetirement effects;
+            if (proof == eTiledRetirementProof::NONE || m_state != eTiledRuntimeState::QUIESCED)
+                return effects;
+
+            if (m_prepared && m_prepared->reservation) {
+                effects.retireReservation = true;
+                effects.reservation       = m_prepared->reservation;
+            }
+
+            if (proof != eTiledRetirementProof::BACKEND_TEARDOWN_NO_CALLBACKS) {
+                effects.releases.reserve(m_currentFrames.size() + (m_prepared ? 1U : 0U));
+                const auto APPEND_UNIQUE = [&effects](const SFrame& frame) {
+                    if (frame.bufferId != 0 && std::ranges::find(effects.releases, frame.bufferId, &SRelease::bufferId) == effects.releases.end())
+                        effects.releases.emplace_back(SRelease{.bufferId = frame.bufferId, .owner = frame.bufferOwner});
+                };
+                for (const auto& CURRENT : m_currentFrames)
+                    APPEND_UNIQUE(CURRENT);
+                if (m_prepared)
+                    APPEND_UNIQUE(m_prepared->frame);
+            }
+
+            for (auto& MEMBER : m_members) {
+                MEMBER.frontFramebuffer = 0;
+                MEMBER.frontBuffer      = 0;
+                MEMBER.backFramebuffer  = 0;
+                MEMBER.backBuffer       = 0;
+                MEMBER.lastFramebuffer  = 0;
+                MEMBER.lastBuffer       = 0;
+            }
+
+            m_currentFrames.clear();
+            m_lastFrames.clear();
+            m_prepared.reset();
+            m_completedTransaction = 0;
+            m_restorePending       = false;
+            m_quiesceReason        = eTiledQuiesceReason::NONE;
+            effects.retired        = true;
+
+            if (proof == eTiledRetirementProof::DRM_DEVICE_GONE || proof == eTiledRetirementProof::BACKEND_TEARDOWN_NO_CALLBACKS) {
+                m_successor.reset();
+                m_activePlan = {};
+                m_members.clear();
+                m_state = eTiledRuntimeState::TEARDOWN;
+            } else {
+                m_state = eTiledRuntimeState::PUBLISHED_DISABLED;
+                adoptSuccessor(effects.successorAdopted, effects.successorGeneration);
+            }
+
+            return effects;
+        }
+
+        [[nodiscard]] SSuccessor stageSuccessor(SPlan successor) {
+            if (m_state == eTiledRuntimeState::TEARDOWN)
+                return {.result = eTiledSuccessorResult::INVALID_STATE};
+            if (!normalizePlan(successor))
+                return {.result = eTiledSuccessorResult::INVALID_PLAN};
+            if (sameOwner(successor.generationOwner, m_activePlan.generationOwner) || (m_successor && sameOwner(successor.generationOwner, m_successor->generationOwner)))
+                return {.result = eTiledSuccessorResult::INVALID_PLAN};
+            if (successor.generation <= m_activePlan.generation || (m_successor && successor.generation <= m_successor->generation))
+                return {.result = eTiledSuccessorResult::STALE_GENERATION};
+            if (!equivalentDefinition(m_activePlan, successor)) {
+                auto effects = quiesce(eTiledQuiesceReason::INVALID_TOPOLOGY);
+                return {.result = eTiledSuccessorResult::NON_EQUIVALENT, .effects = std::move(effects)};
+            }
+
+            m_successor = std::move(successor);
+            if (m_prepared || m_state == eTiledRuntimeState::PUBLISHED_IN_FLIGHT || m_state == eTiledRuntimeState::QUIESCED)
+                return {.result = eTiledSuccessorResult::STAGED};
+
+            bool     adopted    = false;
+            uint64_t generation = 0;
+            adoptSuccessor(adopted, generation);
+            return {.result = adopted ? eTiledSuccessorResult::ADOPTED : eTiledSuccessorResult::STAGED};
+        }
+
+        // A session-inactive transition is per logical runtime, so consuming
+        // this latch gives a future adapter exactly one group restore attempt.
+        [[nodiscard]] bool takeSessionRestoreRequest() noexcept {
+            if (m_state != eTiledRuntimeState::QUIESCED || m_quiesceReason != eTiledQuiesceReason::SESSION_INACTIVE || !m_restorePending)
+                return false;
+            m_restorePending = false;
+            return true;
+        }
+
+        [[nodiscard]] eTiledRuntimeState state() const noexcept {
+            return m_state;
+        }
+
+        [[nodiscard]] eTiledQuiesceReason quiesceReason() const noexcept {
+            return m_quiesceReason;
+        }
+
+        [[nodiscard]] const SPlan& activePlan() const noexcept {
+            return m_activePlan;
+        }
+
+        [[nodiscard]] const std::vector<STiledMemberFrameState>& members() const noexcept {
+            return m_members;
+        }
+
+        [[nodiscard]] const std::vector<SFrame>& currentFrames() const noexcept {
+            return m_currentFrames;
+        }
+
+        [[nodiscard]] const std::vector<SFrame>& lastFrames() const noexcept {
+            return m_lastFrames;
+        }
+
+        [[nodiscard]] uint64_t deadlineNs() const noexcept {
+            return m_prepared ? m_prepared->deadlineNs : 0;
+        }
+
+      private:
+        struct SPreparedTransaction {
+            STiledFlipRoute                      route;
+            CPageFlipBarrier                     barrier;
+            SFrame                               frame;
+            std::vector<SRelease>                releases;
+            uint64_t                             deadlineNs = 0;
+            std::optional<STiledFlipReservation> reservation;
+
+            SPreparedTransaction(STiledFlipRoute preparedRoute, SFrame preparedFrame, std::vector<SRelease> preparedReleases, uint64_t preparedDeadlineNs) :
+                route(std::move(preparedRoute)), barrier(static_cast<uint64_t>(route.transactionId), route.generation, route.crtcIds), frame(std::move(preparedFrame)),
+                releases(std::move(preparedReleases)), deadlineNs(preparedDeadlineNs) {}
+
+            SPreparedTransaction(const SPreparedTransaction&)            = delete;
+            SPreparedTransaction& operator=(const SPreparedTransaction&) = delete;
+            SPreparedTransaction(SPreparedTransaction&&)                 = delete;
+            SPreparedTransaction& operator=(SPreparedTransaction&&)      = delete;
+        };
+
+        static bool normalizePlan(SPlan& plan) {
+            std::ranges::sort(plan.crtcIds);
+            if (plan.generation == 0 || !plan.generationOwner || !plan.definitionIdentity || plan.primaryCrtcId == 0 || plan.crtcIds.empty() ||
+                plan.memberRoutes.size() != plan.crtcIds.size() || std::ranges::find(plan.crtcIds, 0U) != plan.crtcIds.end() ||
+                std::ranges::adjacent_find(plan.crtcIds) != plan.crtcIds.end() || !std::ranges::binary_search(plan.crtcIds, plan.primaryCrtcId))
+                return false;
+
+            std::vector<uint32_t> connectors;
+            std::vector<uint32_t> routedCrtcs;
+            std::vector<uint32_t> planes;
+            connectors.reserve(plan.memberRoutes.size());
+            routedCrtcs.reserve(plan.memberRoutes.size());
+            planes.reserve(plan.memberRoutes.size());
+            for (const auto& ROUTE : plan.memberRoutes) {
+                if (ROUTE.connectorId == 0 || ROUTE.crtcId == 0 || ROUTE.primaryPlaneId == 0)
+                    return false;
+                connectors.push_back(ROUTE.connectorId);
+                routedCrtcs.push_back(ROUTE.crtcId);
+                planes.push_back(ROUTE.primaryPlaneId);
+            }
+            std::ranges::sort(connectors);
+            std::ranges::sort(routedCrtcs);
+            std::ranges::sort(planes);
+            return std::ranges::adjacent_find(connectors) == connectors.end() && std::ranges::adjacent_find(routedCrtcs) == routedCrtcs.end() &&
+                std::ranges::adjacent_find(planes) == planes.end() && routedCrtcs == plan.crtcIds;
+        }
+
+        static bool equivalentDefinition(const SPlan& lhs, const SPlan& rhs) noexcept {
+            return sameOwner(lhs.definitionIdentity, rhs.definitionIdentity) && lhs.primaryCrtcId == rhs.primaryCrtcId && lhs.crtcIds == rhs.crtcIds &&
+                lhs.memberRoutes == rhs.memberRoutes;
+        }
+
+        template <typename T, typename U>
+        static bool sameOwner(const Hyprutils::Memory::CSharedPointer<T>& lhs, const Hyprutils::Memory::CSharedPointer<U>& rhs) noexcept {
+            return lhs.impl_ != nullptr && lhs.impl_ == rhs.impl_;
+        }
+
+        void adoptSuccessor(bool& adopted, uint64_t& generation) noexcept {
+            if (!m_successor)
+                return;
+            generation = m_successor->generation;
+            adoptSuccessor();
+            adopted = true;
+        }
+
+        void adoptSuccessor() noexcept {
+            if (!m_successor)
+                return;
+            m_activePlan = std::move(*m_successor);
+            m_successor.reset();
+        }
+
+        SPlan                               m_activePlan;
+        std::optional<SPlan>                m_successor;
+        std::vector<STiledMemberFrameState> m_members;
+        std::vector<SFrame>                 m_currentFrames;
+        std::vector<SFrame>                 m_lastFrames;
+        std::optional<SPreparedTransaction> m_prepared;
+        eTiledRuntimeState                  m_state                = eTiledRuntimeState::STAGED;
+        eTiledQuiesceReason                 m_quiesceReason        = eTiledQuiesceReason::NONE;
+        uintptr_t                           m_completedTransaction = 0;
+        bool                                m_restorePending       = false;
+        bool                                m_everPublished        = false;
+    };
+
+}
diff --git a/tests/AtomicSubmit.cpp b/tests/AtomicSubmit.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0d32becc5b746ef9365275b1634b5190377d28c3
--- /dev/null
+++ b/tests/AtomicSubmit.cpp
@@ -0,0 +1,121 @@
+#include "backend/drm/AtomicSubmit.hpp"
+#include "shared.hpp"
+
+#include <cerrno>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <xf86drmMode.h>
+
+using namespace Aquamarine::NDRM;
+
+namespace {
+    struct SAtomicRequestDeleter {
+        void operator()(drmModeAtomicReq* request) const {
+            drmModeAtomicFree(request);
+        }
+    };
+
+    int resultOf(const SAtomicSubmitResult& result) {
+        return static_cast<bool>(result) ? 1 : 0;
+    }
+}
+
+int main() {
+    int ret = 0;
+
+    static_assert(noexcept(std::declval<const SAtomicSubmitResult&>().operator bool()));
+    static_assert(noexcept(normalizeDRMCallError(0, 0)));
+
+    EXPECT(normalizeDRMCallError(0, EACCES), 0);
+    EXPECT(normalizeDRMCallError(-1, 0), EIO);
+    EXPECT(normalizeDRMCallError(-1, EACCES), EACCES);
+    EXPECT(normalizeDRMCallError(-EACCES, 0), EACCES);
+    EXPECT(normalizeDRMCallError(std::numeric_limits<int>::min(), 0), EIO);
+    EXPECT(normalizeDRMCallError(7, 0), EIO);
+
+    const auto request = std::unique_ptr<drmModeAtomicReq, SAtomicRequestDeleter>{drmModeAtomicAlloc()};
+    EXPECT(request != nullptr, true);
+    if (!request)
+        return ret;
+
+    EXPECT(drmModeAtomicAddProperty(request.get(), 101, 202, 303) >= 0, true);
+
+    constexpr int       DRM_FD    = 37;
+    constexpr uint32_t  FLAGS     = DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
+    constexpr uintptr_t USER_DATA = 0x1234ABCDU;
+
+    int                 submittedFD       = -1;
+    drmModeAtomicReqPtr submittedRequest  = nullptr;
+    uint32_t            submittedFlags    = 0;
+    uintptr_t           submittedUserData = 0;
+
+    const auto          success = submitAtomicRequest(DRM_FD, request.get(), FLAGS, USER_DATA, [&](int fd, drmModeAtomicReqPtr req, uint32_t flags, void* userData) {
+        submittedFD       = fd;
+        submittedRequest  = req;
+        submittedFlags    = flags;
+        submittedUserData = reinterpret_cast<uintptr_t>(userData); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): verify the libdrm token round-trip
+        return 0;
+    });
+
+    EXPECT(resultOf(success), 1);
+    EXPECT(success.returnCode, 0);
+    EXPECT(success.error, 0);
+    EXPECT(submittedFD, DRM_FD);
+    EXPECT(submittedRequest == request.get(), true);
+    EXPECT(submittedFlags, FLAGS);
+    EXPECT(submittedUserData, USER_DATA);
+
+    bool       zeroTokenSubmitted = false;
+    const auto testOnly           = submitAtomicRequest(DRM_FD, request.get(), DRM_MODE_ATOMIC_TEST_ONLY, 0, [&](int fd, drmModeAtomicReqPtr req, uint32_t flags, void* userData) {
+        zeroTokenSubmitted = fd == DRM_FD && req == request.get() && flags == DRM_MODE_ATOMIC_TEST_ONLY && userData == nullptr;
+        return 0;
+    });
+
+    EXPECT(resultOf(testOnly), 1);
+    EXPECT(zeroTokenSubmitted, true);
+
+    const auto directError = submitAtomicRequest(DRM_FD, request.get(), FLAGS, USER_DATA, [](int, drmModeAtomicReqPtr, uint32_t, void*) { return -EINVAL; });
+    EXPECT(resultOf(directError), 0);
+    EXPECT(directError.returnCode, -EINVAL);
+    EXPECT(directError.error, EINVAL);
+
+    const auto errnoError = submitAtomicRequest(DRM_FD, request.get(), FLAGS, USER_DATA, [](int, drmModeAtomicReqPtr, uint32_t, void*) {
+        errno = EACCES;
+        return -1;
+    });
+    EXPECT(resultOf(errnoError), 0);
+    EXPECT(errnoError.returnCode, -1);
+    EXPECT(errnoError.error, EACCES);
+
+    const auto missingErrno = submitAtomicRequest(DRM_FD, request.get(), FLAGS, USER_DATA, [](int, drmModeAtomicReqPtr, uint32_t, void*) noexcept {
+        errno = 0;
+        return -1;
+    });
+    EXPECT(resultOf(missingErrno), 0);
+    EXPECT(missingErrno.returnCode, -1);
+    EXPECT(missingErrno.error, EIO);
+
+    bool       submitted  = false;
+    bool       linearized = false;
+    const auto ordered    = submitAtomicRequest(
+        DRM_FD, request.get(), FLAGS, USER_DATA,
+        [&](int, drmModeAtomicReqPtr, uint32_t, void*) noexcept {
+            submitted = true;
+            errno     = EACCES;
+            return -1;
+        },
+        [&](int returnCode) noexcept {
+            linearized = submitted && returnCode == -1;
+            errno      = EINVAL;
+        });
+    static_assert(
+        noexcept(submitAtomicRequest(DRM_FD, request.get(), FLAGS, USER_DATA, [](int, drmModeAtomicReqPtr, uint32_t, void*) noexcept { return 0; }, [](int) noexcept {})));
+    EXPECT(linearized, true);
+    EXPECT(ordered.returnCode, -1);
+    EXPECT(ordered.error, EACCES);
+
+    return ret;
+}
diff --git a/tests/PageFlipBarrier.cpp b/tests/PageFlipBarrier.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ee751cb7cbb43e49f99f9d8937b6d3c5d061e7a
--- /dev/null
+++ b/tests/PageFlipBarrier.cpp
@@ -0,0 +1,172 @@
+#include "backend/drm/PageFlipBarrier.hpp"
+#include "shared.hpp"
+
+#include <array>
+#include <cstdint>
+#include <limits>
+#include <span>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+using namespace Aquamarine::NDRM;
+
+namespace {
+    int resultOf(ePageFlipBarrierResult result) {
+        return static_cast<int>(result);
+    }
+
+    int expected(ePageFlipBarrierResult result) {
+        return static_cast<int>(result);
+    }
+}
+
+int main() {
+    int ret = 0;
+
+    static_assert(noexcept(std::declval<CPageFlipBarrier&>().record(1, 1, 1, 1)));
+    static_assert(!std::is_copy_constructible_v<CPageFlipBarrier>);
+    static_assert(!std::is_copy_assignable_v<CPageFlipBarrier>);
+    static_assert(!std::is_move_constructible_v<CPageFlipBarrier>);
+    static_assert(!std::is_move_assignable_v<CPageFlipBarrier>);
+    static_assert(noexcept(std::declval<CPageFlipBarrier&>().cancel()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().valid()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().complete()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().cancelled()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().transactionId()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().topologyGeneration()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().expectedCrtcs()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().received()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().receivedCapacity()));
+    static_assert(noexcept(std::declval<const CPageFlipBarrier&>().timing()));
+
+    constexpr std::array<uint32_t, 1> ONE_CRTC{17};
+    CPageFlipBarrier                  one(101, 7, ONE_CRTC);
+    EXPECT(one.valid(), true);
+    EXPECT(one.transactionId(), 101U);
+    EXPECT(one.topologyGeneration(), 7U);
+    EXPECT(one.complete(), false);
+    EXPECT(one.cancelled(), false);
+    const auto ONE_CAPACITY = one.receivedCapacity();
+    EXPECT(ONE_CAPACITY >= ONE_CRTC.size(), true);
+    EXPECT(one.timing().has_value(), false);
+    EXPECT(resultOf(one.record(101, 17, 3, 900)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(one.complete(), true);
+    EXPECT(one.received().size(), 1U);
+    EXPECT(one.receivedCapacity(), ONE_CAPACITY);
+    EXPECT((one.received().front() == SPageFlipEvidence{.crtcId = 17, .sequence = 3, .timestampNs = 900}), true);
+    EXPECT((one.timing() == SPageFlipTiming{.earliestTimestampNs = 900, .latestTimestampNs = 900, .skewNs = 0}), true);
+    EXPECT(resultOf(one.record(101, 17, 4, 901)), expected(ePageFlipBarrierResult::ALREADY_COMPLETE));
+
+    constexpr std::array<uint32_t, 2> TWO_CRTCS_REVERSED{22, 11};
+    const std::vector<uint32_t>       TWO_CRTCS_SORTED{11, 22};
+    CPageFlipBarrier                  forward(202, 8, TWO_CRTCS_REVERSED);
+    const auto                        TWO_CAPACITY = forward.receivedCapacity();
+    EXPECT(TWO_CAPACITY >= TWO_CRTCS_REVERSED.size(), true);
+    EXPECT(forward.expectedCrtcs() == TWO_CRTCS_SORTED, true);
+    EXPECT(resultOf(forward.record(202, 11, 101, 1'000)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(forward.complete(), false);
+    EXPECT(forward.timing().has_value(), false);
+    EXPECT(resultOf(forward.record(202, 22, 202, 1'009)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(forward.receivedCapacity(), TWO_CAPACITY);
+    EXPECT((forward.timing() == SPageFlipTiming{.earliestTimestampNs = 1'000, .latestTimestampNs = 1'009, .skewNs = 9}), true);
+
+    CPageFlipBarrier reverse(202, 8, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(reverse.record(202, 22, 202, 1'009)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(reverse.record(202, 11, 101, 1'000)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(reverse.expectedCrtcs() == forward.expectedCrtcs(), true);
+    EXPECT(reverse.received() == forward.received(), true);
+    EXPECT(reverse.timing() == forward.timing(), true);
+
+    CPageFlipBarrier missing(303, 9, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(missing.record(303, 11, 1, 100)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(missing.complete(), false);
+    EXPECT(missing.received().size(), 1U);
+    EXPECT(missing.timing().has_value(), false);
+
+    CPageFlipBarrier duplicate(404, 10, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(duplicate.record(404, 11, 1, 100)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(duplicate.record(404, 11, 99, 999)), expected(ePageFlipBarrierResult::DUPLICATE_EVENT));
+    EXPECT(duplicate.received().size(), 1U);
+    EXPECT((duplicate.received().front() == SPageFlipEvidence{.crtcId = 11, .sequence = 1, .timestampNs = 100}), true);
+    EXPECT(resultOf(duplicate.record(404, 22, 2, 110)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(resultOf(duplicate.record(404, 11, 3, 120)), expected(ePageFlipBarrierResult::ALREADY_COMPLETE));
+    EXPECT(duplicate.received().size(), 2U);
+
+    CPageFlipBarrier rejected(505, 11, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(rejected.record(504, 11, 1, 100)), expected(ePageFlipBarrierResult::STALE_TRANSACTION));
+    EXPECT(resultOf(rejected.record(505, 33, 1, 100)), expected(ePageFlipBarrierResult::UNEXPECTED_CRTC));
+    EXPECT(rejected.received().empty(), true);
+
+    CPageFlipBarrier cancelledBefore(606, 12, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(cancelledBefore.cancel()), expected(ePageFlipBarrierResult::CANCELLED));
+    EXPECT(resultOf(cancelledBefore.cancel()), expected(ePageFlipBarrierResult::CANCELLED));
+    EXPECT(cancelledBefore.cancelled(), true);
+    EXPECT(cancelledBefore.complete(), false);
+    EXPECT(resultOf(cancelledBefore.record(606, 11, 1, 100)), expected(ePageFlipBarrierResult::CANCELLED));
+    EXPECT(cancelledBefore.received().empty(), true);
+    EXPECT(cancelledBefore.timing().has_value(), false);
+
+    CPageFlipBarrier cancelledPartial(707, 13, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(cancelledPartial.record(707, 11, 1, 100)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(cancelledPartial.cancel()), expected(ePageFlipBarrierResult::CANCELLED));
+    EXPECT(resultOf(cancelledPartial.record(707, 22, 2, 110)), expected(ePageFlipBarrierResult::CANCELLED));
+    EXPECT(cancelledPartial.received().size(), 1U);
+    EXPECT(cancelledPartial.complete(), false);
+
+    CPageFlipBarrier cancelledAfter(808, 14, ONE_CRTC);
+    EXPECT(resultOf(cancelledAfter.record(808, 17, 1, 100)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(resultOf(cancelledAfter.cancel()), expected(ePageFlipBarrierResult::ALREADY_COMPLETE));
+    EXPECT(resultOf(cancelledAfter.cancel()), expected(ePageFlipBarrierResult::ALREADY_COMPLETE));
+    EXPECT(cancelledAfter.complete(), true);
+    EXPECT(cancelledAfter.cancelled(), false);
+    EXPECT(cancelledAfter.timing().has_value(), true);
+
+    constexpr std::array<uint32_t, 4> FOUR_CRTCS_UNSORTED{40, 10, 30, 20};
+    const std::vector<uint32_t>       FOUR_CRTCS_SORTED{10, 20, 30, 40};
+    CPageFlipBarrier                  four(909, 15, FOUR_CRTCS_UNSORTED);
+    const auto                        FOUR_CAPACITY = four.receivedCapacity();
+    EXPECT(FOUR_CAPACITY >= FOUR_CRTCS_UNSORTED.size(), true);
+    EXPECT(four.expectedCrtcs() == FOUR_CRTCS_SORTED, true);
+    EXPECT(resultOf(four.record(909, 30, 3, 300)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(four.record(909, 10, 1, 100)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(four.record(909, 40, 4, 400)), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(four.record(909, 20, 2, 200)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(four.received().size(), 4U);
+    EXPECT(four.receivedCapacity(), FOUR_CAPACITY);
+    EXPECT(four.received().at(0).crtcId, 10U);
+    EXPECT(four.received().at(1).crtcId, 20U);
+    EXPECT(four.received().at(2).crtcId, 30U);
+    EXPECT(four.received().at(3).crtcId, 40U);
+    EXPECT((four.timing() == SPageFlipTiming{.earliestTimestampNs = 100, .latestTimestampNs = 400, .skewNs = 300}), true);
+
+    CPageFlipBarrier extremes(1'010, 16, TWO_CRTCS_REVERSED);
+    EXPECT(resultOf(extremes.record(1'010, 11, 1, std::numeric_limits<uint64_t>::max())), expected(ePageFlipBarrierResult::RECORDED));
+    EXPECT(resultOf(extremes.record(1'010, 22, 2, 0)), expected(ePageFlipBarrierResult::COMPLETED));
+    EXPECT(
+        (extremes.timing() == SPageFlipTiming{.earliestTimestampNs = 0, .latestTimestampNs = std::numeric_limits<uint64_t>::max(), .skewNs = std::numeric_limits<uint64_t>::max()}),
+        true);
+
+    const auto expectInvalid = [&](uint64_t transactionId, uint64_t generation, std::span<const uint32_t> crtcs) {
+        CPageFlipBarrier invalid(transactionId, generation, crtcs);
+        EXPECT(invalid.valid(), false);
+        EXPECT(invalid.complete(), false);
+        EXPECT(invalid.cancelled(), false);
+        EXPECT(invalid.receivedCapacity() >= crtcs.size(), true);
+        EXPECT(invalid.received().empty(), true);
+        EXPECT(invalid.timing().has_value(), false);
+        EXPECT(resultOf(invalid.record(transactionId, 1, 1, 1)), expected(ePageFlipBarrierResult::INVALID));
+        EXPECT(resultOf(invalid.cancel()), expected(ePageFlipBarrierResult::INVALID));
+    };
+
+    constexpr std::array<uint32_t, 0> EMPTY_CRTCS{};
+    constexpr std::array<uint32_t, 1> ZERO_CRTC{0};
+    constexpr std::array<uint32_t, 2> DUPLICATE_CRTCS{11, 11};
+    expectInvalid(0, 1, ONE_CRTC);
+    expectInvalid(1, 0, ONE_CRTC);
+    expectInvalid(1, 1, EMPTY_CRTCS);
+    expectInvalid(1, 1, ZERO_CRTC);
+    expectInvalid(1, 1, DUPLICATE_CRTCS);
+
+    return ret;
+}
diff --git a/tests/TiledOutputBridge.cpp b/tests/TiledOutputBridge.cpp
index aed1b96cfe10cc89f3f3b0081816ab78f7d07045..f1be52c6d77ea12bcd7a30a627e9897a60dc6777 100644
--- a/tests/TiledOutputBridge.cpp
+++ b/tests/TiledOutputBridge.cpp
@@ -292,15 +292,17 @@ int main() {
     CHECK(allocatedPlan && allocatedPlan->status() == eGroupStatus::ALLOCATED);
     CHECK(allocatedPlan && allocatedPlan->bindings().size() == 2);
     CHECK(allocated && allocated->modeSet() && allocated->modeSet()->modes().size() == 1);
+    CHECK(allocated && allocated->definitionIdentity());
     CHECK(driver && driver->projection() == eGroupProjection::DRIVER_UNIFIED);
     CHECK(driver && !driver->allocation().has_value());
-    CHECK(driver && !driver->allocationDefinition() && !driver->modeDefinition() && !driver->modeSet());
+    CHECK(driver && !driver->allocationDefinition() && !driver->modeDefinition() && !driver->modeSet() && !driver->definitionIdentity());
     CHECK(installed1->findConnector(3) && installed1->findConnector(3)->projection() == eConnectorProjection::DRIVER_UNIFIED_PRIMARY);
     CHECK(installed1->findConnector(4) && installed1->findConnector(4)->projection() == eConnectorProjection::DRIVER_UNIFIED_REDUNDANT);
     CHECK(installed1->findConnector(4) && installed1->findConnector(4)->scanDisposition() == eConnectorDisposition::SUPPRESS_REDUNDANT);
     CHECK(installed1->findConnector(1) && installed1->findConnector(1)->projection() == eConnectorProjection::MULTI_STREAM_AGGREGATE_CANDIDATE);
 
-    const auto mode1 = allocated->modeSet()->modes().front().outputMode;
+    const auto mode1               = allocated->modeSet()->modes().front().outputMode;
+    const auto definitionIdentity1 = allocated->definitionIdentity();
     CHECK(mode1 && !mode1->modeInfo.has_value());
     CHECK(allocated->modeSet()->logicalModeFor(mode1) != nullptr);
     CHECK(allocated->modeSet()->physicalMappingFor(mode1) != nullptr);
@@ -327,6 +329,7 @@ int main() {
     const auto* allocated2 = groupOf(candidate2, NTiling::eTileGroupKind::MULTI_STREAM);
     CHECK(allocated2 && sameOwner(allocated2->modeSet(), allocated->modeSet()));
     CHECK(allocated2 && sameOwner(allocated2->modeSet()->modes().front().outputMode, mode1));
+    CHECK(allocated2 && sameOwner(allocated2->definitionIdentity(), definitionIdentity1));
     CHECK(state.install(prepared2.prepared, currentFor(plan2)) == eInstallResult::INSTALLED);
 
     // Session freshness is reminted, but identical validated topology and
@@ -342,6 +345,7 @@ int main() {
     CHECK(allocated3 && !sameOwner(allocated3->modeSet(), allocated2->modeSet()));
     CHECK(allocated3 && sameOwner(allocated3->modeDefinition(), scan2->modeDefinitions().front()));
     CHECK(allocated3 && sameOwner(allocated3->modeSet()->modes().front().outputMode, mode1));
+    CHECK(allocated3 && sameOwner(allocated3->definitionIdentity(), definitionIdentity1));
     CHECK(state.install(prepared3.prepared, currentFor(plan3)) == eInstallResult::INSTALLED);
 
     // A physical mapping change is material even when the logical dimensions
@@ -354,6 +358,7 @@ int main() {
     const auto* allocated4 = groupOf(prepared4.prepared->candidate(), NTiling::eTileGroupKind::MULTI_STREAM);
     CHECK(allocated4 && !sameOwner(allocated4->modeSet()->modes().front().outputMode, mode1));
     CHECK(allocated4 && allocated4->modeSet()->physicalMappingFor(mode1) == nullptr);
+    CHECK(allocated4 && !sameOwner(allocated4->definitionIdentity(), definitionIdentity1));
 
     // Reused public owners are checked again under the exact-current install
     // gate. Mutation after prepare must reject the swap.
@@ -378,6 +383,7 @@ int main() {
     CHECK(allocated5 && !sameOwner(allocated5->modeSet()->modes().front().outputMode, mode1));
     CHECK(allocated5 && allocated5->modeSet()->modes().front().outputMode->refreshRate == 60000);
     CHECK(allocated5 && !allocated5->modeSet()->modes().front().outputMode->modeInfo.has_value());
+    CHECK(allocated5 && sameOwner(allocated5->definitionIdentity(), definitionIdentity1));
 
     // Current-plan and optimistic-base failures leave the installed owner
     // unchanged.
@@ -390,6 +396,17 @@ int main() {
     CHECK(!state.withCurrent(currentFor(plan1), [&](const COutputBridgeObservation&) { ++currentCallbacks; }));
     CHECK(currentCallbacks == 1);
 
+    // Allocation status is not part of the stable topology/mode definition.
+    // The fallback projection carries the same identity, but no runtime is
+    // created for it.
+    const SResources constrainedResources({1, 2, 3, 4}, 1);
+    const auto       fallbackTransitionPlan = planFor(snapshotFor(scan2, constrainedResources, 6), {3});
+    const auto       fallbackTransition     = state.prepare(fallbackTransitionPlan);
+    CHECK(static_cast<bool>(fallbackTransition));
+    const auto* fallbackTransitionGroup = groupOf(fallbackTransition.prepared->candidate(), NTiling::eTileGroupKind::MULTI_STREAM);
+    CHECK(fallbackTransitionGroup && fallbackTransitionGroup->projection() == eGroupProjection::MULTI_STREAM_FALLBACK);
+    CHECK(fallbackTransitionGroup && sameOwner(fallbackTransitionGroup->definitionIdentity(), definitionIdentity1));
+
     // With one route, a two-member group is NO_MATCH and every member remains
     // an ordinary fallback. Driver-unified scan behavior is not involved.
     SFixture           fallbackFixture({10, 11}, 1);
@@ -409,6 +426,7 @@ int main() {
             fallbackAllocation = &allocation->get();
     }
     CHECK(fallbackGroup && fallbackGroup->projection() == eGroupProjection::MULTI_STREAM_FALLBACK);
+    CHECK(fallbackGroup && fallbackGroup->definitionIdentity());
     CHECK(fallbackAllocation && fallbackAllocation->status() == eGroupStatus::NO_MATCH);
     CHECK(fallbackAllocation && fallbackAllocation->bindings().empty());
     CHECK(fallback->findConnector(10) && fallback->findConnector(10)->projection() == eConnectorProjection::MULTI_STREAM_ORDINARY_FALLBACK);
diff --git a/tests/TiledRuntime.cpp b/tests/TiledRuntime.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..83b716feb79d6f34178e24e5b31a203df91bc117
--- /dev/null
+++ b/tests/TiledRuntime.cpp
@@ -0,0 +1,794 @@
+#include "backend/drm/TiledRuntime.hpp"
+#include "shared.hpp"
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <hyprutils/memory/WeakPtr.hpp>
+
+using namespace Aquamarine::NDRM;
+
+namespace {
+    using Hyprutils::Memory::CSharedPointer;
+    using Hyprutils::Memory::CWeakPointer;
+    using NTiledOutputBridge::COutputBridgeObservation;
+    using NTiledOutputBridge::COutputDefinitionIdentity;
+    using NTiledOutputBridge::POutputBridgeObservation;
+    using NTiledOutputBridge::POutputDefinitionIdentity;
+
+    struct SOwner {
+        std::string                                   name;
+        std::map<uint64_t, POutputDefinitionIdentity> definitions;
+    };
+
+    using SStrongOwner = std::shared_ptr<SOwner>;
+    using SRuntime     = CTiledFrameRuntime<SStrongOwner>;
+    using SPlan        = SRuntime::SPlan;
+    using SFrame       = SRuntime::SFrame;
+    using SMemberFrame = SRuntime::SMemberFrame;
+
+    struct SGenerationCarrier {
+        SStrongOwner retained;
+    };
+
+    struct SDefinitionCarrier {
+        uint64_t id = 0;
+    };
+
+    template <typename TEnum>
+    int enumValue(TEnum value) {
+        return static_cast<int>(value);
+    }
+
+    SStrongOwner owner(std::string name) {
+        return std::make_shared<SOwner>(SOwner{.name = std::move(name)});
+    }
+
+    POutputBridgeObservation generationOwner(SStrongOwner retained) {
+        if (!retained)
+            return {};
+        CSharedPointer<SGenerationCarrier> carrier{new SGenerationCarrier{.retained = std::move(retained)}};
+        return Hyprutils::Memory::reinterpretPointerCast<const COutputBridgeObservation>(carrier);
+    }
+
+    POutputDefinitionIdentity definitionIdentity(const SStrongOwner& planOwner, uint64_t definitionId) {
+        if (!planOwner)
+            return {};
+        auto& identity = planOwner->definitions[definitionId];
+        if (!identity) {
+            CSharedPointer<SDefinitionCarrier> carrier{new SDefinitionCarrier{.id = definitionId}};
+            identity = Hyprutils::Memory::reinterpretPointerCast<const COutputDefinitionIdentity>(carrier);
+        }
+        return identity;
+    }
+
+    SPlan plan(uint64_t generation, SStrongOwner planOwner, uint64_t definitionId = 55, std::vector<uint32_t> crtcIds = {22, 11}, uint32_t primaryCrtcId = 11,
+               std::vector<STiledRuntimeMemberRoute> memberRoutes = {}, CWeakPointer<const COutputBridgeObservation>* generationWeak = nullptr) {
+        if (memberRoutes.empty()) {
+            auto routedCrtcs = crtcIds;
+            std::ranges::sort(routedCrtcs);
+            memberRoutes.reserve(routedCrtcs.size());
+            for (size_t index = 0; index < routedCrtcs.size(); ++index) {
+                memberRoutes.push_back({
+                    .connectorId    = static_cast<uint32_t>(index + 1),
+                    .crtcId         = routedCrtcs.at(index),
+                    .primaryPlaneId = static_cast<uint32_t>(101 + index),
+                });
+            }
+        }
+        auto exactGeneration = generationOwner(planOwner);
+        if (generationWeak)
+            *generationWeak = exactGeneration;
+        return {
+            .generation         = generation,
+            .generationOwner    = std::move(exactGeneration),
+            .definitionIdentity = definitionIdentity(planOwner, definitionId),
+            .primaryCrtcId      = primaryCrtcId,
+            .crtcIds            = std::move(crtcIds),
+            .memberRoutes       = std::move(memberRoutes),
+        };
+    }
+
+    SFrame frame(uint64_t framebufferId, uint64_t bufferId, SStrongOwner frameOwner) {
+        return {.framebufferId = framebufferId, .bufferId = bufferId, .framebufferOwner = frameOwner, .bufferOwner = std::move(frameOwner)};
+    }
+
+    STiledFlipRoute route(uintptr_t transactionId, uint64_t generation, std::vector<uint32_t> crtcIds = {11, 22}) {
+        return {.transactionId = transactionId, .generation = generation, .crtcIds = std::move(crtcIds)};
+    }
+
+    SMemberFrame member(uint32_t crtcId, uint64_t framebufferId, uint64_t bufferId, const SStrongOwner& frameOwner) {
+        return {.crtcId = crtcId, .frame = frame(framebufferId, bufferId, frameOwner)};
+    }
+
+    SMemberFrame member(uint32_t crtcId, uint64_t framebufferId, uint64_t bufferId, const SStrongOwner& framebufferOwner, const SStrongOwner& bufferOwner) {
+        return {.crtcId = crtcId, .frame = {.framebufferId = framebufferId, .bufferId = bufferId, .framebufferOwner = framebufferOwner, .bufferOwner = bufferOwner}};
+    }
+
+    bool noCompletionEffects(const SRuntime::SEffects& effects) {
+        return !effects.schedulerComplete && !effects.present && !effects.schedulerInvalidate && !effects.requestRecovery && !effects.rollbackReservation &&
+            !effects.quiesceReservation && !effects.retireReservation && !effects.presentation && !effects.reservation && effects.releases.empty();
+    }
+
+    template <typename TRuntime>
+    bool terminalTeardown(TRuntime& runtime) {
+        if (runtime.state() != eTiledRuntimeState::QUIESCED) {
+            const auto quiesced = runtime.quiesce(eTiledQuiesceReason::BACKEND_TEARDOWN);
+            if (!quiesced.requestRecovery)
+                return false;
+        }
+
+        const auto retired = runtime.retire(eTiledRetirementProof::BACKEND_TEARDOWN_NO_CALLBACKS);
+        return retired.retired && runtime.state() == eTiledRuntimeState::TEARDOWN && runtime.readyForDestruction();
+    }
+}
+
+int main() {
+    int ret = 0;
+
+    static_assert(noexcept(std::declval<SRuntime&>().accept()));
+    static_assert(noexcept(std::declval<SRuntime&>().record(1, 1, 1, 1)));
+    static_assert(noexcept(std::declval<SRuntime&>().quiesce(eTiledQuiesceReason::EVENT_TIMEOUT)));
+    static_assert(noexcept(std::declval<SRuntime&>().expire(1)));
+    static_assert(noexcept(std::declval<CTiledFlipReservationRegistry&>().accept({})));
+    static_assert(noexcept(std::declval<CTiledFlipReservationRegistry&>().rollback({})));
+    static_assert(noexcept(std::declval<CTiledFlipReservationRegistry&>().quiesce({})));
+    static_assert(noexcept(std::declval<CTiledFlipReservationRegistry&>().retire({})));
+    static_assert(noexcept(std::declval<CTiledFlipReservationRegistry&>().shutdown(eTiledRegistryShutdownProof::DRM_DEVICE_GONE)));
+    static_assert(noexcept(std::declval<const CTiledFlipReservationRegistry&>().readyForDestruction()));
+    static_assert(!std::is_copy_constructible_v<CTiledFlipReservationRegistry>);
+    static_assert(!std::is_copy_assignable_v<CTiledFlipReservationRegistry>);
+    static_assert(!std::is_move_constructible_v<CTiledFlipReservationRegistry>);
+    static_assert(!std::is_move_assignable_v<CTiledFlipReservationRegistry>);
+    static_assert(!std::is_copy_constructible_v<SRuntime>);
+    static_assert(!std::is_copy_assignable_v<SRuntime>);
+    static_assert(!std::is_move_constructible_v<SRuntime>);
+    static_assert(!std::is_move_assignable_v<SRuntime>);
+    static_assert(std::is_nothrow_move_constructible_v<SFrame>);
+    static_assert(std::is_nothrow_move_assignable_v<SFrame>);
+    static_assert(std::is_nothrow_destructible_v<SFrame>);
+    static_assert(noexcept(std::declval<const SStrongOwner&>().get()));
+
+    {
+        CTiledFlipReservationRegistry registry;
+        EXPECT(registry.readyForDestruction(), true);
+        const STiledFlipRoute route{.transactionId = 100, .generation = 7, .crtcIds = {11, 22}};
+        const auto            reserved = registry.reserveAll(route);
+        EXPECT(!!reserved, true);
+        EXPECT(registry.readyForDestruction(), false);
+        EXPECT(registry.matches(reserved.reservation, route), true);
+        EXPECT(registry.transactionCount(), 1U);
+        EXPECT(registry.claimedCrtcCount(), 2U);
+        EXPECT(enumValue(registry.routeEvent(100, 11)), enumValue(eTiledRouteEventResult::RESERVED));
+        EXPECT(enumValue(registry.routeEvent(100, 99)), enumValue(eTiledRouteEventResult::UNEXPECTED_CRTC));
+
+        const auto duplicateToken = registry.reserveAll({.transactionId = 100, .generation = 8, .crtcIds = {33, 44}});
+        EXPECT(enumValue(duplicateToken.error), enumValue(eTiledReservationError::TOKEN_CONFLICT));
+        const auto overlapping = registry.reserveAll({.transactionId = 101, .generation = 8, .crtcIds = {22, 33}});
+        EXPECT(enumValue(overlapping.error), enumValue(eTiledReservationError::CRTC_CONFLICT));
+        EXPECT(registry.transactionCount(), 1U);
+        EXPECT(registry.claimedCrtcCount(), 2U);
+
+        EXPECT(registry.rollback(reserved.reservation), true);
+        EXPECT(registry.rollback(reserved.reservation), false);
+        EXPECT(registry.readyForDestruction(), true);
+        EXPECT(registry.transactionCount(), 0U);
+        EXPECT(registry.claimedCrtcCount(), 0U);
+        EXPECT(enumValue(registry.routeEvent(100, 11)), enumValue(eTiledRouteEventResult::NOT_OWNED));
+
+        const auto accepted = registry.reserveAll(route);
+        EXPECT(!!accepted, true);
+        EXPECT(registry.accept(accepted.reservation), true);
+        EXPECT(registry.readyForDestruction(), false);
+        EXPECT(registry.accept(accepted.reservation), false);
+        EXPECT(enumValue(registry.state(accepted.reservation).value_or(eTiledReservationState::RESERVED)), enumValue(eTiledReservationState::IN_FLIGHT));
+        EXPECT(enumValue(registry.routeEvent(100, 22)), enumValue(eTiledRouteEventResult::ROUTABLE));
+        EXPECT(enumValue(registry.routeEvent(999, 22)), enumValue(eTiledRouteEventResult::STALE_TOKEN));
+        EXPECT(registry.quiesce(accepted.reservation), true);
+        EXPECT(registry.quiesce(accepted.reservation), true);
+        EXPECT(enumValue(registry.state(accepted.reservation).value_or(eTiledReservationState::RESERVED)), enumValue(eTiledReservationState::QUIESCED));
+        EXPECT(enumValue(registry.routeEvent(100, 11)), enumValue(eTiledRouteEventResult::ROUTABLE));
+        EXPECT(registry.retire(accepted.reservation), true);
+        EXPECT(registry.retire(accepted.reservation), false);
+        EXPECT(registry.readyForDestruction(), false);
+        EXPECT(registry.transactionCount(), 0U);
+        EXPECT(registry.claimedCrtcCount(), 0U);
+        EXPECT(enumValue(registry.routeEvent(100, 11)), enumValue(eTiledRouteEventResult::STALE_TOKEN));
+
+        const auto retiredToken = registry.reserveAll(route);
+        EXPECT(enumValue(retiredToken.error), enumValue(eTiledReservationError::RETIRED_TOKEN));
+        const auto successor = registry.reserveAll({.transactionId = 102, .generation = 8, .crtcIds = {11, 22}});
+        EXPECT(!!successor, true);
+        EXPECT(registry.rollback(successor.reservation), true);
+
+        const auto invalid = registry.reserveAll({.transactionId = 103, .generation = 8, .crtcIds = {11, 11}});
+        EXPECT(enumValue(invalid.error), enumValue(eTiledReservationError::INVALID_ROUTE));
+        const auto exhaustedToken = registry.reserveAll({.transactionId = 0, .generation = 8, .crtcIds = {11, 22}});
+        EXPECT(enumValue(exhaustedToken.error), enumValue(eTiledReservationError::INVALID_ROUTE));
+        const auto nonCanonical = registry.reserveAll({.transactionId = 104, .generation = 8, .crtcIds = {22, 11}});
+        EXPECT(enumValue(nonCanonical.error), enumValue(eTiledReservationError::INVALID_ROUTE));
+        EXPECT(registry.transactionCount(), 0U);
+        EXPECT(registry.claimedCrtcCount(), 0U);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::NONE), false);
+        EXPECT(registry.readyForDestruction(), false);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::DRM_DEVICE_GONE), true);
+        EXPECT(registry.readyForDestruction(), true);
+        const auto afterShutdown = registry.reserveAll({.transactionId = 105, .generation = 9, .crtcIds = {11, 22}});
+        EXPECT(enumValue(afterShutdown.error), enumValue(eTiledReservationError::SHUTDOWN));
+    }
+
+    {
+        SRuntime runtime(plan(6, owner("route-validation-plan")));
+        EXPECT(runtime.readyForDestruction(), true);
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(runtime.readyForDestruction(), false);
+        EXPECT(enumValue(runtime.prepare(route(600, 5), frame(600, 600, owner("wrong-generation")), 1'000)), enumValue(eTiledRuntimePrepareError::INVALID_ROUTE));
+        EXPECT(enumValue(runtime.prepare(route(600, 6, {11, 33}), frame(600, 600, owner("wrong-members")), 1'000)), enumValue(eTiledRuntimePrepareError::INVALID_ROUTE));
+        EXPECT(enumValue(runtime.prepare(route(600, 6, {22, 11}), frame(600, 600, owner("noncanonical-members")), 1'000)), enumValue(eTiledRuntimePrepareError::INVALID_ROUTE));
+        EXPECT(enumValue(runtime.prepare(route(600, 6), {.framebufferId = 600, .bufferId = 600, .framebufferOwner = {}, .bufferOwner = owner("buffer-only")}, 1'000)),
+               enumValue(eTiledRuntimePrepareError::INVALID_FRAME));
+        EXPECT(enumValue(runtime.prepare(route(600, 6), {.framebufferId = 600, .bufferId = 600, .framebufferOwner = owner("fb-only"), .bufferOwner = {}}, 1'000)),
+               enumValue(eTiledRuntimePrepareError::INVALID_FRAME));
+        EXPECT(runtime.preparedRoute() == nullptr, true);
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::OUTPUT_DISABLED).requestRecovery, true);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(runtime.readyForDestruction(), false);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                                         oldPlanOwner  = owner("plan-generation-7");
+        auto                                         oldFrameOwner = owner("old-shared-buffer");
+        auto                                         newFrameOwner = owner("accepted-frame");
+        const std::weak_ptr<SOwner>                  oldPlanWeak   = oldPlanOwner;
+        const std::weak_ptr<SOwner>                  oldFrameWeak  = oldFrameOwner;
+        const std::weak_ptr<SOwner>                  newFrameWeak  = newFrameOwner;
+        CWeakPointer<const COutputBridgeObservation> oldGenerationWeak;
+        CWeakPointer<const COutputBridgeObservation> successorGenerationWeak;
+
+        SRuntime                                     runtime(plan(7, oldPlanOwner, 55, {22, 11}, 11, {}, &oldGenerationWeak));
+        EXPECT(runtime.valid(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::STAGED));
+        EXPECT(runtime.publishIdle({member(22, 202, 500, oldFrameOwner), member(11, 101, 500, oldFrameOwner)}), true);
+        oldFrameOwner.reset();
+        EXPECT(oldFrameWeak.expired(), false);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_IDLE));
+        EXPECT(runtime.currentFrames().size(), 2U);
+
+        EXPECT(enumValue(runtime.prepare(route(1'000, 7), frame(900, 900, std::move(newFrameOwner)), 50'000)), enumValue(eTiledRuntimePrepareError::NONE));
+        EXPECT(runtime.deadlineNs(), 50'000U);
+        EXPECT(runtime.preparedRoute() != nullptr, true);
+        EXPECT(runtime.preparedRoute()->crtcIds == std::vector<uint32_t>({11, 22}), true);
+        EXPECT(newFrameWeak.expired(), false);
+
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(!!reserved, true);
+        EXPECT(registry.matches(reserved.reservation, *runtime.preparedRoute()), true);
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        const auto accepted = runtime.accept();
+        EXPECT(accepted.accepted, true);
+        EXPECT(accepted.schedulerSubmit, true);
+        EXPECT(registry.accept(reserved.reservation), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_IN_FLIGHT));
+        EXPECT(runtime.members().at(0).frontFramebuffer, 101U);
+        EXPECT(runtime.members().at(0).backFramebuffer, 900U);
+        EXPECT(runtime.members().at(1).frontFramebuffer, 202U);
+        EXPECT(runtime.members().at(1).backFramebuffer, 900U);
+        EXPECT(runtime.rollbackPrepared(), false);
+
+        EXPECT(enumValue(runtime.stageSuccessor(plan(8, oldPlanOwner, 55, {22, 11}, 11, {}, &successorGenerationWeak)).result), enumValue(eTiledSuccessorResult::STAGED));
+        oldPlanOwner.reset();
+        EXPECT(oldPlanWeak.expired(), false);
+        EXPECT(oldGenerationWeak.expired(), false);
+        EXPECT(successorGenerationWeak.expired(), false);
+
+        const auto first = runtime.record(1'000, 22, 222, 120);
+        EXPECT(enumValue(first.disposition), enumValue(eTiledEventDisposition::RECORDED));
+        EXPECT(noCompletionEffects(first), true);
+        EXPECT(runtime.members().at(0).frontFramebuffer, 101U);
+        EXPECT(runtime.members().at(1).frontFramebuffer, 202U);
+
+        const auto duplicate = runtime.record(1'000, 22, 999, 999);
+        EXPECT(enumValue(duplicate.disposition), enumValue(eTiledEventDisposition::DUPLICATE));
+        EXPECT(noCompletionEffects(duplicate), true);
+        const auto stale = runtime.record(999, 11, 111, 100);
+        EXPECT(enumValue(stale.disposition), enumValue(eTiledEventDisposition::STALE));
+        EXPECT(noCompletionEffects(stale), true);
+
+        auto completed = runtime.record(1'000, 11, 111, 100);
+        EXPECT(enumValue(completed.disposition), enumValue(eTiledEventDisposition::COMPLETED));
+        EXPECT(completed.schedulerComplete, true);
+        EXPECT(completed.present, true);
+        EXPECT(completed.retireReservation, true);
+        EXPECT(completed.quiesceReservation, false);
+        EXPECT(completed.presentation.has_value(), true);
+        const auto presentation = completed.presentation.value_or(STiledPresentationSample{});
+        EXPECT(presentation.transactionId, 1'000U);
+        EXPECT(presentation.generation, 7U);
+        EXPECT(presentation.primarySequence, 111U);
+        EXPECT(presentation.timestampNs, 120U);
+        EXPECT((presentation.timing == SPageFlipTiming{.earliestTimestampNs = 100, .latestTimestampNs = 120, .skewNs = 20}), true);
+        EXPECT(completed.releases.size(), 1U);
+        EXPECT(completed.releases.front().bufferId, 500U);
+        EXPECT(completed.successorAdopted, true);
+        EXPECT(completed.successorGeneration, 8U);
+        EXPECT(runtime.activePlan().generation, 8U);
+        EXPECT(oldPlanWeak.expired(), false);
+        EXPECT(oldGenerationWeak.expired(), true);
+        EXPECT(successorGenerationWeak.expired(), false);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_IDLE));
+        EXPECT(runtime.currentFrames().size(), 1U);
+        EXPECT(runtime.currentFrames().front().bufferId, 900U);
+        EXPECT(runtime.members().at(0).frontFramebuffer, 900U);
+        EXPECT(runtime.members().at(0).lastFramebuffer, 101U);
+        EXPECT(runtime.members().at(1).frontFramebuffer, 900U);
+        EXPECT(runtime.members().at(1).lastFramebuffer, 202U);
+        EXPECT(registry.retire(completed.reservation.value_or(STiledFlipReservation{})), true);
+
+        const auto late = runtime.record(1'000, 11, 112, 130);
+        EXPECT(enumValue(late.disposition), enumValue(eTiledEventDisposition::ALREADY_COMPLETE));
+        EXPECT(noCompletionEffects(late), true);
+        EXPECT(enumValue(registry.routeEvent(1'000, 11)), enumValue(eTiledRouteEventResult::STALE_TOKEN));
+        EXPECT(oldFrameWeak.expired(), false);
+        completed.releases.clear();
+        EXPECT(oldFrameWeak.expired(), false);
+        EXPECT(newFrameWeak.expired(), false);
+        EXPECT(runtime.lastFrames().size(), 2U);
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::OUTPUT_DISABLED).requestRecovery, true);
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        EXPECT(retired.releases.size(), 1U);
+        EXPECT(oldFrameWeak.expired(), true);
+        EXPECT(newFrameWeak.expired(), false);
+        retired.releases.clear();
+        EXPECT(newFrameWeak.expired(), true);
+        EXPECT(terminalTeardown(runtime), true);
+        EXPECT(oldPlanWeak.expired(), true);
+        EXPECT(successorGenerationWeak.expired(), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        auto                        leftFramebufferOwner  = owner("left-old-fb");
+        auto                        rightFramebufferOwner = owner("right-old-fb");
+        auto                        sharedBufferOwner     = owner("shared-old-buffer");
+        auto                        nextFrameOwner        = owner("next-frame");
+        const std::weak_ptr<SOwner> leftWeak              = leftFramebufferOwner;
+        const std::weak_ptr<SOwner> rightWeak             = rightFramebufferOwner;
+        const std::weak_ptr<SOwner> bufferWeak            = sharedBufferOwner;
+        const std::weak_ptr<SOwner> nextWeak              = nextFrameOwner;
+
+        SRuntime                    runtime(plan(9, owner("last-frame-plan")));
+        EXPECT(runtime.publishIdle({member(11, 211, 777, leftFramebufferOwner, sharedBufferOwner), member(22, 222, 777, rightFramebufferOwner, sharedBufferOwner)}), true);
+        leftFramebufferOwner.reset();
+        rightFramebufferOwner.reset();
+        sharedBufferOwner.reset();
+        EXPECT(enumValue(runtime.prepare(route(1'100, 9), frame(990, 990, std::move(nextFrameOwner)), 9'000)), enumValue(eTiledRuntimePrepareError::NONE));
+
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        EXPECT(runtime.accept().accepted, true);
+        EXPECT(registry.accept(reserved.reservation), true);
+        EXPECT(enumValue(runtime.record(1'100, 11, 1, 100).disposition), enumValue(eTiledEventDisposition::RECORDED));
+        auto completed = runtime.record(1'100, 22, 2, 101);
+        EXPECT(enumValue(completed.disposition), enumValue(eTiledEventDisposition::COMPLETED));
+        EXPECT(completed.releases.size(), 1U);
+        EXPECT(completed.releases.front().bufferId, 777U);
+        EXPECT(completed.releases.front().owner->name, "shared-old-buffer");
+        EXPECT(runtime.lastFrames().size(), 2U);
+        EXPECT(runtime.lastFrames().at(0).framebufferId, 211U);
+        EXPECT(runtime.lastFrames().at(1).framebufferId, 222U);
+        EXPECT(leftWeak.expired(), false);
+        EXPECT(rightWeak.expired(), false);
+        EXPECT(bufferWeak.expired(), false);
+        completed.releases.clear();
+        EXPECT(leftWeak.expired(), false);
+        EXPECT(rightWeak.expired(), false);
+        EXPECT(bufferWeak.expired(), false);
+        EXPECT(registry.retire(completed.reservation.value_or(STiledFlipReservation{})), true);
+
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::OUTPUT_DISABLED).requestRecovery, true);
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        EXPECT(leftWeak.expired(), true);
+        EXPECT(rightWeak.expired(), true);
+        EXPECT(bufferWeak.expired(), true);
+        EXPECT(nextWeak.expired(), false);
+        retired.releases.clear();
+        EXPECT(nextWeak.expired(), true);
+        EXPECT(terminalTeardown(runtime), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        auto                        planOwner    = owner("timeout-plan");
+        auto                        currentOwner = owner("timeout-current");
+        auto                        pendingOwner = owner("timeout-pending");
+        const std::weak_ptr<SOwner> currentWeak  = currentOwner;
+        const std::weak_ptr<SOwner> pendingWeak  = pendingOwner;
+        SRuntime                    runtime(plan(20, std::move(planOwner)));
+        EXPECT(runtime.publishIdle({member(11, 301, 701, currentOwner), member(22, 302, 701, currentOwner)}), true);
+        currentOwner.reset();
+        EXPECT(enumValue(runtime.prepare(route(2'000, 20), frame(999, 999, std::move(pendingOwner)), 1'000)), enumValue(eTiledRuntimePrepareError::NONE));
+
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        EXPECT(runtime.accept().accepted, true);
+        EXPECT(registry.accept(reserved.reservation), true);
+        EXPECT(enumValue(runtime.record(2'000, 11, 1, 900).disposition), enumValue(eTiledEventDisposition::RECORDED));
+        EXPECT(enumValue(runtime.expire(999).disposition), enumValue(eTiledEventDisposition::NO_EFFECT));
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_IN_FLIGHT));
+
+        const auto timeout = runtime.expire(1'000);
+        EXPECT(enumValue(timeout.disposition), enumValue(eTiledEventDisposition::TIMED_OUT));
+        EXPECT(timeout.schedulerInvalidate, true);
+        EXPECT(timeout.requestRecovery, true);
+        EXPECT(timeout.quiesceReservation, true);
+        EXPECT(timeout.releases.empty(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::QUIESCED));
+        EXPECT(enumValue(runtime.quiesceReason()), enumValue(eTiledQuiesceReason::EVENT_TIMEOUT));
+        EXPECT(registry.quiesce(timeout.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(currentWeak.expired(), false);
+        EXPECT(pendingWeak.expired(), false);
+
+        const auto afterTimeout = runtime.record(2'000, 22, 2, 1'001);
+        EXPECT(enumValue(afterTimeout.disposition), enumValue(eTiledEventDisposition::QUIESCED));
+        EXPECT(noCompletionEffects(afterTimeout), true);
+        EXPECT(runtime.retire(eTiledRetirementProof::NONE).retired, false);
+        EXPECT(currentWeak.expired(), false);
+        EXPECT(pendingWeak.expired(), false);
+
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        EXPECT(retired.retireReservation, true);
+        EXPECT(retired.releases.size(), 2U);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_DISABLED));
+        EXPECT(registry.retire(retired.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(currentWeak.expired(), false);
+        EXPECT(pendingWeak.expired(), false);
+        retired.releases.clear();
+        EXPECT(currentWeak.expired(), true);
+        EXPECT(pendingWeak.expired(), true);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, false);
+        EXPECT(terminalTeardown(runtime), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        SRuntime runtime(plan(25, owner("initial-modeset-plan")));
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(enumValue(runtime.prepare(route(2'500, 25), frame(950, 950, owner("initial-modeset-frame")), 3'000)), enumValue(eTiledRuntimePrepareError::NONE));
+
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        EXPECT(runtime.accept().accepted, true);
+        EXPECT(registry.accept(reserved.reservation), true);
+
+        // Primary can arrive first; it is retained until the final member and
+        // still supplies the logical presentation sequence.
+        const auto primaryFirst = runtime.record(2'500, 11, 77, 2'000);
+        EXPECT(enumValue(primaryFirst.disposition), enumValue(eTiledEventDisposition::RECORDED));
+        EXPECT(noCompletionEffects(primaryFirst), true);
+        auto secondaryFinal = runtime.record(2'500, 22, 88, 1'990);
+        EXPECT(enumValue(secondaryFinal.disposition), enumValue(eTiledEventDisposition::COMPLETED));
+        const auto presentation = secondaryFinal.presentation.value_or(STiledPresentationSample{});
+        EXPECT(presentation.primarySequence, 77U);
+        EXPECT(presentation.timestampNs, 2'000U);
+        EXPECT(secondaryFinal.releases.empty(), true);
+        EXPECT(runtime.members().at(0).lastFramebuffer, 0U);
+        EXPECT(runtime.members().at(0).frontFramebuffer, 950U);
+        EXPECT(runtime.members().at(1).lastFramebuffer, 0U);
+        EXPECT(runtime.members().at(1).frontFramebuffer, 950U);
+        EXPECT(registry.retire(secondaryFinal.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::OUTPUT_DISABLED).requestRecovery, true);
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        retired.releases.clear();
+        EXPECT(terminalTeardown(runtime), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        SRuntime runtime(plan(26, owner("allocation-free-rotation-plan")));
+        EXPECT(runtime.publishDisabled(), true);
+        const auto CURRENT_CAPACITY = runtime.currentFrames().capacity();
+        const auto LAST_CAPACITY    = runtime.lastFrames().capacity();
+        EXPECT(CURRENT_CAPACITY >= runtime.members().size(), true);
+        EXPECT(LAST_CAPACITY >= runtime.members().size(), true);
+
+        CTiledFlipReservationRegistry registry;
+        for (uint64_t I = 0; I < 2; ++I) {
+            const auto TOKEN = static_cast<uintptr_t>(2'600 + I);
+            EXPECT(enumValue(runtime.prepare(route(TOKEN, 26), frame(960 + I, 960 + I, owner("rotation-frame-" + std::to_string(I))), 3'100 + I)),
+                   enumValue(eTiledRuntimePrepareError::NONE));
+            const auto reserved = registry.reserveAll(*runtime.preparedRoute());
+            EXPECT(!!reserved, true);
+            EXPECT(runtime.bindReservation(reserved.reservation), true);
+            EXPECT(runtime.accept().accepted, true);
+            EXPECT(registry.accept(reserved.reservation), true);
+            EXPECT(enumValue(runtime.record(TOKEN, 11, static_cast<uint32_t>(10 + I), 2'100 + I).disposition), enumValue(eTiledEventDisposition::RECORDED));
+            auto completed = runtime.record(TOKEN, 22, static_cast<uint32_t>(20 + I), 2'110 + I);
+            EXPECT(enumValue(completed.disposition), enumValue(eTiledEventDisposition::COMPLETED));
+            EXPECT(registry.retire(completed.reservation.value_or(STiledFlipReservation{})), true);
+            EXPECT(runtime.currentFrames().capacity(), CURRENT_CAPACITY);
+            EXPECT(runtime.lastFrames().capacity(), LAST_CAPACITY);
+            EXPECT(runtime.currentFrames().size(), 1U);
+            EXPECT(runtime.lastFrames().size(), static_cast<size_t>(I));
+        }
+
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::OUTPUT_DISABLED).requestRecovery, true);
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        retired.releases.clear();
+        EXPECT(terminalTeardown(runtime), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        auto                        pendingOwner = owner("preaccept-pending");
+        const std::weak_ptr<SOwner> pendingWeak  = pendingOwner;
+        SRuntime                    runtime(plan(27, owner("preaccept-plan")));
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(enumValue(runtime.prepare(route(2'700, 27), frame(970, 970, std::move(pendingOwner)), 3'500)), enumValue(eTiledRuntimePrepareError::NONE));
+
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        const auto incomplete = runtime.quiesce(eTiledQuiesceReason::INCOMPLETE_SCAN);
+        EXPECT(incomplete.rollbackReservation, true);
+        EXPECT(incomplete.quiesceReservation, false);
+        EXPECT(incomplete.schedulerInvalidate, false);
+        EXPECT(registry.rollback(incomplete.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(pendingWeak.expired(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::QUIESCED));
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                        currentOwner = owner("rollback-current");
+        auto                        pendingOwner = owner("rollback-pending");
+        auto                        planOwner    = owner("rollback-plan");
+        const std::weak_ptr<SOwner> pendingWeak  = pendingOwner;
+        SRuntime                    runtime(plan(30, planOwner));
+        EXPECT(runtime.publishIdle({member(11, 401, 801, currentOwner), member(22, 402, 801, currentOwner)}), true);
+        EXPECT(enumValue(runtime.prepare(route(3'000, 30), frame(1'001, 1'001, std::move(pendingOwner)), 5'000)), enumValue(eTiledRuntimePrepareError::NONE));
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        EXPECT(enumValue(runtime.stageSuccessor(plan(31, planOwner)).result), enumValue(eTiledSuccessorResult::STAGED));
+        EXPECT(runtime.activePlan().generation, 30U);
+        EXPECT(runtime.rollbackPrepared(), true);
+        EXPECT(runtime.activePlan().generation, 31U);
+        EXPECT(registry.rollback(reserved.reservation), true);
+        EXPECT(pendingWeak.expired(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_IDLE));
+        EXPECT(runtime.currentFrames().front().bufferId, 801U);
+        EXPECT(runtime.accept().accepted, false);
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::OUTPUT_DISABLED).requestRecovery, true);
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        retired.releases.clear();
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                        planOwner    = owner("unexpected-plan");
+        auto                        currentOwner = owner("unexpected-current");
+        auto                        pendingOwner = owner("unexpected-pending");
+        const std::weak_ptr<SOwner> planWeak     = planOwner;
+        const std::weak_ptr<SOwner> currentWeak  = currentOwner;
+        const std::weak_ptr<SOwner> pendingWeak  = pendingOwner;
+        SRuntime                    runtime(plan(40, std::move(planOwner)));
+        EXPECT(runtime.publishIdle({member(11, 501, 901, currentOwner), member(22, 502, 901, currentOwner)}), true);
+        currentOwner.reset();
+        EXPECT(enumValue(runtime.prepare(route(4'000, 40), frame(1'100, 1'100, std::move(pendingOwner)), 6'000)), enumValue(eTiledRuntimePrepareError::NONE));
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        EXPECT(runtime.accept().accepted, true);
+        EXPECT(registry.accept(reserved.reservation), true);
+
+        const auto unexpected = runtime.record(4'000, 99, 1, 1);
+        EXPECT(enumValue(unexpected.disposition), enumValue(eTiledEventDisposition::UNEXPECTED_CRTC));
+        EXPECT(unexpected.schedulerInvalidate, true);
+        EXPECT(unexpected.quiesceReservation, true);
+        EXPECT(unexpected.releases.empty(), true);
+        EXPECT(registry.quiesce(unexpected.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(planWeak.expired(), false);
+        EXPECT(currentWeak.expired(), false);
+        EXPECT(pendingWeak.expired(), false);
+
+        auto teardown = runtime.retire(eTiledRetirementProof::BACKEND_TEARDOWN_NO_CALLBACKS);
+        EXPECT(teardown.retired, true);
+        EXPECT(teardown.releases.empty(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::TEARDOWN));
+        EXPECT(registry.retire(teardown.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(planWeak.expired(), true);
+        EXPECT(currentWeak.expired(), true);
+        EXPECT(pendingWeak.expired(), true);
+        EXPECT(runtime.readyForDestruction(), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        SRuntime runtime(plan(50, owner("session-plan")));
+        EXPECT(runtime.publishIdle({member(11, 601, 1'201, owner("session-buffer")), member(22, 602, 1'201, owner("session-buffer"))}), true);
+        const auto inactive = runtime.quiesce(eTiledQuiesceReason::SESSION_INACTIVE);
+        EXPECT(inactive.requestRecovery, true);
+        EXPECT(inactive.schedulerInvalidate, false);
+        EXPECT(runtime.takeSessionRestoreRequest(), true);
+        EXPECT(runtime.takeSessionRestoreRequest(), false);
+        EXPECT(enumValue(runtime.quiesceReason()), enumValue(eTiledQuiesceReason::SESSION_INACTIVE));
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto     stablePlanOwner = owner("same-mode-definition-plan");
+        SRuntime runtime(plan(53, stablePlanOwner));
+        EXPECT(runtime.publishDisabled(), true);
+        const auto transition = runtime.stageSuccessor(plan(54, stablePlanOwner, 56));
+        EXPECT(enumValue(transition.result), enumValue(eTiledSuccessorResult::NON_EQUIVALENT));
+        EXPECT(transition.effects.requestRecovery, true);
+        EXPECT(transition.effects.schedulerInvalidate, false);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                        pendingOwner = owner("successor-prepared-pending");
+        const std::weak_ptr<SOwner> pendingWeak  = pendingOwner;
+        SRuntime                    runtime(plan(55, owner("successor-prepared-plan")));
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(enumValue(runtime.prepare(route(5'500, 55), frame(1'550, 1'550, std::move(pendingOwner)), 8'000)), enumValue(eTiledRuntimePrepareError::NONE));
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+
+        const auto transition = runtime.stageSuccessor(plan(56, owner("successor-prepared-invalid"), 99));
+        EXPECT(enumValue(transition.result), enumValue(eTiledSuccessorResult::NON_EQUIVALENT));
+        EXPECT(transition.effects.requestRecovery, true);
+        EXPECT(transition.effects.rollbackReservation, true);
+        EXPECT(transition.effects.quiesceReservation, false);
+        EXPECT(transition.effects.schedulerInvalidate, false);
+        EXPECT(transition.effects.reservation == reserved.reservation, true);
+        EXPECT(registry.rollback(transition.effects.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(pendingWeak.expired(), true);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                        currentOwner = owner("successor-inflight-current");
+        auto                        pendingOwner = owner("successor-inflight-pending");
+        const std::weak_ptr<SOwner> currentWeak  = currentOwner;
+        const std::weak_ptr<SOwner> pendingWeak  = pendingOwner;
+        SRuntime                    runtime(plan(57, owner("successor-inflight-plan")));
+        EXPECT(runtime.publishIdle({member(11, 711, 1'711, currentOwner), member(22, 722, 1'711, currentOwner)}), true);
+        currentOwner.reset();
+        EXPECT(enumValue(runtime.prepare(route(5'700, 57), frame(1'770, 1'770, std::move(pendingOwner)), 8'500)), enumValue(eTiledRuntimePrepareError::NONE));
+        CTiledFlipReservationRegistry registry;
+        const auto                    reserved = registry.reserveAll(*runtime.preparedRoute());
+        EXPECT(runtime.bindReservation(reserved.reservation), true);
+        EXPECT(runtime.accept().accepted, true);
+        EXPECT(registry.accept(reserved.reservation), true);
+
+        const auto transition = runtime.stageSuccessor(plan(58, owner("successor-inflight-invalid"), 99));
+        EXPECT(enumValue(transition.result), enumValue(eTiledSuccessorResult::NON_EQUIVALENT));
+        EXPECT(transition.effects.requestRecovery, true);
+        EXPECT(transition.effects.rollbackReservation, false);
+        EXPECT(transition.effects.quiesceReservation, true);
+        EXPECT(transition.effects.schedulerInvalidate, true);
+        EXPECT(transition.effects.reservation == reserved.reservation, true);
+        EXPECT(registry.quiesce(transition.effects.reservation.value_or(STiledFlipReservation{})), true);
+        EXPECT(currentWeak.expired(), false);
+        EXPECT(pendingWeak.expired(), false);
+
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        EXPECT(retired.retired, true);
+        EXPECT(retired.retireReservation, true);
+        EXPECT(retired.releases.size(), 2U);
+        EXPECT(registry.retire(retired.reservation.value_or(STiledFlipReservation{})), true);
+        retired.releases.clear();
+        EXPECT(currentWeak.expired(), true);
+        EXPECT(pendingWeak.expired(), true);
+        EXPECT(terminalTeardown(runtime), true);
+        EXPECT(registry.shutdown(eTiledRegistryShutdownProof::BACKEND_NO_CALLBACKS), true);
+    }
+
+    {
+        auto     stablePlanOwner = owner("successor-plan");
+        SRuntime runtime(plan(60, stablePlanOwner));
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(enumValue(runtime.stageSuccessor(plan(61, stablePlanOwner)).result), enumValue(eTiledSuccessorResult::ADOPTED));
+        EXPECT(runtime.activePlan().generation, 61U);
+        EXPECT(runtime.activePlan().definitionIdentity == stablePlanOwner->definitions.at(55), true);
+        EXPECT(enumValue(runtime.stageSuccessor(plan(61, stablePlanOwner)).result), enumValue(eTiledSuccessorResult::STALE_GENERATION));
+        const auto nonEquivalent = runtime.stageSuccessor(plan(62, owner("same-definition-new-owner")));
+        EXPECT(enumValue(nonEquivalent.result), enumValue(eTiledSuccessorResult::NON_EQUIVALENT));
+        EXPECT(nonEquivalent.effects.requestRecovery, true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::QUIESCED));
+        EXPECT(enumValue(runtime.quiesceReason()), enumValue(eTiledQuiesceReason::INVALID_TOPOLOGY));
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                                        planOwner = owner("same-crtcs-different-plane");
+        const std::vector<STiledRuntimeMemberRoute> routes{
+            {.connectorId = 1, .crtcId = 11, .primaryPlaneId = 101},
+            {.connectorId = 2, .crtcId = 22, .primaryPlaneId = 102},
+        };
+        auto changedPlane                 = routes;
+        changedPlane.at(1).primaryPlaneId = 202;
+
+        SRuntime runtime(plan(65, planOwner, 55, {11, 22}, 11, routes));
+        EXPECT(runtime.publishDisabled(), true);
+        const auto transition = runtime.stageSuccessor(plan(66, planOwner, 55, {11, 22}, 11, std::move(changedPlane)));
+        EXPECT(enumValue(transition.result), enumValue(eTiledSuccessorResult::NON_EQUIVALENT));
+        EXPECT(transition.effects.requestRecovery, true);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                                        planOwner = owner("swapped-member-crtcs");
+        const std::vector<STiledRuntimeMemberRoute> routes{
+            {.connectorId = 1, .crtcId = 11, .primaryPlaneId = 101},
+            {.connectorId = 2, .crtcId = 22, .primaryPlaneId = 102},
+        };
+        const std::vector<STiledRuntimeMemberRoute> swapped{
+            {.connectorId = 1, .crtcId = 22, .primaryPlaneId = 102},
+            {.connectorId = 2, .crtcId = 11, .primaryPlaneId = 101},
+        };
+
+        SRuntime runtime(plan(67, planOwner, 55, {11, 22}, 11, routes));
+        EXPECT(runtime.publishDisabled(), true);
+        const auto transition = runtime.stageSuccessor(plan(68, planOwner, 55, {11, 22}, 11, swapped));
+        EXPECT(enumValue(transition.result), enumValue(eTiledSuccessorResult::NON_EQUIVALENT));
+        EXPECT(transition.effects.requestRecovery, true);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
+    {
+        auto                        retainedPlan = owner("incomplete-scan-plan");
+        const std::weak_ptr<SOwner> retainedWeak = retainedPlan;
+        SRuntime                    runtime(plan(70, std::move(retainedPlan)));
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::INCOMPLETE_SCAN).requestRecovery, true);
+        EXPECT(runtime.activePlan().generation, 70U);
+        EXPECT(retainedWeak.expired(), false);
+        EXPECT(runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED).retired, true);
+        EXPECT(retainedWeak.expired(), false);
+        EXPECT(runtime.quiesce(eTiledQuiesceReason::BACKEND_TEARDOWN).requestRecovery, true);
+        EXPECT(runtime.retire(eTiledRetirementProof::DRM_DEVICE_GONE).retired, true);
+        EXPECT(runtime.readyForDestruction(), true);
+        EXPECT(retainedWeak.expired(), true);
+    }
+
+    {
+        SRuntime invalid(plan(0, owner("invalid-plan")));
+        EXPECT(invalid.valid(), false);
+        EXPECT(enumValue(invalid.state()), enumValue(eTiledRuntimeState::QUIESCED));
+        EXPECT(enumValue(invalid.quiesceReason()), enumValue(eTiledQuiesceReason::INVALID_TOPOLOGY));
+    }
+
+    {
+        SRuntime invalidOwner(plan(80, {}));
+        EXPECT(invalidOwner.valid(), false);
+        EXPECT(enumValue(invalidOwner.quiesceReason()), enumValue(eTiledQuiesceReason::INVALID_TOPOLOGY));
+    }
+
+    return ret;
+}
diff --git a/tests/TiledVisibility.cmake b/tests/TiledVisibility.cmake
index bf6c7ec9584d9e41a27e6c5f18c52cf702eceddf..9e00a20262d7367f6cdc767903693ea971fb1ea0 100644
--- a/tests/TiledVisibility.cmake
+++ b/tests/TiledVisibility.cmake
@@ -74,6 +74,6 @@ if(NOT demangle_result EQUAL 0)
 endif()
 
 if(demangled_output MATCHES
-   "Aquamarine::(NTiling|TiledCrtcAllocator)::|Aquamarine::NDRM::NTiled(CrtcAllocator|Incarnations|Scan|DRMIntegration|OutputBridge)::|Aquamarine::NDRM::.*(Tile|tile|PlaneViewport|PlaneFormats|intersectPlaneFormats|encodePlaneViewport)")
+   "Aquamarine::(NTiling|TiledCrtcAllocator)::|Aquamarine::NDRM::NTiled(CrtcAllocator|Incarnations|Scan|DRMIntegration|OutputBridge)::|Aquamarine::NDRM::.*(Tile|tile|PageFlip|TiledRuntime|TiledFlip|AtomicSubmit|normalizeDRMCallError|submitAtomicRequest|PlaneViewport|PlaneFormats|intersectPlaneFormats|encodePlaneViewport)")
   message(FATAL_ERROR "source-private TILE symbol family is dynamically exported")
 endif()