Subject: [PATCH 16/24] wip: add initial tiled modeset transaction

From: Justin Youens <[email-masked]>
Date: Sat, 15 Aug 2026 11:40:43 -0500

---
 src/backend/drm/TiledAtomic.cpp  |  45 ++---
 src/backend/drm/TiledAtomic.hpp  | 297 +++++++++++++++++++------------
 src/backend/drm/TiledRuntime.cpp |  17 ++
 src/backend/drm/TiledRuntime.hpp |  42 ++++-
 tests/TiledAtomic.cpp            | 232 +++++++++++++++++++++++-
 5 files changed, 488 insertions(+), 145 deletions(-)

diff --git a/src/backend/drm/TiledAtomic.cpp b/src/backend/drm/TiledAtomic.cpp
index 531084848298c8fb4e66e689bac577f39dc0c321..413e559587a63594875fc4206d435375404e6ac5 100644
--- a/src/backend/drm/TiledAtomic.cpp
+++ b/src/backend/drm/TiledAtomic.cpp
@@ -221,10 +221,11 @@ namespace Aquamarine::NDRM::NTiledAtomic {
     };
 
     struct SRequestAssembler {
-        static PPreparedTiledTestModeset create(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations, PModeBlobCleanupRegistry cleanupRegistry,
-                                                drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs, std::vector<PModeBlobCleanupRecord> modeBlobOwners) {
-            CSharedPointer<CPreparedTiledTestModeset> prepared{
-                new CPreparedTiledTestModeset{std::move(route), std::move(operations), std::move(cleanupRegistry), request, std::move(modeBlobs), std::move(modeBlobOwners)}};
+        static PPreparedTiledModesetRequest create(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations,
+                                                   PModeBlobCleanupRegistry cleanupRegistry, drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs,
+                                                   std::vector<PModeBlobCleanupRecord> modeBlobOwners) {
+            CSharedPointer<CPreparedTiledModesetRequest> prepared{
+                new CPreparedTiledModesetRequest{std::move(route), std::move(operations), std::move(cleanupRegistry), request, std::move(modeBlobs), std::move(modeBlobOwners)}};
             return prepared;
         }
     };
@@ -530,37 +531,33 @@ STiledAtomicResolveResult Aquamarine::NDRM::NTiledAtomic::resolveCapturedTiledAt
     } catch (...) { return {.error = eTiledAtomicError::ALLOCATION_FAILED}; }
 }
 
-CPreparedTiledTestModeset::CPreparedTiledTestModeset(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations,
-                                                     PModeBlobCleanupRegistry cleanupRegistry, drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs,
-                                                     std::vector<PModeBlobCleanupRecord> modeBlobOwners) noexcept :
+CPreparedTiledModesetRequest::CPreparedTiledModesetRequest(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations,
+                                                           PModeBlobCleanupRegistry cleanupRegistry, drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs,
+                                                           std::vector<PModeBlobCleanupRecord> modeBlobOwners) noexcept :
     m_route(std::move(route)), m_operations(std::move(operations)), m_cleanupRegistry(std::move(cleanupRegistry)), m_request(request), m_modeBlobs(std::move(modeBlobs)),
     m_modeBlobOwners(std::move(modeBlobOwners)) {}
 
-CPreparedTiledTestModeset::~CPreparedTiledTestModeset() noexcept {
+CPreparedTiledModesetRequest::~CPreparedTiledModesetRequest() noexcept {
     static_cast<void>(cleanup());
 }
 
-const PResolvedTiledAtomicRoute& CPreparedTiledTestModeset::route() const noexcept {
+const PResolvedTiledAtomicRoute& CPreparedTiledModesetRequest::route() const noexcept {
     return m_route;
 }
 
-drmModeAtomicReqPtr CPreparedTiledTestModeset::request() const noexcept {
+drmModeAtomicReqPtr CPreparedTiledModesetRequest::request() const noexcept {
     return m_request;
 }
 
-uint32_t CPreparedTiledTestModeset::flags() const noexcept {
-    return TILED_ATOMIC_TEST_MODESET_FLAGS;
+const CSharedPointer<ITiledAtomicRequestOperations>& CPreparedTiledModesetRequest::operations() const noexcept {
+    return m_operations;
 }
 
-uintptr_t CPreparedTiledTestModeset::userData() const noexcept {
-    return 0;
-}
-
-std::span<const uint32_t> CPreparedTiledTestModeset::modeBlobs() const noexcept {
+std::span<const uint32_t> CPreparedTiledModesetRequest::modeBlobs() const noexcept {
     return m_modeBlobs;
 }
 
-STiledModeBlobCleanupOutcome CPreparedTiledTestModeset::cleanup() noexcept {
+STiledModeBlobCleanupOutcome CPreparedTiledModesetRequest::cleanup() noexcept {
     freeRequest(m_operations, m_request);
     if (!m_cleanupRegistry && !m_modeBlobOwners.empty())
         std::terminate();
@@ -574,9 +571,9 @@ STiledAtomicBuildResult::operator bool() const noexcept {
     return error == eTiledAtomicError::NONE && prepared;
 }
 
-STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledTestModeset(const PResolvedTiledAtomicRoute& route, int drmFD,
-                                                                              const CSharedPointer<ITiledAtomicRequestOperations>& operations,
-                                                                              const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept {
+STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledModesetRequest(const PResolvedTiledAtomicRoute& route, int drmFD,
+                                                                                 const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                                 const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept {
     if (!route)
         return {.error = eTiledAtomicError::INVALID_INPUT};
     if (!operations || !cleanupRegistry || drmFD < 0 || cleanupRegistry->drmFD() != drmFD)
@@ -633,6 +630,12 @@ STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledTestModeset(co
     } catch (...) { return fail(eTiledAtomicError::ALLOCATION_FAILED); }
 }
 
+STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledTestModeset(const PResolvedTiledAtomicRoute& route, int drmFD,
+                                                                              const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                              const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept {
+    return buildTiledModesetRequest(route, drmFD, operations, cleanupRegistry);
+}
+
 STiledTestModesetExecutionResult::operator bool() const noexcept {
     return status == eTiledTestModesetStatus::SUCCEEDED;
 }
diff --git a/src/backend/drm/TiledAtomic.hpp b/src/backend/drm/TiledAtomic.hpp
index 83fc8790a36d08f8cdedd79eac0cbf853f59eada..0bfa8f327f5905dd39a997e5d3713022dbae7498 100644
--- a/src/backend/drm/TiledAtomic.hpp
+++ b/src/backend/drm/TiledAtomic.hpp
@@ -214,8 +214,9 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         virtual int                 submit(int drmFD, drmModeAtomicReqPtr request, uint32_t flags, void* userData) noexcept                   = 0;
     };
 
-    // TEST_MODESET extends the normal-frame request boundary with temporary
-    // mode-blob ownership. One production implementation can serve both paths.
+    // Full modeset requests extend the normal-frame boundary with temporary
+    // mode-blob ownership. One production implementation serves TEST_ONLY and
+    // dormant initial-frame paths.
     class AQ_TILED_ATOMIC_PRIVATE ITiledAtomicRequestOperations : public ITiledAtomicFrameOperations {
       public:
         ~ITiledAtomicRequestOperations() override = default;
@@ -272,31 +273,33 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         bool                                       m_abandoned = false;
         std::vector<PModeBlobCleanupRecord>        m_records;
 
-        friend class CPreparedTiledTestModeset;
+        friend class CPreparedTiledModesetRequest;
         friend struct SBuildResources;
     };
 
-    class CPreparedTiledTestModeset;
-    using PPreparedTiledTestModeset = CSharedPointer<CPreparedTiledTestModeset>;
+    class CPreparedTiledModesetRequest;
+    using PPreparedTiledModesetRequest = CSharedPointer<CPreparedTiledModesetRequest>;
+    using PPreparedTiledTestModeset    = PPreparedTiledModesetRequest;
 
-    class AQ_TILED_ATOMIC_PRIVATE CPreparedTiledTestModeset final {
+    // Neutral full connector/CRTC/plane request. The caller fixes TEST_ONLY or
+    // real initial-frame flags; this owner only manages request/blob lifetime.
+    class AQ_TILED_ATOMIC_PRIVATE CPreparedTiledModesetRequest final {
       public:
-        CPreparedTiledTestModeset(const CPreparedTiledTestModeset&)            = delete;
-        CPreparedTiledTestModeset(CPreparedTiledTestModeset&&)                 = delete;
-        CPreparedTiledTestModeset& operator=(const CPreparedTiledTestModeset&) = delete;
-        CPreparedTiledTestModeset& operator=(CPreparedTiledTestModeset&&)      = delete;
-        ~CPreparedTiledTestModeset() noexcept;
+        CPreparedTiledModesetRequest(const CPreparedTiledModesetRequest&)            = delete;
+        CPreparedTiledModesetRequest(CPreparedTiledModesetRequest&&)                 = delete;
+        CPreparedTiledModesetRequest& operator=(const CPreparedTiledModesetRequest&) = delete;
+        CPreparedTiledModesetRequest& operator=(CPreparedTiledModesetRequest&&)      = delete;
+        ~CPreparedTiledModesetRequest() noexcept;
 
-        [[nodiscard]] const PResolvedTiledAtomicRoute& route() const noexcept;
-        [[nodiscard]] drmModeAtomicReqPtr              request() const noexcept;
-        [[nodiscard]] uint32_t                         flags() const noexcept;
-        [[nodiscard]] uintptr_t                        userData() const noexcept;
-        [[nodiscard]] std::span<const uint32_t>        modeBlobs() const noexcept;
-        [[nodiscard]] STiledModeBlobCleanupOutcome     cleanup() noexcept;
+        [[nodiscard]] const PResolvedTiledAtomicRoute&                     route() const noexcept;
+        [[nodiscard]] drmModeAtomicReqPtr                                  request() const noexcept;
+        [[nodiscard]] const CSharedPointer<ITiledAtomicRequestOperations>& operations() const noexcept;
+        [[nodiscard]] std::span<const uint32_t>                            modeBlobs() const noexcept;
+        [[nodiscard]] STiledModeBlobCleanupOutcome                         cleanup() noexcept;
 
       private:
-        CPreparedTiledTestModeset(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations, PModeBlobCleanupRegistry cleanupRegistry,
-                                  drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs, std::vector<PModeBlobCleanupRecord> modeBlobOwners) noexcept;
+        CPreparedTiledModesetRequest(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations, PModeBlobCleanupRegistry cleanupRegistry,
+                                     drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs, std::vector<PModeBlobCleanupRecord> modeBlobOwners) noexcept;
 
         PResolvedTiledAtomicRoute                     m_route;
         CSharedPointer<ITiledAtomicRequestOperations> m_operations;
@@ -309,7 +312,7 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
     };
 
     struct AQ_TILED_ATOMIC_PRIVATE STiledAtomicBuildResult {
-        PPreparedTiledTestModeset    prepared;
+        PPreparedTiledModesetRequest prepared;
         eTiledAtomicError            error = eTiledAtomicError::INVALID_INPUT;
         STiledModeBlobCleanupOutcome cleanup;
         PModeBlobCleanupRegistry     retainedCleanup;
@@ -317,6 +320,9 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         explicit                     operator bool() const noexcept;
     };
 
+    [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledAtomicBuildResult buildTiledModesetRequest(const PResolvedTiledAtomicRoute& route, int drmFD,
+                                                                                           const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                                           const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept;
     [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledAtomicBuildResult buildTiledTestModeset(const PResolvedTiledAtomicRoute& route, int drmFD,
                                                                                         const CSharedPointer<ITiledAtomicRequestOperations>& operations,
                                                                                         const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept;
@@ -349,7 +355,8 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
                                                                                                    const CSharedPointer<ITiledAtomicRequestOperations>& operations,
                                                                                                    const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept;
 
-    inline constexpr uint32_t                                              TILED_ATOMIC_FRAME_FLAGS = DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
+    inline constexpr uint32_t                                              TILED_ATOMIC_FRAME_FLAGS         = DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
+    inline constexpr uint32_t                                              TILED_ATOMIC_INITIAL_FRAME_FLAGS = TILED_ATOMIC_FRAME_FLAGS | DRM_MODE_ATOMIC_ALLOW_MODESET;
 
     enum class eTiledFrameTransactionStatus : uint8_t {
         ACCEPTED = 0,
@@ -415,6 +422,8 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         bool                                 registryAccepted    = false;
         bool                                 runtimeRolledBack   = false;
         bool                                 registryRolledBack  = false;
+        bool                                 runtimeRecovered    = false;
+        bool                                 registryRecovered   = false;
         STiledRuntimeAcceptEffects           runtimeAccept;
         std::optional<STiledFlipReservation> reservation;
     };
@@ -429,12 +438,129 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         explicit                           operator bool() const noexcept;
     };
 
+    namespace NDetail {
+        template <typename TOwner, typename TOperations>
+        [[nodiscard]] STiledFrameTransactionResult submitPreparedTiledFrameTransaction(const PResolvedTiledAtomicRoute& route, CTiledFrameRuntime<TOwner>& runtime,
+                                                                                       CTiledFlipReservationRegistry& registry, STiledRuntimeFrame<TOwner> frame,
+                                                                                       uintptr_t transactionId, uint64_t deadlineNs, int drmFD, const TOperations& operations,
+                                                                                       drmModeAtomicReqPtr request, uint32_t flags, eTiledRuntimeState requiredState) noexcept {
+            STiledFrameTransactionResult result;
+            if (!route || !operations || !request || drmFD < 0 || transactionId == 0 || deadlineNs == 0 || frame.framebufferId != route->framebuffer().id) {
+                result.status = !operations || drmFD < 0 ? eTiledFrameTransactionStatus::INVALID_OPERATIONS : eTiledFrameTransactionStatus::INVALID_INPUT;
+                return result;
+            }
+            if (!route->matchesRuntimePlan(runtime.activePlan())) {
+                result.status = eTiledFrameTransactionStatus::ROUTE_RUNTIME_MISMATCH;
+                return result;
+            }
+            if (runtime.state() != requiredState) {
+                result.runtimePrepareError = eTiledRuntimePrepareError::INVALID_STATE;
+                result.status              = eTiledFrameTransactionStatus::RUNTIME_PREPARE_FAILED;
+                return result;
+            }
+            result.effects.requestBuilt = true;
+
+            const auto ROLLBACK_RUNTIME = [&]() noexcept {
+                if (result.effects.runtimePrepared)
+                    result.effects.runtimeRolledBack = runtime.rollbackPrepared();
+            };
+            const auto ROLLBACK_REGISTRY = [&]() noexcept {
+                if (result.effects.reservationReserved && result.effects.reservation)
+                    result.effects.registryRolledBack = registry.rollback(*result.effects.reservation);
+            };
+
+            try {
+                STiledFlipRoute runtimeRoute{
+                    .transactionId = transactionId,
+                    .generation    = route->generation(),
+                    .crtcIds       = {route->crtcIds().begin(), route->crtcIds().end()},
+                };
+                result.runtimePrepareError = runtime.prepare(std::move(runtimeRoute), std::move(frame), deadlineNs);
+                if (result.runtimePrepareError != eTiledRuntimePrepareError::NONE) {
+                    result.status = eTiledFrameTransactionStatus::RUNTIME_PREPARE_FAILED;
+                    return result;
+                }
+                result.effects.runtimePrepared = true;
+
+                const auto* PREPARED_ROUTE = runtime.preparedRoute();
+                if (!PREPARED_ROUTE) {
+                    ROLLBACK_RUNTIME();
+                    result.status = eTiledFrameTransactionStatus::RUNTIME_PREPARE_FAILED;
+                    return result;
+                }
+
+                for (const auto& MEMBER : route->members()) {
+                    if (!MEMBER.crtc || MEMBER.crtcId == 0 || MEMBER.crtc->id != MEMBER.crtcId) {
+                        ROLLBACK_RUNTIME();
+                        result.status = eTiledFrameTransactionStatus::INVALID_INPUT;
+                        return result;
+                    }
+                    if (MEMBER.crtc->pendingFlip.id.has_value()) {
+                        ROLLBACK_RUNTIME();
+                        result.status = eTiledFrameTransactionStatus::MEMBER_PENDING_FLIP;
+                        return result;
+                    }
+                }
+
+                const auto RESERVED     = registry.reserveAll(*PREPARED_ROUTE);
+                result.reservationError = RESERVED.error;
+                if (!RESERVED) {
+                    ROLLBACK_RUNTIME();
+                    result.status = eTiledFrameTransactionStatus::RESERVATION_FAILED;
+                    return result;
+                }
+                result.effects.reservationReserved = true;
+                result.effects.reservation         = RESERVED.reservation;
+
+                if (!runtime.bindReservation(RESERVED.reservation)) {
+                    ROLLBACK_RUNTIME();
+                    ROLLBACK_REGISTRY();
+                    result.status = eTiledFrameTransactionStatus::RESERVATION_BIND_FAILED;
+                    return result;
+                }
+                result.effects.reservationBound = true;
+
+                result.effects.submitInvoked = true;
+                const auto SUBMISSION        = submitAtomicRequest(
+                    drmFD, request, flags, transactionId,
+                    [&operations](int fd, drmModeAtomicReqPtr submittedRequest, uint32_t submittedFlags, void* userData) noexcept {
+                        return operations->submit(fd, submittedRequest, submittedFlags, userData);
+                    },
+                    [&result, &runtime, &registry, &reserved = RESERVED.reservation](int returnCode) noexcept {
+                        if (returnCode != 0)
+                            return;
+                        result.effects.kmsAccepted     = true;
+                        result.effects.runtimeAccept   = runtime.accept();
+                        result.effects.runtimeAccepted = result.effects.runtimeAccept.accepted;
+                        if (result.effects.runtimeAccepted)
+                            result.effects.registryAccepted = registry.accept(reserved);
+                    });
+                result.submission = SUBMISSION;
+
+                if (!SUBMISSION) {
+                    ROLLBACK_RUNTIME();
+                    ROLLBACK_REGISTRY();
+                    result.status = eTiledFrameTransactionStatus::SUBMISSION_FAILED;
+                    return result;
+                }
+                result.status = result.effects.runtimeAccepted && result.effects.registryAccepted ? eTiledFrameTransactionStatus::ACCEPTED :
+                                                                                                    eTiledFrameTransactionStatus::ACCEPTED_INVARIANT_FAILURE;
+                return result;
+            } catch (...) {
+                if (result.effects.kmsAccepted)
+                    std::terminate();
+                ROLLBACK_RUNTIME();
+                ROLLBACK_REGISTRY();
+                result.status = eTiledFrameTransactionStatus::ALLOCATION_FAILED;
+                return result;
+            }
+        }
+    }
+
     // transactionId must come from the backend-wide nonzero, never-reused
     // allocator documented by STiledFlipRoute. This seam additionally relies
-    // on same-event-thread, non-reentrant submit operations. A successful KMS
-    // call is linearized as runtime.accept() followed by registry.accept(); an
-    // impossible failure in either leaves the accepted/prepared ownership and
-    // reservation intact for a later quiesce/recovery path.
+    // on same-event-thread, non-reentrant submit operations. Its public
+    // contract remains the plane-only PUBLISHED_IDLE frame path.
     template <typename TOwner>
     [[nodiscard]] STiledFrameTransactionResult submitTiledFrameTransaction(const PResolvedTiledAtomicRoute& route, CTiledFrameRuntime<TOwner>& runtime,
                                                                            CTiledFlipReservationRegistry& registry, STiledRuntimeFrame<TOwner> frame, uintptr_t transactionId,
@@ -465,100 +591,41 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
             }
             return result;
         }
-        result.effects.requestBuilt = true;
 
-        const auto ROLLBACK_RUNTIME = [&]() noexcept {
-            if (result.effects.runtimePrepared)
-                result.effects.runtimeRolledBack = runtime.rollbackPrepared();
-        };
-        const auto ROLLBACK_REGISTRY = [&]() noexcept {
-            if (result.effects.reservationReserved && result.effects.reservation)
-                result.effects.registryRolledBack = registry.rollback(*result.effects.reservation);
-        };
+        return NDetail::submitPreparedTiledFrameTransaction(route, runtime, registry, std::move(frame), transactionId, deadlineNs, drmFD, BUILT.prepared->operations(),
+                                                            BUILT.prepared->request(), TILED_ATOMIC_FRAME_FLAGS, eTiledRuntimeState::PUBLISHED_IDLE);
+    }
 
-        try {
-            STiledFlipRoute runtimeRoute{
-                .transactionId = transactionId,
-                .generation    = route->generation(),
-                .crtcIds       = {route->crtcIds().begin(), route->crtcIds().end()},
-            };
-            result.runtimePrepareError = runtime.prepare(std::move(runtimeRoute), std::move(frame), deadlineNs);
-            if (result.runtimePrepareError != eTiledRuntimePrepareError::NONE) {
-                result.status = eTiledFrameTransactionStatus::RUNTIME_PREPARE_FAILED;
-                return result;
-            }
-            result.effects.runtimePrepared = true;
+    // Dormant lower seam for the first real grouped transaction. Before any
+    // future production call, transactionId must come from the backend's
+    // process-global page-flip allocator; no independent grouped counter is
+    // valid. Tests may inject a token only at this source-private boundary.
+    // Accepted invariant failures are recovered synchronously and never rolled
+    // back.
+    template <typename TOwner>
+    [[nodiscard]] STiledFrameTransactionResult submitInitialTiledFrameTransaction(const PPreparedTiledModesetRequest& prepared, CTiledFrameRuntime<TOwner>& runtime,
+                                                                                  CTiledFlipReservationRegistry& registry, STiledRuntimeFrame<TOwner> frame,
+                                                                                  uintptr_t transactionId, uint64_t deadlineNs, int drmFD) noexcept {
+        if (!prepared)
+            return {.status = eTiledFrameTransactionStatus::INVALID_INPUT};
 
-            const auto* PREPARED_ROUTE = runtime.preparedRoute();
-            if (!PREPARED_ROUTE) {
-                ROLLBACK_RUNTIME();
-                result.status = eTiledFrameTransactionStatus::RUNTIME_PREPARE_FAILED;
-                return result;
-            }
-
-            for (const auto& MEMBER : route->members()) {
-                if (!MEMBER.crtc || MEMBER.crtcId == 0 || MEMBER.crtc->id != MEMBER.crtcId) {
-                    ROLLBACK_RUNTIME();
-                    result.status = eTiledFrameTransactionStatus::INVALID_INPUT;
-                    return result;
-                }
-                if (MEMBER.crtc->pendingFlip.id.has_value()) {
-                    ROLLBACK_RUNTIME();
-                    result.status = eTiledFrameTransactionStatus::MEMBER_PENDING_FLIP;
-                    return result;
-                }
-            }
-
-            const auto RESERVED     = registry.reserveAll(*PREPARED_ROUTE);
-            result.reservationError = RESERVED.error;
-            if (!RESERVED) {
-                ROLLBACK_RUNTIME();
-                result.status = eTiledFrameTransactionStatus::RESERVATION_FAILED;
-                return result;
-            }
-            result.effects.reservationReserved = true;
-            result.effects.reservation         = RESERVED.reservation;
-
-            if (!runtime.bindReservation(RESERVED.reservation)) {
-                ROLLBACK_RUNTIME();
-                ROLLBACK_REGISTRY();
-                result.status = eTiledFrameTransactionStatus::RESERVATION_BIND_FAILED;
-                return result;
-            }
-            result.effects.reservationBound = true;
-
-            result.effects.submitInvoked = true;
-            const auto SUBMISSION        = submitAtomicRequest(
-                drmFD, BUILT.prepared->request(), TILED_ATOMIC_FRAME_FLAGS, transactionId,
-                [&preparedOperations = BUILT.prepared->operations()](int fd, drmModeAtomicReqPtr request, uint32_t flags, void* userData) noexcept {
-                    return preparedOperations->submit(fd, request, flags, userData);
-                },
-                [&result, &runtime, &registry, &reserved = RESERVED.reservation](int returnCode) noexcept {
-                    if (returnCode != 0)
-                        return;
-                    result.effects.kmsAccepted     = true;
-                    result.effects.runtimeAccept   = runtime.accept();
-                    result.effects.runtimeAccepted = result.effects.runtimeAccept.accepted;
-                    if (result.effects.runtimeAccepted)
-                        result.effects.registryAccepted = registry.accept(reserved);
-                });
-            result.submission = SUBMISSION;
-
-            if (!SUBMISSION) {
-                ROLLBACK_RUNTIME();
-                ROLLBACK_REGISTRY();
-                result.status = eTiledFrameTransactionStatus::SUBMISSION_FAILED;
-                return result;
-            }
-            result.status = result.effects.runtimeAccepted && result.effects.registryAccepted ? eTiledFrameTransactionStatus::ACCEPTED :
-                                                                                                eTiledFrameTransactionStatus::ACCEPTED_INVARIANT_FAILURE;
+        auto result = NDetail::submitPreparedTiledFrameTransaction(prepared->route(), runtime, registry, std::move(frame), transactionId, deadlineNs, drmFD, prepared->operations(),
+                                                                   prepared->request(), TILED_ATOMIC_INITIAL_FRAME_FLAGS, eTiledRuntimeState::PUBLISHED_DISABLED);
+        if (result.status != eTiledFrameTransactionStatus::ACCEPTED_INVARIANT_FAILURE)
             return result;
-        } catch (...) {
-            ROLLBACK_RUNTIME();
-            ROLLBACK_REGISTRY();
-            result.status = eTiledFrameTransactionStatus::ALLOCATION_FAILED;
-            return result;
-        }
+        if (!result.effects.kmsAccepted || !result.effects.reservation)
+            std::terminate();
+
+        // RESERVED already swallows callbacks. Quiesce the exact runtime first,
+        // then make the retained registry record routable only to that runtime.
+        result.effects.runtimeRecovered = runtime.recoverAcceptedInvariant(*result.effects.reservation);
+        if (!result.effects.runtimeRecovered)
+            std::terminate();
+        result.effects.registryRecovered = registry.recoverAccepted(*result.effects.reservation);
+        if (!result.effects.registryRecovered)
+            std::terminate();
+        result.effects.runtimeAccept.schedulerSubmit = false;
+        return result;
     }
 }
 
diff --git a/src/backend/drm/TiledRuntime.cpp b/src/backend/drm/TiledRuntime.cpp
index a852b08edac286f4157e67c8a96c3fc28456f3ff..1dfafcb6e2d65800403615200604a53b656474b2 100644
--- a/src/backend/drm/TiledRuntime.cpp
+++ b/src/backend/drm/TiledRuntime.cpp
@@ -62,6 +62,23 @@ bool CTiledFlipReservationRegistry::accept(const STiledFlipReservation& reservat
     return true;
 }
 
+bool CTiledFlipReservationRegistry::recoverAccepted(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 && RECORD->second.state != eTiledReservationState::IN_FLIGHT &&
+         RECORD->second.state != eTiledReservationState::QUIESCED))
+        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;
+    }
+
+    RECORD->second.state = eTiledReservationState::QUIESCED;
+    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)
diff --git a/src/backend/drm/TiledRuntime.hpp b/src/backend/drm/TiledRuntime.hpp
index b1211943b81a1e63ecac3c79bb1c017b038db3ea..16cbc69088009e16b47f16d89b053221c4d33f50 100644
--- a/src/backend/drm/TiledRuntime.hpp
+++ b/src/backend/drm/TiledRuntime.hpp
@@ -162,8 +162,12 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
         [[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;
+        // The KMS ioctl has already accepted at this boundary. Unlike
+        // rollback(), this keeps every member slot claimed and makes the token
+        // routable only to the fail-closed grouped recovery path.
+        [[nodiscard]] bool recoverAccepted(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;
@@ -290,10 +294,10 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
 
     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.
+        // Numeric values are never ownership authority. framebufferId may cache
+        // the exact retained DRM FB's ID for diagnostics/state rotation;
+        // bufferId identifies the retained underlying IBuffer so backendRelease
+        // can be deduplicated. The strong owners below remain authoritative.
         uint64_t framebufferId = 0;
         uint64_t bufferId      = 0;
         TOwner   framebufferOwner;
@@ -490,6 +494,10 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
             return m_prepared ? &m_prepared->route : nullptr;
         }
 
+        [[nodiscard]] const STiledFlipReservation* preparedReservation() const noexcept {
+            return m_prepared && m_prepared->reservation ? &*m_prepared->reservation : nullptr;
+        }
+
         [[nodiscard]] bool bindReservation(const STiledFlipReservation& reservation) noexcept {
             if (!m_prepared || m_state == eTiledRuntimeState::PUBLISHED_IN_FLIGHT || m_prepared->reservation)
                 return false;
@@ -518,6 +526,28 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
             return {.accepted = true, .schedulerSubmit = true};
         }
 
+        // Only the successful-ioctl linearization path may call this. It keeps
+        // the prepared route and all frame owners alive, cancels completion,
+        // and prevents an accepted token from ever returning to singular KMS.
+        [[nodiscard]] bool recoverAcceptedInvariant(const STiledFlipReservation& reservation) noexcept {
+            if (!m_prepared || !m_prepared->reservation || *m_prepared->reservation != reservation ||
+                (m_state != eTiledRuntimeState::PUBLISHED_DISABLED && m_state != eTiledRuntimeState::PUBLISHED_IDLE && m_state != eTiledRuntimeState::PUBLISHED_IN_FLIGHT &&
+                 m_state != eTiledRuntimeState::QUIESCED))
+                return false;
+
+            // accept() may have been the invariant failure. Mirror the
+            // kernel-accepted scanout before quiescing even in that case.
+            for (auto& MEMBER : m_members) {
+                MEMBER.backFramebuffer = m_prepared->frame.framebufferId;
+                MEMBER.backBuffer      = m_prepared->frame.bufferId;
+            }
+            static_cast<void>(m_prepared->barrier.cancel());
+            m_state          = eTiledRuntimeState::QUIESCED;
+            m_quiesceReason  = eTiledQuiesceReason::EVENT_INVARIANT;
+            m_restorePending = false;
+            return true;
+        }
+
         // Submit failure is the only valid rollback point. Accepted and
         // quiesced transactions require page-flip completion or retirement
         // proof instead.
diff --git a/tests/TiledAtomic.cpp b/tests/TiledAtomic.cpp
index 63858f638d7d89ba14e3527f16fd8b67fc0a8d8b..82a3547fa16477084df6936a42db139aef838435 100644
--- a/tests/TiledAtomic.cpp
+++ b/tests/TiledAtomic.cpp
@@ -488,7 +488,7 @@ namespace {
         return frames;
     }
 
-    struct SFrameRecorder final : ITiledAtomicFrameOperations {
+    struct SFrameRecorder final : ITiledAtomicRequestOperations {
         drmModeAtomicReqPtr allocateRequest() noexcept override {
             ++allocations;
             // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): opaque fake request identity for the injected test boundary
@@ -521,13 +521,47 @@ namespace {
                 transactionCountDuringSubmit = registry->transactionCount();
                 routeDuringSubmit            = registry->routeEvent(submittedToken, observedCrtcId);
             }
+            if (acceptRuntimeDuringSubmit && runtime)
+                runtimeAcceptDuringSubmit = runtime->accept();
+            if (acceptRegistryDuringSubmit && runtime && registry) {
+                const auto* RESERVATION      = runtime->preparedReservation();
+                registryAcceptedDuringSubmit = RESERVATION && registry->accept(*RESERVATION);
+            }
             return submitResult;
         }
 
+        int createModeBlob(int, const drmModeModeInfo& mode, uint32_t* blobId) noexcept override {
+            if (!blobId)
+                return -1;
+            *blobId = nextBlob++;
+            try {
+                createdBlobs.push_back(*blobId);
+                physicalModes.push_back(mode);
+                return 0;
+            } catch (...) { return -1; }
+        }
+
+        int destroyModeBlob(int, uint32_t blobId) noexcept override {
+            try {
+                destructionAttempts.push_back(blobId);
+                if (destroyFailuresRemaining != 0) {
+                    --destroyFailuresRemaining;
+                    return -EBUSY;
+                }
+                destroyedBlobs.push_back(blobId);
+                return 0;
+            } catch (...) { return -1; }
+        }
+
         SFrameRuntime*                 runtime                      = nullptr;
         CTiledFlipReservationRegistry* registry                     = nullptr;
         uint32_t                       observedCrtcId               = 0;
         int                            submitResult                 = 0;
+        uint32_t                       nextBlob                     = 1'200;
+        size_t                         destroyFailuresRemaining     = 0;
+        bool                           acceptRuntimeDuringSubmit    = false;
+        bool                           acceptRegistryDuringSubmit   = false;
+        bool                           registryAcceptedDuringSubmit = false;
         size_t                         allocations                  = 0;
         size_t                         frees                        = 0;
         size_t                         submits                      = 0;
@@ -538,7 +572,12 @@ namespace {
         eTiledRuntimeState             runtimeStateDuringSubmit     = eTiledRuntimeState::STAGED;
         eTiledRouteEventResult         routeDuringSubmit            = eTiledRouteEventResult::NOT_OWNED;
         size_t                         transactionCountDuringSubmit = 0;
+        STiledRuntimeAcceptEffects     runtimeAcceptDuringSubmit;
         std::vector<SPropertyWrite>    properties;
+        std::vector<uint32_t>          createdBlobs;
+        std::vector<uint32_t>          destructionAttempts;
+        std::vector<uint32_t>          destroyedBlobs;
+        std::vector<drmModeModeInfo>   physicalModes;
     };
 
     void appendFrameExpected(std::vector<SPropertyWrite>& expected, const STiledAtomicMember& member, uint32_t framebufferId) {
@@ -681,8 +720,7 @@ int main() {
     auto built = buildTiledTestModeset(resolved.route, 19, operations, cleanupRegistry);
     CHECK(static_cast<bool>(built));
     CHECK(built.prepared->request() != nullptr);
-    CHECK(built.prepared->flags() == TILED_ATOMIC_TEST_MODESET_FLAGS);
-    CHECK(built.prepared->userData() == 0);
+    CHECK(sameOwner(built.prepared->operations(), operations));
     CHECK(std::ranges::equal(built.prepared->modeBlobs(), recorder->createdBlobs));
     CHECK(recorder->physicalModes.size() == resolved.route->members().size());
 
@@ -812,6 +850,194 @@ int main() {
         CHECK(retainedCleanup->pendingCount() == 0);
     }
 
+    // Initial 1/5: one full grouped modeset starts from PUBLISHED_DISABLED,
+    // remains RESERVED during the ioctl, then atomically becomes routable.
+    {
+        SFrameRuntime runtime(resolved.route->runtimePlan<PFrameOwner>());
+        CHECK(runtime.publishDisabled());
+        CTiledFlipReservationRegistry                 registry;
+        auto                                          initialRecorder   = makeShared<SFrameRecorder>();
+        auto                                          initialCleanup    = CTiledModeBlobCleanupRegistry::create(31);
+        CSharedPointer<ITiledAtomicRequestOperations> initialOperations = initialRecorder;
+        const auto                                    initialBuilt      = buildTiledModesetRequest(resolved.route, 31, initialOperations, initialCleanup);
+        CHECK(static_cast<bool>(initialBuilt));
+
+        initialRecorder->runtime        = &runtime;
+        initialRecorder->registry       = &registry;
+        initialRecorder->observedCrtcId = resolved.route->crtcIds().front();
+        const auto transaction          = submitInitialTiledFrameTransaction(
+            initialBuilt.prepared, runtime, registry, runtimeFrame(resolved.route->framebuffer().id, 1'201, frameOwner(1'200), frameOwner(1'201)), 6'001, 100'000, 31);
+        CHECK(static_cast<bool>(transaction));
+        CHECK(transaction.status == eTiledFrameTransactionStatus::ACCEPTED);
+        CHECK(initialRecorder->submittedFlags == TILED_ATOMIC_INITIAL_FRAME_FLAGS);
+        CHECK(initialRecorder->submittedToken == 6'001);
+        CHECK(initialRecorder->runtimeStateDuringSubmit == eTiledRuntimeState::PUBLISHED_DISABLED);
+        CHECK(initialRecorder->routeDuringSubmit == eTiledRouteEventResult::RESERVED);
+        CHECK(runtime.state() == eTiledRuntimeState::PUBLISHED_IN_FLIGHT);
+        CHECK(transaction.effects.reservation.has_value());
+        CHECK(registry.state(transaction.effects.reservation.value_or(STiledFlipReservation{})) == eTiledReservationState::IN_FLIGHT);
+
+        std::vector<SPropertyWrite> expectedInitial;
+        for (size_t index = 0; index < resolved.route->members().size(); ++index)
+            appendExpected(expectedInitial, resolved.route->members().subspan(index, 1).front(), resolved.route->framebuffer().id, initialRecorder->createdBlobs.at(index));
+        CHECK(initialRecorder->properties == expectedInitial);
+        const auto cleanup = initialBuilt.prepared->cleanup();
+        CHECK(cleanup.complete());
+        CHECK(cleanup.destroyed == resolved.route->members().size());
+        CHECK(teardown(runtime, registry));
+    }
+
+    // Initial 2/5: a singular pending flip prevents reserve/submit, and a later
+    // rejected ioctl rolls back both prepared ownership and all member slots.
+    {
+        SFrameRuntime runtime(resolved.route->runtimePlan<PFrameOwner>());
+        CHECK(runtime.publishDisabled());
+        CTiledFlipReservationRegistry                 registry;
+
+        auto                                          blockedRecorder   = makeShared<SFrameRecorder>();
+        auto                                          blockedCleanup    = CTiledModeBlobCleanupRegistry::create(32);
+        CSharedPointer<ITiledAtomicRequestOperations> blockedOperations = blockedRecorder;
+        const auto                                    blockedBuilt      = buildTiledModesetRequest(resolved.route, 32, blockedOperations, blockedCleanup);
+        CHECK(static_cast<bool>(blockedBuilt));
+        auto& PENDING      = resolved.route->members().front().crtc->pendingFlip.id;
+        PENDING            = 77;
+        const auto blocked = submitInitialTiledFrameTransaction(blockedBuilt.prepared, runtime, registry,
+                                                                runtimeFrame(resolved.route->framebuffer().id, 1'301, frameOwner(1'300), frameOwner(1'301)), 6'002, 110'000, 32);
+        PENDING.reset();
+        CHECK(blocked.status == eTiledFrameTransactionStatus::MEMBER_PENDING_FLIP);
+        CHECK(blockedRecorder->submits == 0);
+        CHECK(runtime.state() == eTiledRuntimeState::PUBLISHED_DISABLED);
+        CHECK(registry.transactionCount() == 0);
+        CHECK(blockedBuilt.prepared->cleanup().complete());
+
+        auto failedRecorder                                            = makeShared<SFrameRecorder>();
+        auto failedCleanup                                             = CTiledModeBlobCleanupRegistry::create(33);
+        failedRecorder->submitResult                                   = -EBUSY;
+        CSharedPointer<ITiledAtomicRequestOperations> failedOperations = failedRecorder;
+        const auto                                    failedBuilt      = buildTiledModesetRequest(resolved.route, 33, failedOperations, failedCleanup);
+        CHECK(static_cast<bool>(failedBuilt));
+        const auto failed = submitInitialTiledFrameTransaction(failedBuilt.prepared, runtime, registry,
+                                                               runtimeFrame(resolved.route->framebuffer().id, 1'302, frameOwner(1'302), frameOwner(1'303)), 6'003, 120'000, 33);
+        CHECK(failed.status == eTiledFrameTransactionStatus::SUBMISSION_FAILED);
+        CHECK(failed.effects.runtimeRolledBack);
+        CHECK(failed.effects.registryRolledBack);
+        CHECK(runtime.state() == eTiledRuntimeState::PUBLISHED_DISABLED);
+        CHECK(registry.transactionCount() == 0);
+        CHECK(failedBuilt.prepared->cleanup().complete());
+        CHECK(teardown(runtime, registry));
+    }
+
+    // Initial 3/5: an injected runtime-accept failure after KMS acceptance is
+    // recovered runtime-first, retains accepted back state, and leaves a late
+    // event tombstoned after proven retirement.
+    {
+        SFrameRuntime runtime(resolved.route->runtimePlan<PFrameOwner>());
+        CHECK(runtime.publishDisabled());
+        CTiledFlipReservationRegistry                 registry;
+        auto                                          recoveryRecorder   = makeShared<SFrameRecorder>();
+        auto                                          recoveryCleanup    = CTiledModeBlobCleanupRegistry::create(34);
+        CSharedPointer<ITiledAtomicRequestOperations> recoveryOperations = recoveryRecorder;
+        const auto                                    recoveryBuilt      = buildTiledModesetRequest(resolved.route, 34, recoveryOperations, recoveryCleanup);
+        CHECK(static_cast<bool>(recoveryBuilt));
+        recoveryRecorder->runtime                   = &runtime;
+        recoveryRecorder->registry                  = &registry;
+        recoveryRecorder->observedCrtcId            = resolved.route->crtcIds().front();
+        recoveryRecorder->acceptRuntimeDuringSubmit = true;
+        const auto acceptedBuffer                   = frameOwner(1'401);
+        const auto recovered = submitInitialTiledFrameTransaction(recoveryBuilt.prepared, runtime, registry,
+                                                                  runtimeFrame(resolved.route->framebuffer().id, 1'401, frameOwner(1'400), acceptedBuffer), 6'004, 130'000, 34);
+        CHECK(recovered.status == eTiledFrameTransactionStatus::ACCEPTED_INVARIANT_FAILURE);
+        CHECK(recovered.effects.kmsAccepted);
+        CHECK(recovered.effects.runtimeRecovered);
+        CHECK(recovered.effects.registryRecovered);
+        CHECK(!recovered.effects.runtimeAccept.schedulerSubmit);
+        CHECK(recoveryRecorder->runtimeAcceptDuringSubmit.accepted);
+        CHECK(runtime.state() == eTiledRuntimeState::QUIESCED);
+        CHECK(runtime.quiesceReason() == eTiledQuiesceReason::EVENT_INVARIANT);
+        CHECK(std::ranges::all_of(runtime.members(), [&](const auto& member) { return member.backFramebuffer == resolved.route->framebuffer().id && member.backBuffer == 1'401; }));
+        const auto reservation = recovered.effects.reservation.value_or(STiledFlipReservation{});
+        CHECK(registry.state(reservation) == eTiledReservationState::QUIESCED);
+        CHECK(registry.routeEvent(6'004, resolved.route->crtcIds().front()) == eTiledRouteEventResult::ROUTABLE);
+        CHECK(runtime.record(6'004, resolved.route->crtcIds().front(), 1, 1).disposition == eTiledEventDisposition::QUIESCED);
+        auto retired = runtime.retire(eTiledRetirementProof::ATOMIC_DISABLE_COMPLETED);
+        CHECK(retired.retired);
+        CHECK(retired.retireReservation);
+        CHECK(retired.releases.size() == 1);
+        CHECK(retired.releases.front().bufferId == 1'401);
+        CHECK(retired.releases.front().owner == acceptedBuffer);
+        CHECK(registry.retire(reservation));
+        CHECK(registry.routeEvent(6'004, resolved.route->crtcIds().front()) == eTiledRouteEventResult::STALE_TOKEN);
+        retired.releases.clear();
+        CHECK(recoveryBuilt.prepared->cleanup().complete());
+        CHECK(teardown(runtime, registry));
+    }
+
+    // Initial 4/5: an injected registry-accept failure recovers an already
+    // accepted runtime without a second scheduler submission; both recovery
+    // operations are idempotent on the exact reservation.
+    {
+        SFrameRuntime runtime(resolved.route->runtimePlan<PFrameOwner>());
+        CHECK(runtime.publishDisabled());
+        CTiledFlipReservationRegistry                 registry;
+        auto                                          recoveryRecorder   = makeShared<SFrameRecorder>();
+        auto                                          recoveryCleanup    = CTiledModeBlobCleanupRegistry::create(35);
+        CSharedPointer<ITiledAtomicRequestOperations> recoveryOperations = recoveryRecorder;
+        const auto                                    recoveryBuilt      = buildTiledModesetRequest(resolved.route, 35, recoveryOperations, recoveryCleanup);
+        CHECK(static_cast<bool>(recoveryBuilt));
+        recoveryRecorder->runtime                    = &runtime;
+        recoveryRecorder->registry                   = &registry;
+        recoveryRecorder->observedCrtcId             = resolved.route->crtcIds().front();
+        recoveryRecorder->acceptRegistryDuringSubmit = true;
+        const auto recovered = submitInitialTiledFrameTransaction(recoveryBuilt.prepared, runtime, registry,
+                                                                  runtimeFrame(resolved.route->framebuffer().id, 1'501, frameOwner(1'500), frameOwner(1'501)), 6'005, 140'000, 35);
+        CHECK(recoveryRecorder->registryAcceptedDuringSubmit);
+        CHECK(recovered.status == eTiledFrameTransactionStatus::ACCEPTED_INVARIANT_FAILURE);
+        CHECK(recovered.effects.runtimeAccepted);
+        CHECK(!recovered.effects.registryAccepted);
+        CHECK(recovered.effects.runtimeRecovered);
+        CHECK(recovered.effects.registryRecovered);
+        CHECK(!recovered.effects.runtimeAccept.schedulerSubmit);
+        const auto reservation = recovered.effects.reservation.value_or(STiledFlipReservation{});
+        CHECK(runtime.state() == eTiledRuntimeState::QUIESCED);
+        CHECK(registry.state(reservation) == eTiledReservationState::QUIESCED);
+        CHECK(runtime.recoverAcceptedInvariant(reservation));
+        CHECK(registry.recoverAccepted(reservation));
+        CHECK(recoveryBuilt.prepared->cleanup().complete());
+        CHECK(teardown(runtime, registry));
+    }
+
+    // Initial 5/5: an exact route/runtime mismatch is inert, while a failed
+    // blob destroy remains owned by the fd registry and succeeds on retry.
+    {
+        auto foreignPlan = resolved.route->runtimePlan<PFrameOwner>();
+        ++foreignPlan.generation;
+        SFrameRuntime runtime(std::move(foreignPlan));
+        CHECK(runtime.publishDisabled());
+        CTiledFlipReservationRegistry registry;
+        auto                          debtRecorder                   = makeShared<SFrameRecorder>();
+        auto                          debtCleanup                    = CTiledModeBlobCleanupRegistry::create(36);
+        debtRecorder->destroyFailuresRemaining                       = 1;
+        CSharedPointer<ITiledAtomicRequestOperations> debtOperations = debtRecorder;
+        const auto                                    debtBuilt      = buildTiledModesetRequest(resolved.route, 36, debtOperations, debtCleanup);
+        CHECK(static_cast<bool>(debtBuilt));
+        const auto rejected = submitInitialTiledFrameTransaction(debtBuilt.prepared, runtime, registry,
+                                                                 runtimeFrame(resolved.route->framebuffer().id, 1'601, frameOwner(1'600), frameOwner(1'601)), 6'006, 150'000, 36);
+        CHECK(rejected.status == eTiledFrameTransactionStatus::ROUTE_RUNTIME_MISMATCH);
+        CHECK(debtRecorder->submits == 0);
+        const auto debt = debtBuilt.prepared->cleanup();
+        CHECK(debt.retained == 1);
+        CHECK(debtCleanup->pendingCount() == 1);
+        const auto retried = debtCleanup->retryPending();
+        CHECK(retried.complete());
+        CHECK(retried.destroyed == 1);
+        CHECK(debtCleanup->pendingCount() == 0);
+        CHECK(teardown(runtime, registry));
+    }
+
+    static_assert(
+        noexcept(submitInitialTiledFrameTransaction(std::declval<const PPreparedTiledModesetRequest&>(), std::declval<SFrameRuntime&>(),
+                                                    std::declval<CTiledFlipReservationRegistry&>(), std::declval<SFrameRuntime::SFrame>(), uintptr_t{1}, uint64_t{1}, 1)));
+
     static_assert(noexcept(submitTiledFrameTransaction(std::declval<const PResolvedTiledAtomicRoute&>(), std::declval<SFrameRuntime&>(),
                                                        std::declval<CTiledFlipReservationRegistry&>(), std::declval<SFrameRuntime::SFrame>(), uintptr_t{1}, uint64_t{1}, 1,
                                                        std::declval<const CSharedPointer<ITiledAtomicFrameOperations>&>())));