Subject: [PATCH 18/21] wip: prepare transactional tiled KMS replacement

From: Justin Youens <[email-masked]>
Date: Sat, 15 Aug 2026 13:50:14 -0500

---
 src/backend/drm/TiledAtomic.cpp           | 635 +++++++++++++++++++---
 src/backend/drm/TiledAtomic.hpp           | 253 ++++++++-
 src/backend/drm/TiledDRMIntegration.cpp   |  47 +-
 src/backend/drm/TiledDRMIntegration.hpp   | 120 ++--
 src/backend/drm/TiledRuntime.hpp          |  26 +-
 src/backend/drm/TiledRuntimeAuthority.cpp | 160 +++---
 src/backend/drm/TiledRuntimeAuthority.hpp |  92 ++--
 tests/TiledAtomic.cpp                     | 360 +++++++++++-
 tests/TiledDRMIntegration.cpp             | 136 ++++-
 tests/TiledRuntime.cpp                    |  16 +
 10 files changed, 1553 insertions(+), 292 deletions(-)

diff --git a/src/backend/drm/TiledAtomic.cpp b/src/backend/drm/TiledAtomic.cpp
index 413e559587a63594875fc4206d435375404e6ac5..66ea87abc70a61831af688bf0e13856bcf117f4c 100644
--- a/src/backend/drm/TiledAtomic.cpp
+++ b/src/backend/drm/TiledAtomic.cpp
@@ -2,8 +2,12 @@
 
 #include <algorithm>
 #include <array>
+#include <cmath>
 #include <exception>
+#include <limits>
+#include <map>
 #include <ranges>
+#include <set>
 #include <tuple>
 #include <utility>
 
@@ -104,28 +108,81 @@ namespace {
         return operations->addProperty(request, objectId, propertyId, value) >= 0;
     }
 
-    [[nodiscard]] bool addMember(const CSharedPointer<ITiledAtomicRequestOperations>& operations, drmModeAtomicReqPtr request, const STiledAtomicMember& member,
-                                 uint32_t framebufferId, uint32_t modeBlobId) noexcept {
+    class CPropertyGraphBuilder {
+      public:
+        [[nodiscard]] bool fixed(uint32_t objectId, uint32_t propertyId, uint64_t value) {
+            return add({.objectId = objectId, .propertyId = propertyId, .source = eTiledAtomicPropertyValueSource::FIXED, .value = value});
+        }
+
+        [[nodiscard]] bool modeBlob(uint32_t objectId, uint32_t propertyId, size_t memberIndex) {
+            return add({.objectId = objectId, .propertyId = propertyId, .source = eTiledAtomicPropertyValueSource::MODE_BLOB, .memberIndex = memberIndex});
+        }
+
+        [[nodiscard]] std::vector<STiledAtomicPropertyWrite> take() {
+            std::ranges::sort(m_writes, [](const auto& lhs, const auto& rhs) {
+                return std::tie(lhs.objectId, lhs.propertyId, lhs.source, lhs.memberIndex, lhs.value) <
+                    std::tie(rhs.objectId, rhs.propertyId, rhs.source, rhs.memberIndex, rhs.value);
+            });
+            return std::move(m_writes);
+        }
+
+      private:
+        [[nodiscard]] bool add(STiledAtomicPropertyWrite write) {
+            if (write.objectId == 0 || write.propertyId == 0)
+                return false;
+            const auto EXISTING =
+                std::ranges::find_if(m_writes, [&](const auto& candidate) { return candidate.objectId == write.objectId && candidate.propertyId == write.propertyId; });
+            if (EXISTING == m_writes.end()) {
+                m_writes.push_back(write);
+                return true;
+            }
+            return *EXISTING == write;
+        }
+
+        std::vector<STiledAtomicPropertyWrite> m_writes;
+    };
+
+    [[nodiscard]] bool addDesiredMember(CPropertyGraphBuilder& graph, const STiledAtomicMember& member, size_t memberIndex, uint32_t framebufferId) {
         const auto& CONNECTOR = member.connectorProperties;
         const auto& CRTC      = member.crtcProperties;
         const auto& PLANE     = member.planeProperties;
         const auto& VIEWPORT  = member.viewport;
 
-        if (!addProperty(operations, request, member.connectorId, CONNECTOR.crtcId, member.crtcId))
-            return false;
-        if (CONNECTOR.linkStatus != 0 && !addProperty(operations, request, member.connectorId, CONNECTOR.linkStatus, DRM_MODE_LINK_STATUS_GOOD))
-            return false;
-        return addProperty(operations, request, member.crtcId, CRTC.modeId, modeBlobId) && addProperty(operations, request, member.crtcId, CRTC.active, 1) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.fbId, framebufferId) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.crtcId, member.crtcId) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.srcX, VIEWPORT.srcX) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.srcY, VIEWPORT.srcY) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.srcW, VIEWPORT.srcW) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.srcH, VIEWPORT.srcH) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.crtcX, static_cast<uint64_t>(static_cast<int64_t>(VIEWPORT.crtcX))) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.crtcY, static_cast<uint64_t>(static_cast<int64_t>(VIEWPORT.crtcY))) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.crtcW, VIEWPORT.crtcW) &&
-            addProperty(operations, request, member.primaryPlaneId, PLANE.crtcH, VIEWPORT.crtcH);
+        return graph.fixed(member.connectorId, CONNECTOR.crtcId, member.crtcId) &&
+            (CONNECTOR.linkStatus == 0 || graph.fixed(member.connectorId, CONNECTOR.linkStatus, DRM_MODE_LINK_STATUS_GOOD)) &&
+            graph.modeBlob(member.crtcId, CRTC.modeId, memberIndex) && graph.fixed(member.crtcId, CRTC.active, 1) &&
+            graph.fixed(member.primaryPlaneId, PLANE.fbId, framebufferId) && graph.fixed(member.primaryPlaneId, PLANE.crtcId, member.crtcId) &&
+            graph.fixed(member.primaryPlaneId, PLANE.srcX, VIEWPORT.srcX) && graph.fixed(member.primaryPlaneId, PLANE.srcY, VIEWPORT.srcY) &&
+            graph.fixed(member.primaryPlaneId, PLANE.srcW, VIEWPORT.srcW) && graph.fixed(member.primaryPlaneId, PLANE.srcH, VIEWPORT.srcH) &&
+            graph.fixed(member.primaryPlaneId, PLANE.crtcX, static_cast<uint64_t>(static_cast<int64_t>(VIEWPORT.crtcX))) &&
+            graph.fixed(member.primaryPlaneId, PLANE.crtcY, static_cast<uint64_t>(static_cast<int64_t>(VIEWPORT.crtcY))) &&
+            graph.fixed(member.primaryPlaneId, PLANE.crtcW, VIEWPORT.crtcW) && graph.fixed(member.primaryPlaneId, PLANE.crtcH, VIEWPORT.crtcH);
+    }
+
+    [[nodiscard]] std::optional<std::vector<STiledAtomicPropertyWrite>> targetPropertyGraph(const PResolvedTiledAtomicRoute& route) {
+        if (!route)
+            return std::nullopt;
+        CPropertyGraphBuilder graph;
+        for (size_t index = 0; index < route->members().size(); ++index) {
+            if (!addDesiredMember(graph, route->members().subspan(index, 1).front(), index, route->framebuffer().id))
+                return std::nullopt;
+        }
+        return graph.take();
+    }
+
+    [[nodiscard]] bool emitPropertyGraph(const CSharedPointer<ITiledAtomicRequestOperations>& operations, drmModeAtomicReqPtr request,
+                                         std::span<const STiledAtomicPropertyWrite> graph, std::span<const uint32_t> modeBlobs) noexcept {
+        for (const auto& WRITE : graph) {
+            uint64_t value = WRITE.value;
+            if (WRITE.source == eTiledAtomicPropertyValueSource::MODE_BLOB) {
+                if (WRITE.memberIndex >= modeBlobs.size() || modeBlobs[WRITE.memberIndex] == 0)
+                    return false;
+                value = modeBlobs[WRITE.memberIndex];
+            }
+            if (!addProperty(operations, request, WRITE.objectId, WRITE.propertyId, value))
+                return false;
+        }
+        return true;
     }
 
     void cleanupFrameRequest(const CSharedPointer<ITiledAtomicFrameOperations>& operations, drmModeAtomicReqPtr& request) noexcept {
@@ -221,15 +278,30 @@ namespace Aquamarine::NDRM::NTiledAtomic {
     };
 
     struct SRequestAssembler {
-        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)}};
+        static PPreparedTiledModesetRequest create(PResolvedTiledAtomicRoute route, PResolvedTiledAtomicReplacement replacement,
+                                                   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(replacement), std::move(operations), std::move(cleanupRegistry), request, std::move(modeBlobs), std::move(modeBlobOwners)}};
             return prepared;
         }
     };
 
+    struct SReplacementAssembler {
+        static PReplacementPlaneIncarnation planeIncarnation(POutputBridgeObservation generationOwner, CSharedPointer<SDRMPlane> plane, uint64_t serial) {
+            CSharedPointer<CTiledReplacementPlaneIncarnation> incarnation{new CTiledReplacementPlaneIncarnation{std::move(generationOwner), std::move(plane), serial}};
+            return incarnation;
+        }
+
+        static PResolvedTiledAtomicReplacement create(PResolvedTiledAtomicRoute targetRoute, PAtomicFramebufferOwner targetFramebufferOwner, PAtomicPlaneInventory planeInventory,
+                                                      std::vector<STiledReplacementConnector> connectors, std::vector<STiledReplacementCrtc> crtcs,
+                                                      std::vector<STiledAtomicPropertyWrite> propertyGraph) {
+            CSharedPointer<CResolvedTiledAtomicReplacement> replacement{new CResolvedTiledAtomicReplacement{
+                std::move(targetRoute), std::move(targetFramebufferOwner), std::move(planeInventory), std::move(connectors), std::move(crtcs), std::move(propertyGraph)}};
+            return replacement;
+        }
+    };
+
     struct SFrameRequestAssembler {
         static PPreparedTiledFrameRequest create(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicFrameOperations> operations, drmModeAtomicReqPtr request) {
             CSharedPointer<CPreparedTiledFrameRequest> prepared{new CPreparedTiledFrameRequest{std::move(route), std::move(operations), request}};
@@ -531,11 +603,361 @@ STiledAtomicResolveResult Aquamarine::NDRM::NTiledAtomic::resolveCapturedTiledAt
     } catch (...) { return {.error = eTiledAtomicError::ALLOCATION_FAILED}; }
 }
 
-CPreparedTiledModesetRequest::CPreparedTiledModesetRequest(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations,
-                                                           PModeBlobCleanupRegistry cleanupRegistry, drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs,
+CTiledAtomicFramebufferOwner::CTiledAtomicFramebufferOwner(POutputBridgeObservation generationOwner, NTiledIncarnations::PBackendLifetime backend,
+                                                           CSharedPointer<CDRMFB> drmFramebuffer, CSharedPointer<IBuffer> buffer, STiledAtomicFramebuffer framebuffer,
+                                                           bool dead) noexcept :
+    m_generationOwner(std::move(generationOwner)), m_backend(std::move(backend)), m_drmFramebuffer(std::move(drmFramebuffer)), m_buffer(std::move(buffer)),
+    m_framebuffer(framebuffer), m_dead(dead) {}
+
+const POutputBridgeObservation& CTiledAtomicFramebufferOwner::generationOwner() const noexcept {
+    return m_generationOwner;
+}
+
+const NTiledIncarnations::PBackendLifetime& CTiledAtomicFramebufferOwner::backend() const noexcept {
+    return m_backend;
+}
+
+const CSharedPointer<CDRMFB>& CTiledAtomicFramebufferOwner::drmFramebuffer() const noexcept {
+    return m_drmFramebuffer;
+}
+
+const CSharedPointer<IBuffer>& CTiledAtomicFramebufferOwner::buffer() const noexcept {
+    return m_buffer;
+}
+
+const STiledAtomicFramebuffer& CTiledAtomicFramebufferOwner::framebuffer() const noexcept {
+    return m_framebuffer;
+}
+
+bool CTiledAtomicFramebufferOwner::dead() const noexcept {
+    return m_dead;
+}
+
+PAtomicFramebufferOwner CTiledAtomicFramebufferOwner::createCurrent(const POutputBridgeObservation& generationOwner, const CSharedPointer<CDRMFB>& drmFramebuffer) noexcept {
+    try {
+        const auto& SNAPSHOT = generationOwner ? generationOwner->capturedSnapshot() : CSharedPointer<const CSnapshot>{};
+        const auto  BACKEND  = SNAPSHOT && SNAPSHOT->device() ? SNAPSHOT->device()->backend().lock() : NTiledIncarnations::PBackendLifetime{};
+        const auto  BUFFER   = drmFramebuffer ? drmFramebuffer->buffer.lock() : CSharedPointer<IBuffer>{};
+        if (!SNAPSHOT || !BACKEND || BACKEND->binding() != NTiledIncarnations::eBackendBinding::PRODUCTION_BACKEND || !drmFramebuffer || drmFramebuffer->id == 0 ||
+            drmFramebuffer->dead || !BACKEND->matchesResourceBackend(drmFramebuffer->backend) || !BUFFER)
+            return {};
+        const auto ATTRS = BUFFER->dmabuf();
+        if (!ATTRS.success || ATTRS.format == DRM_FORMAT_INVALID || ATTRS.size.x <= 0 || ATTRS.size.y <= 0 ||
+            ATTRS.size.x > static_cast<double>(std::numeric_limits<uint32_t>::max()) || ATTRS.size.y > static_cast<double>(std::numeric_limits<uint32_t>::max()) ||
+            std::trunc(ATTRS.size.x) != ATTRS.size.x || std::trunc(ATTRS.size.y) != ATTRS.size.y)
+            return {};
+        CSharedPointer<CTiledAtomicFramebufferOwner> owner{
+            new CTiledAtomicFramebufferOwner{generationOwner,
+                                             BACKEND,
+                                             drmFramebuffer,
+                                             BUFFER,
+                                             {.id       = drmFramebuffer->id,
+                                              .size     = {.width = static_cast<uint32_t>(ATTRS.size.x), .height = static_cast<uint32_t>(ATTRS.size.y)},
+                                              .format   = ATTRS.format,
+                                              .modifier = ATTRS.modifier},
+                                             false}};
+        return owner;
+    } catch (...) { return {}; }
+}
+
+PAtomicFramebufferOwner CTiledAtomicFramebufferOwner::createFixture(const POutputBridgeObservation& generationOwner, const CSharedPointer<CDRMFB>& drmFramebuffer,
+                                                                    const CSharedPointer<IBuffer>& buffer, STiledAtomicFramebuffer framebuffer, bool dead) noexcept {
+    try {
+        const auto& SNAPSHOT = generationOwner ? generationOwner->capturedSnapshot() : CSharedPointer<const CSnapshot>{};
+        const auto  BACKEND  = SNAPSHOT && SNAPSHOT->device() ? SNAPSHOT->device()->backend().lock() : NTiledIncarnations::PBackendLifetime{};
+        if (!SNAPSHOT || !BACKEND || BACKEND->binding() != NTiledIncarnations::eBackendBinding::TEST_TOKEN || BACKEND->drmBackend().impl_ != nullptr || !drmFramebuffer ||
+            !buffer || framebuffer.id == 0 || framebuffer.size.width == 0 || framebuffer.size.height == 0 || framebuffer.format == DRM_FORMAT_INVALID)
+            return {};
+        CSharedPointer<CTiledAtomicFramebufferOwner> owner{new CTiledAtomicFramebufferOwner{generationOwner, BACKEND, drmFramebuffer, buffer, framebuffer, dead}};
+        return owner;
+    } catch (...) { return {}; }
+}
+
+CTiledReplacementPlaneIncarnation::CTiledReplacementPlaneIncarnation(POutputBridgeObservation generationOwner, CSharedPointer<SDRMPlane> plane, uint64_t serial) noexcept :
+    m_generationOwner(std::move(generationOwner)), m_plane(std::move(plane)), m_serial(serial) {}
+
+const POutputBridgeObservation& CTiledReplacementPlaneIncarnation::generationOwner() const noexcept {
+    return m_generationOwner;
+}
+
+const CSharedPointer<SDRMPlane>& CTiledReplacementPlaneIncarnation::plane() const noexcept {
+    return m_plane;
+}
+
+uint64_t CTiledReplacementPlaneIncarnation::serial() const noexcept {
+    return m_serial;
+}
+
+CTiledAtomicPlaneInventory::CTiledAtomicPlaneInventory(POutputBridgeObservation generationOwner, NTiledIncarnations::PBackendLifetime backend,
+                                                       std::vector<STiledReplacementPlane> planes) noexcept :
+    m_generationOwner(std::move(generationOwner)), m_backend(std::move(backend)), m_planes(std::move(planes)) {}
+
+const POutputBridgeObservation& CTiledAtomicPlaneInventory::generationOwner() const noexcept {
+    return m_generationOwner;
+}
+
+const NTiledIncarnations::PBackendLifetime& CTiledAtomicPlaneInventory::backend() const noexcept {
+    return m_backend;
+}
+
+std::span<const STiledReplacementPlane> CTiledAtomicPlaneInventory::planes() const noexcept {
+    return m_planes;
+}
+
+PAtomicPlaneInventory CTiledAtomicPlaneInventory::create(const POutputBridgeObservation& generationOwner, std::vector<STiledPlaneInventoryResource> resources,
+                                                         std::vector<STiledPlaneInventoryState> states) noexcept {
+    try {
+        const auto& SNAPSHOT = generationOwner ? generationOwner->capturedSnapshot() : CSharedPointer<const CSnapshot>{};
+        const auto  BACKEND  = SNAPSHOT && SNAPSHOT->device() ? SNAPSHOT->device()->backend().lock() : NTiledIncarnations::PBackendLifetime{};
+        if (!SNAPSHOT || !SNAPSHOT->observation() || !BACKEND || resources.empty() || resources.size() != states.size())
+            return {};
+        std::ranges::sort(resources, {}, &STiledPlaneInventoryResource::id);
+        std::ranges::sort(states, {}, &STiledPlaneInventoryState::id);
+
+        std::set<uint32_t>                  resourceIds;
+        std::set<const void*>               resourceOwners;
+        std::vector<STiledReplacementPlane> planes;
+        planes.reserve(resources.size());
+        uint64_t serial = 0;
+        for (size_t index = 0; index < resources.size(); ++index) {
+            const auto& RESOURCE = resources.at(index);
+            const auto& STATE    = states.at(index);
+            if (!RESOURCE.owner || RESOURCE.id == 0 || RESOURCE.owner->id != RESOURCE.id || STATE.id != RESOURCE.id || !sameOwner(STATE.owner, RESOURCE.owner) ||
+                !resourceIds.emplace(RESOURCE.id).second || !resourceOwners.emplace(RESOURCE.owner.impl_).second || !BACKEND->matchesResourceBackend(RESOURCE.owner->backend) ||
+                RESOURCE.owner->props.values.fb_id == 0 || RESOURCE.owner->props.values.crtc_id == 0 || RESOURCE.owner->props.values.fb_id == RESOURCE.owner->props.values.crtc_id)
+                return {};
+
+            uint64_t expectedType = 0;
+            switch (RESOURCE.role) {
+                case eTiledReplacementPlaneRole::PRIMARY: expectedType = DRM_PLANE_TYPE_PRIMARY; break;
+                case eTiledReplacementPlaneRole::CURSOR: expectedType = DRM_PLANE_TYPE_CURSOR; break;
+                case eTiledReplacementPlaneRole::OVERLAY: expectedType = DRM_PLANE_TYPE_OVERLAY; break;
+                default: return {};
+            }
+            if (RESOURCE.owner->type != expectedType)
+                return {};
+
+            const auto PRIMARY = std::ranges::find_if(SNAPSHOT->primaryPlanes(), [&](const auto& candidate) { return sameOwner(candidate.plane, RESOURCE.owner); });
+            CSharedPointer<const SResourceIncarnation> allocatorIncarnation;
+            if (RESOURCE.role == eTiledReplacementPlaneRole::PRIMARY) {
+                if (PRIMARY == SNAPSHOT->primaryPlanes().end() ||
+                    !validIncarnation(PRIMARY->incarnation, eResourceKind::PRIMARY_PLANE, RESOURCE.id, SNAPSHOT->allocationEpoch(), SNAPSHOT->observation()))
+                    return {};
+                allocatorIncarnation = PRIMARY->incarnation;
+            } else if (PRIMARY != SNAPSHOT->primaryPlanes().end())
+                return {};
+
+            if ((STATE.crtcId == 0) != (STATE.framebufferId == 0) || (STATE.framebufferId == 0) != !STATE.framebufferOwner)
+                return {};
+            if (STATE.crtcId != 0) {
+                const auto CRTC = std::ranges::find(SNAPSHOT->crtcs(), STATE.crtcId, [](const auto& candidate) { return candidate.crtc ? candidate.crtc->id : 0; });
+                if (CRTC == SNAPSHOT->crtcs().end() || !STATE.framebufferOwner || STATE.framebufferOwner->dead() ||
+                    !sameOwner(STATE.framebufferOwner->generationOwner(), generationOwner) || !sameOwner(STATE.framebufferOwner->backend(), BACKEND) ||
+                    STATE.framebufferOwner->framebuffer().id != STATE.framebufferId || !STATE.framebufferOwner->drmFramebuffer() || !STATE.framebufferOwner->buffer() ||
+                    (!sameOwner(STATE.framebufferOwner->drmFramebuffer(), RESOURCE.owner->front) && !sameOwner(STATE.framebufferOwner->drmFramebuffer(), RESOURCE.owner->back) &&
+                     !sameOwner(STATE.framebufferOwner->drmFramebuffer(), RESOURCE.owner->last)))
+                    return {};
+            }
+
+            auto incarnation = SReplacementAssembler::planeIncarnation(generationOwner, RESOURCE.owner, ++serial);
+            if (!incarnation)
+                return {};
+            planes.push_back({
+                .owner                = RESOURCE.owner,
+                .incarnation          = std::move(incarnation),
+                .allocatorIncarnation = std::move(allocatorIncarnation),
+                .framebufferOwner     = STATE.framebufferOwner,
+                .id                   = RESOURCE.id,
+                .crtcId               = STATE.crtcId,
+                .framebufferId        = STATE.framebufferId,
+                .fbIdProperty         = RESOURCE.owner->props.values.fb_id,
+                .crtcIdProperty       = RESOURCE.owner->props.values.crtc_id,
+                .role                 = RESOURCE.role,
+            });
+        }
+
+        for (const auto& PRIMARY : SNAPSHOT->primaryPlanes()) {
+            const auto FOUND = std::ranges::find_if(planes, [&](const auto& candidate) {
+                return candidate.role == eTiledReplacementPlaneRole::PRIMARY && sameOwner(candidate.owner, PRIMARY.plane) &&
+                    sameOwner(candidate.allocatorIncarnation, PRIMARY.incarnation);
+            });
+            if (FOUND == planes.end())
+                return {};
+        }
+
+        CSharedPointer<CTiledAtomicPlaneInventory> inventory{new CTiledAtomicPlaneInventory{generationOwner, BACKEND, std::move(planes)}};
+        return inventory;
+    } catch (...) { return {}; }
+}
+
+CResolvedTiledAtomicReplacement::CResolvedTiledAtomicReplacement(PResolvedTiledAtomicRoute targetRoute, PAtomicFramebufferOwner targetFramebufferOwner,
+                                                                 PAtomicPlaneInventory planeInventory, std::vector<STiledReplacementConnector> connectors,
+                                                                 std::vector<STiledReplacementCrtc> crtcs, std::vector<STiledAtomicPropertyWrite> propertyGraph) noexcept :
+    m_targetRoute(std::move(targetRoute)), m_targetFramebufferOwner(std::move(targetFramebufferOwner)), m_planeInventory(std::move(planeInventory)),
+    m_connectors(std::move(connectors)), m_crtcs(std::move(crtcs)), m_propertyGraph(std::move(propertyGraph)) {}
+
+const PResolvedTiledAtomicRoute& CResolvedTiledAtomicReplacement::targetRoute() const noexcept {
+    return m_targetRoute;
+}
+
+const PAtomicFramebufferOwner& CResolvedTiledAtomicReplacement::targetFramebufferOwner() const noexcept {
+    return m_targetFramebufferOwner;
+}
+
+const PAtomicPlaneInventory& CResolvedTiledAtomicReplacement::planeInventory() const noexcept {
+    return m_planeInventory;
+}
+
+std::span<const STiledReplacementConnector> CResolvedTiledAtomicReplacement::connectors() const noexcept {
+    return m_connectors;
+}
+
+std::span<const STiledReplacementCrtc> CResolvedTiledAtomicReplacement::crtcs() const noexcept {
+    return m_crtcs;
+}
+
+std::span<const STiledReplacementPlane> CResolvedTiledAtomicReplacement::planes() const noexcept {
+    return m_planeInventory ? m_planeInventory->planes() : std::span<const STiledReplacementPlane>{};
+}
+
+std::span<const STiledAtomicPropertyWrite> CResolvedTiledAtomicReplacement::propertyGraph() const noexcept {
+    return m_propertyGraph;
+}
+
+STiledAtomicReplacementResolveResult::operator bool() const noexcept {
+    return error == eTiledAtomicError::NONE && replacement;
+}
+
+STiledAtomicReplacementResolveResult Aquamarine::NDRM::NTiledAtomic::resolveTiledAtomicReplacement(STiledAtomicReplacementCapture capture) noexcept {
+    try {
+        const auto& ROUTE      = capture.targetRoute;
+        const auto& GENERATION = ROUTE ? ROUTE->generationOwner() : POutputBridgeObservation{};
+        const auto& SNAPSHOT   = GENERATION ? GENERATION->capturedSnapshot() : CSharedPointer<const CSnapshot>{};
+        const auto  LIFETIME   = SNAPSHOT && SNAPSHOT->device() ? SNAPSHOT->device()->backend().lock() : NTiledIncarnations::PBackendLifetime{};
+        if (!ROUTE || !GENERATION || !SNAPSHOT || !SNAPSHOT->observation() || !LIFETIME || ROUTE->generation() != SNAPSHOT->allocationEpoch() || !capture.targetFramebufferOwner ||
+            !capture.planeInventory || !sameOwner(capture.targetFramebufferOwner->generationOwner(), GENERATION) ||
+            !sameOwner(capture.targetFramebufferOwner->backend(), LIFETIME) || capture.targetFramebufferOwner->dead() ||
+            capture.targetFramebufferOwner->framebuffer() != ROUTE->framebuffer() || !capture.targetFramebufferOwner->drmFramebuffer() ||
+            !capture.targetFramebufferOwner->buffer() || !sameOwner(capture.planeInventory->generationOwner(), GENERATION) ||
+            !sameOwner(capture.planeInventory->backend(), LIFETIME) || capture.connectors.size() != SNAPSHOT->connectors().size() ||
+            capture.crtcs.size() != SNAPSHOT->crtcs().size())
+            return {.error = eTiledAtomicError::INCOMPLETE_REPLACEMENT};
+
+        std::vector<STiledReplacementConnector> connectors;
+        std::vector<STiledReplacementCrtc>      crtcs;
+        std::set<const void*>                   connectorOwners;
+        std::set<const void*>                   crtcOwners;
+        std::map<uint32_t, uint8_t>             objectKinds;
+        connectors.reserve(capture.connectors.size());
+        crtcs.reserve(capture.crtcs.size());
+
+        for (const auto& CRTC_CAPTURE : capture.crtcs) {
+            const auto& CRTC = CRTC_CAPTURE.crtc;
+            if (!CRTC || CRTC->id == 0 || CRTC->props.values.mode_id == 0 || CRTC->props.values.active == 0 || CRTC->props.values.mode_id == CRTC->props.values.active ||
+                !LIFETIME->matchesResourceBackend(CRTC->backend) || !crtcOwners.emplace(CRTC.impl_).second || !objectKinds.emplace(CRTC->id, 1).second)
+                return {.error = eTiledAtomicError::FOREIGN_RESOURCE};
+            const auto RESOURCE = std::ranges::find_if(SNAPSHOT->crtcs(), [&](const auto& candidate) { return sameOwner(candidate.crtc, CRTC); });
+            if (RESOURCE == SNAPSHOT->crtcs().end() || !validIncarnation(RESOURCE->incarnation, eResourceKind::CRTC, CRTC->id, ROUTE->generation(), SNAPSHOT->observation()))
+                return {.error = eTiledAtomicError::FOREIGN_RESOURCE};
+            crtcs.push_back(
+                {.owner = CRTC, .incarnation = RESOURCE->incarnation, .id = CRTC->id, .modeIdProperty = CRTC->props.values.mode_id, .activeProperty = CRTC->props.values.active});
+        }
+        std::ranges::sort(crtcs, {}, &STiledReplacementCrtc::id);
+
+        for (const auto& CONNECTOR_CAPTURE : capture.connectors) {
+            const auto& CONNECTOR = CONNECTOR_CAPTURE.connector;
+            if (!CONNECTOR || CONNECTOR->id == 0 || CONNECTOR->props.values.crtc_id == 0 || !LIFETIME->matchesResourceBackend(CONNECTOR->backend) ||
+                !connectorOwners.emplace(CONNECTOR.impl_).second || !objectKinds.emplace(CONNECTOR->id, 0).second)
+                return {.error = eTiledAtomicError::FOREIGN_RESOURCE};
+            const auto RESOURCE = std::ranges::find_if(SNAPSHOT->connectors(), [&](const auto& candidate) { return sameOwner(candidate.connector, CONNECTOR); });
+            if (RESOURCE == SNAPSHOT->connectors().end() ||
+                !validIncarnation(RESOURCE->incarnation, eResourceKind::CONNECTOR, CONNECTOR->id, ROUTE->generation(), SNAPSHOT->observation()))
+                return {.error = eTiledAtomicError::FOREIGN_RESOURCE};
+            uint32_t attachedCrtcId = 0;
+            if (CONNECTOR_CAPTURE.attachedCrtc) {
+                const auto CRTC = std::ranges::find_if(crtcs, [&](const auto& candidate) { return sameOwner(candidate.owner, CONNECTOR_CAPTURE.attachedCrtc); });
+                if (CRTC == crtcs.end() || CONNECTOR_CAPTURE.attachedCrtc->id != CRTC->id)
+                    return {.error = eTiledAtomicError::UNKNOWN_ATTACHMENT};
+                attachedCrtcId = CRTC->id;
+            }
+            connectors.push_back({.owner          = CONNECTOR,
+                                  .incarnation    = RESOURCE->incarnation,
+                                  .attachedCrtc   = CONNECTOR_CAPTURE.attachedCrtc,
+                                  .id             = CONNECTOR->id,
+                                  .attachedCrtcId = attachedCrtcId,
+                                  .crtcIdProperty = CONNECTOR->props.values.crtc_id});
+        }
+        std::ranges::sort(connectors, {}, &STiledReplacementConnector::id);
+
+        for (const auto& PLANE : capture.planeInventory->planes()) {
+            if (!PLANE.owner || PLANE.id == 0 || !PLANE.incarnation || !sameOwner(PLANE.incarnation->generationOwner(), GENERATION) ||
+                !sameOwner(PLANE.incarnation->plane(), PLANE.owner) || !objectKinds.emplace(PLANE.id, 2).second)
+                return {.error = eTiledAtomicError::FOREIGN_RESOURCE};
+        }
+
+        std::map<const void*, uint32_t> targetConnectors;
+        std::map<const void*, uint32_t> targetPlanes;
+        std::set<uint32_t>              targetCrtcs;
+        std::set<uint32_t>              displacedCrtcs;
+        for (const auto& MEMBER : ROUTE->members()) {
+            const auto CONNECTOR = std::ranges::find_if(connectors, [&](const auto& candidate) { return sameOwner(candidate.owner, MEMBER.connector); });
+            const auto CRTC      = std::ranges::find_if(crtcs, [&](const auto& candidate) { return sameOwner(candidate.owner, MEMBER.crtc); });
+            const auto PRIMARY   = std::ranges::find_if(capture.planeInventory->planes(), [&](const auto& candidate) { return sameOwner(candidate.owner, MEMBER.primaryPlane); });
+            if (CONNECTOR == connectors.end() || CRTC == crtcs.end() || PRIMARY == capture.planeInventory->planes().end() || PRIMARY->role != eTiledReplacementPlaneRole::PRIMARY ||
+                CONNECTOR->id != MEMBER.connectorId || CRTC->id != MEMBER.crtcId || PRIMARY->id != MEMBER.primaryPlaneId ||
+                !sameOwner(CONNECTOR->incarnation, MEMBER.connectorIncarnation) || !sameOwner(CRTC->incarnation, MEMBER.crtcIncarnation) ||
+                !sameOwner(PRIMARY->allocatorIncarnation, MEMBER.primaryPlaneIncarnation))
+                return {.error = eTiledAtomicError::FOREIGN_RESOURCE};
+            if (!targetConnectors.emplace(MEMBER.connector.impl_, MEMBER.crtcId).second || !targetPlanes.emplace(MEMBER.primaryPlane.impl_, MEMBER.crtcId).second ||
+                !targetCrtcs.emplace(MEMBER.crtcId).second)
+                return {.error = eTiledAtomicError::PROPERTY_CONFLICT};
+            if (CONNECTOR->attachedCrtcId != 0 && CONNECTOR->attachedCrtcId != MEMBER.crtcId)
+                displacedCrtcs.emplace(CONNECTOR->attachedCrtcId);
+        }
+        for (const auto& PLANE : capture.planeInventory->planes()) {
+            const auto TARGET = targetPlanes.find(PLANE.owner.impl_);
+            if (TARGET != targetPlanes.end() && PLANE.crtcId != 0 && PLANE.crtcId != TARGET->second)
+                displacedCrtcs.emplace(PLANE.crtcId);
+        }
+        for (const auto CRTC_ID : targetCrtcs)
+            displacedCrtcs.erase(CRTC_ID);
+
+        std::set<uint32_t> affectedCrtcs = targetCrtcs;
+        affectedCrtcs.insert(displacedCrtcs.begin(), displacedCrtcs.end());
+
+        CPropertyGraphBuilder graph;
+        for (size_t index = 0; index < ROUTE->members().size(); ++index) {
+            if (!addDesiredMember(graph, ROUTE->members().subspan(index, 1).front(), index, ROUTE->framebuffer().id))
+                return {.error = eTiledAtomicError::PROPERTY_CONFLICT};
+        }
+        for (const auto& CONNECTOR : connectors) {
+            if (!targetConnectors.contains(CONNECTOR.owner.impl_) && CONNECTOR.attachedCrtcId != 0 && affectedCrtcs.contains(CONNECTOR.attachedCrtcId) &&
+                !graph.fixed(CONNECTOR.id, CONNECTOR.crtcIdProperty, 0))
+                return {.error = eTiledAtomicError::PROPERTY_CONFLICT};
+        }
+        for (const auto& CRTC : crtcs) {
+            if (displacedCrtcs.contains(CRTC.id) && (!graph.fixed(CRTC.id, CRTC.modeIdProperty, 0) || !graph.fixed(CRTC.id, CRTC.activeProperty, 0)))
+                return {.error = eTiledAtomicError::PROPERTY_CONFLICT};
+        }
+        for (const auto& PLANE : capture.planeInventory->planes()) {
+            if (PLANE.crtcId != 0 && !targetPlanes.contains(PLANE.owner.impl_) && affectedCrtcs.contains(PLANE.crtcId) &&
+                (!graph.fixed(PLANE.id, PLANE.fbIdProperty, 0) || !graph.fixed(PLANE.id, PLANE.crtcIdProperty, 0)))
+                return {.error = eTiledAtomicError::PROPERTY_CONFLICT};
+        }
+
+        auto replacement = SReplacementAssembler::create(std::move(capture.targetRoute), std::move(capture.targetFramebufferOwner), std::move(capture.planeInventory),
+                                                         std::move(connectors), std::move(crtcs), graph.take());
+        return replacement ? STiledAtomicReplacementResolveResult{.replacement = std::move(replacement), .error = eTiledAtomicError::NONE} :
+                             STiledAtomicReplacementResolveResult{.error = eTiledAtomicError::ALLOCATION_FAILED};
+    } catch (...) { return {.error = eTiledAtomicError::ALLOCATION_FAILED}; }
+}
+
+CPreparedTiledModesetRequest::CPreparedTiledModesetRequest(PResolvedTiledAtomicRoute route, PResolvedTiledAtomicReplacement replacement,
+                                                           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)) {}
+    m_route(std::move(route)), m_replacement(std::move(replacement)), m_operations(std::move(operations)), m_cleanupRegistry(std::move(cleanupRegistry)), m_request(request),
+    m_modeBlobs(std::move(modeBlobs)), m_modeBlobOwners(std::move(modeBlobOwners)) {}
 
 CPreparedTiledModesetRequest::~CPreparedTiledModesetRequest() noexcept {
     static_cast<void>(cleanup());
@@ -545,6 +967,10 @@ const PResolvedTiledAtomicRoute& CPreparedTiledModesetRequest::route() const noe
     return m_route;
 }
 
+const PResolvedTiledAtomicReplacement& CPreparedTiledModesetRequest::replacement() const noexcept {
+    return m_replacement;
+}
+
 drmModeAtomicReqPtr CPreparedTiledModesetRequest::request() const noexcept {
     return m_request;
 }
@@ -571,63 +997,81 @@ STiledAtomicBuildResult::operator bool() const noexcept {
     return error == eTiledAtomicError::NONE && prepared;
 }
 
+namespace {
+    STiledAtomicBuildResult buildTiledModesetGraph(const PResolvedTiledAtomicRoute& route, const PResolvedTiledAtomicReplacement& replacement,
+                                                   std::span<const STiledAtomicPropertyWrite> graph, 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)
+            return {.error = eTiledAtomicError::INVALID_OPERATIONS};
+
+        SBuildResources resources{.operations = operations, .cleanupRegistry = cleanupRegistry};
+        const auto      fail = [&](eTiledAtomicError error) {
+            const auto CLEANUP = resources.cleanup();
+            return STiledAtomicBuildResult{
+                .error           = error,
+                .cleanup         = CLEANUP,
+                .retainedCleanup = CLEANUP.retained == 0 ? PModeBlobCleanupRegistry{} : cleanupRegistry,
+            };
+        };
+
+        try {
+            resources.request = operations->allocateRequest();
+            if (!resources.request)
+                return fail(eTiledAtomicError::REQUEST_ALLOCATION_FAILED);
+            resources.modeBlobs.reserve(route->members().size());
+            resources.modeBlobOwners.reserve(route->members().size());
+
+            for (const auto& MEMBER : route->members()) {
+                const auto OWNER = resources.reserveModeBlob();
+                if (!OWNER)
+                    return fail(eTiledAtomicError::ALLOCATION_FAILED);
+                resources.modeBlobOwners.push_back(OWNER);
+
+                uint32_t  blobId = 0;
+                const int result = operations->createModeBlob(drmFD, MEMBER.physicalMode, &blobId);
+                if (blobId != 0) {
+                    // The registry record exists before the create call, so even a
+                    // nonzero ID returned with failure already has a cleanup owner.
+                    if (!resources.claimModeBlob(OWNER, blobId))
+                        return fail(eTiledAtomicError::MODE_BLOB_FAILED);
+                    resources.modeBlobs.push_back(blobId);
+                }
+                if (result != 0 || blobId == 0)
+                    return fail(eTiledAtomicError::MODE_BLOB_FAILED);
+            }
+
+            if (!emitPropertyGraph(operations, resources.request, graph, resources.modeBlobs))
+                return fail(eTiledAtomicError::PROPERTY_ADD_FAILED);
+
+            auto prepared = SRequestAssembler::create(route, replacement, operations, cleanupRegistry, resources.request, resources.modeBlobs, resources.modeBlobOwners);
+            if (!prepared)
+                return fail(eTiledAtomicError::ALLOCATION_FAILED);
+            resources.request = nullptr;
+            resources.modeBlobs.clear();
+            resources.modeBlobOwners.clear();
+            return {.prepared = std::move(prepared), .error = eTiledAtomicError::NONE};
+        } catch (...) { return fail(eTiledAtomicError::ALLOCATION_FAILED); }
+    }
+}
+
 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)
-        return {.error = eTiledAtomicError::INVALID_OPERATIONS};
-
-    SBuildResources resources{.operations = operations, .cleanupRegistry = cleanupRegistry};
-    const auto      fail = [&](eTiledAtomicError error) {
-        const auto CLEANUP = resources.cleanup();
-        return STiledAtomicBuildResult{
-            .error           = error,
-            .cleanup         = CLEANUP,
-            .retainedCleanup = CLEANUP.retained == 0 ? PModeBlobCleanupRegistry{} : cleanupRegistry,
-        };
-    };
-
     try {
-        resources.request = operations->allocateRequest();
-        if (!resources.request)
-            return fail(eTiledAtomicError::REQUEST_ALLOCATION_FAILED);
-        resources.modeBlobs.reserve(route->members().size());
-        resources.modeBlobOwners.reserve(route->members().size());
+        const auto GRAPH = targetPropertyGraph(route);
+        return GRAPH ? buildTiledModesetGraph(route, {}, *GRAPH, drmFD, operations, cleanupRegistry) :
+                       STiledAtomicBuildResult{.error = route ? eTiledAtomicError::PROPERTY_CONFLICT : eTiledAtomicError::INVALID_INPUT};
+    } catch (...) { return {.error = eTiledAtomicError::ALLOCATION_FAILED}; }
+}
 
-        for (const auto& MEMBER : route->members()) {
-            const auto OWNER = resources.reserveModeBlob();
-            if (!OWNER)
-                return fail(eTiledAtomicError::ALLOCATION_FAILED);
-            resources.modeBlobOwners.push_back(OWNER);
-
-            uint32_t  blobId = 0;
-            const int result = operations->createModeBlob(drmFD, MEMBER.physicalMode, &blobId);
-            if (blobId != 0) {
-                // The registry record exists before the create call, so even a
-                // nonzero ID returned with failure already has a cleanup owner.
-                if (!resources.claimModeBlob(OWNER, blobId))
-                    return fail(eTiledAtomicError::MODE_BLOB_FAILED);
-                resources.modeBlobs.push_back(blobId);
-            }
-            if (result != 0 || blobId == 0)
-                return fail(eTiledAtomicError::MODE_BLOB_FAILED);
-        }
-
-        for (size_t index = 0; index < route->members().size(); ++index) {
-            if (!addMember(operations, resources.request, route->members().subspan(index, 1).front(), route->framebuffer().id, resources.modeBlobs.at(index)))
-                return fail(eTiledAtomicError::PROPERTY_ADD_FAILED);
-        }
-
-        auto prepared = SRequestAssembler::create(route, operations, cleanupRegistry, resources.request, resources.modeBlobs, resources.modeBlobOwners);
-        if (!prepared)
-            return fail(eTiledAtomicError::ALLOCATION_FAILED);
-        resources.request = nullptr;
-        resources.modeBlobs.clear();
-        resources.modeBlobOwners.clear();
-        return {.prepared = std::move(prepared), .error = eTiledAtomicError::NONE};
-    } catch (...) { return fail(eTiledAtomicError::ALLOCATION_FAILED); }
+STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledModesetRequest(const PResolvedTiledAtomicReplacement& replacement, int drmFD,
+                                                                                 const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                                 const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept {
+    if (!replacement || !replacement->targetRoute())
+        return {.error = eTiledAtomicError::INVALID_INPUT};
+    return buildTiledModesetGraph(replacement->targetRoute(), replacement, replacement->propertyGraph(), drmFD, operations, cleanupRegistry);
 }
 
 STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledTestModeset(const PResolvedTiledAtomicRoute& route, int drmFD,
@@ -636,6 +1080,12 @@ STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledTestModeset(co
     return buildTiledModesetRequest(route, drmFD, operations, cleanupRegistry);
 }
 
+STiledAtomicBuildResult Aquamarine::NDRM::NTiledAtomic::buildTiledTestModeset(const PResolvedTiledAtomicReplacement& replacement, int drmFD,
+                                                                              const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                              const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept {
+    return buildTiledModesetRequest(replacement, drmFD, operations, cleanupRegistry);
+}
+
 STiledTestModesetExecutionResult::operator bool() const noexcept {
     return status == eTiledTestModesetStatus::SUCCEEDED;
 }
@@ -669,6 +1119,35 @@ STiledTestModesetExecutionResult Aquamarine::NDRM::NTiledAtomic::executeTiledTes
     return execution;
 }
 
+STiledTestModesetExecutionResult Aquamarine::NDRM::NTiledAtomic::executeTiledTestModeset(const PResolvedTiledAtomicReplacement& replacement, int drmFD,
+                                                                                         const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                                         const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept {
+    STiledTestModesetExecutionResult execution;
+    const auto                       BUILT = buildTiledTestModeset(replacement, drmFD, operations, cleanupRegistry);
+    if (!BUILT) {
+        switch (BUILT.error) {
+            case eTiledAtomicError::INVALID_INPUT: execution.status = eTiledTestModesetStatus::INVALID_INPUT; break;
+            case eTiledAtomicError::INVALID_OPERATIONS: execution.status = eTiledTestModesetStatus::INVALID_OPERATIONS; break;
+            case eTiledAtomicError::REQUEST_ALLOCATION_FAILED: execution.status = eTiledTestModesetStatus::REQUEST_ALLOCATION_FAILED; break;
+            case eTiledAtomicError::MODE_BLOB_FAILED: execution.status = eTiledTestModesetStatus::MODE_BLOB_FAILED; break;
+            case eTiledAtomicError::PROPERTY_ADD_FAILED: execution.status = eTiledTestModesetStatus::PROPERTY_ADD_FAILED; break;
+            default: execution.status = eTiledTestModesetStatus::ALLOCATION_FAILED; break;
+        }
+        execution.cleanup         = BUILT.cleanup;
+        execution.retainedCleanup = BUILT.retainedCleanup;
+        return execution;
+    }
+
+    execution.submission = submitAtomicRequest(
+        drmFD, BUILT.prepared->request(), TILED_ATOMIC_TEST_MODESET_FLAGS, 0,
+        [&operations](int fd, drmModeAtomicReqPtr request, uint32_t flags, void* userData) noexcept { return operations->submit(fd, request, flags, userData); });
+    execution.cleanup = BUILT.prepared->cleanup();
+    if (execution.cleanup.retained != 0)
+        execution.retainedCleanup = cleanupRegistry;
+    execution.status = execution.submission && static_cast<bool>(*execution.submission) ? eTiledTestModesetStatus::SUCCEEDED : eTiledTestModesetStatus::SUBMISSION_FAILED;
+    return execution;
+}
+
 CPreparedTiledFrameRequest::CPreparedTiledFrameRequest(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicFrameOperations> operations,
                                                        drmModeAtomicReqPtr request) noexcept : m_route(std::move(route)), m_operations(std::move(operations)), m_request(request) {}
 
diff --git a/src/backend/drm/TiledAtomic.hpp b/src/backend/drm/TiledAtomic.hpp
index 0bfa8f327f5905dd39a997e5d3713022dbae7498..e3eaf66bbd0bd33f7c528fe9f275cf8a5e2b7265 100644
--- a/src/backend/drm/TiledAtomic.hpp
+++ b/src/backend/drm/TiledAtomic.hpp
@@ -18,6 +18,18 @@
 #define AQ_TILED_ATOMIC_PRIVATE
 #endif
 
+namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
+    class CFixtureAuthority;
+}
+
+namespace Aquamarine::NDRM::NTiledDRMIntegrationTest {
+    class CFixtureAuthority;
+}
+
+namespace Aquamarine::NDRM::NTiledDRMIntegration {
+    class CTiledDRMIntegrationRegistry;
+}
+
 namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-naming): established Aquamarine DRM namespace
     using Hyprutils::Memory::CSharedPointer;
     using NTiledCrtcAllocator::CGroupDefinition;
@@ -44,6 +56,10 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         REQUEST_ALLOCATION_FAILED,
         MODE_BLOB_FAILED,
         PROPERTY_ADD_FAILED,
+        INCOMPLETE_REPLACEMENT,
+        FOREIGN_RESOURCE,
+        UNKNOWN_ATTACHMENT,
+        PROPERTY_CONFLICT,
     };
 
     struct AQ_TILED_ATOMIC_PRIVATE STiledAtomicFramebuffer {
@@ -204,6 +220,225 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
     // synchronously inside the combined registry/bridge current-owner gate.
     [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledAtomicResolveResult resolveCapturedTiledAtomic(const STiledAtomicResolveInput& input) noexcept;
 
+    enum class eTiledReplacementPlaneRole : uint8_t {
+        PRIMARY = 0,
+        CURSOR,
+        OVERLAY,
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledReplacementConnectorCapture {
+        CSharedPointer<SDRMConnector> connector;
+        CSharedPointer<SDRMCRTC>      attachedCrtc;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledReplacementCrtcCapture {
+        CSharedPointer<SDRMCRTC> crtc;
+    };
+
+    class CTiledAtomicFramebufferOwner;
+    using PAtomicFramebufferOwner = CSharedPointer<const CTiledAtomicFramebufferOwner>;
+
+    class AQ_TILED_ATOMIC_PRIVATE CTiledAtomicFramebufferOwner final {
+      public:
+        CTiledAtomicFramebufferOwner(const CTiledAtomicFramebufferOwner&)                                        = delete;
+        CTiledAtomicFramebufferOwner(CTiledAtomicFramebufferOwner&&)                                             = delete;
+        CTiledAtomicFramebufferOwner&                             operator=(const CTiledAtomicFramebufferOwner&) = delete;
+        CTiledAtomicFramebufferOwner&                             operator=(CTiledAtomicFramebufferOwner&&)      = delete;
+
+        [[nodiscard]] const POutputBridgeObservation&             generationOwner() const noexcept;
+        [[nodiscard]] const NTiledIncarnations::PBackendLifetime& backend() const noexcept;
+        [[nodiscard]] const CSharedPointer<CDRMFB>&               drmFramebuffer() const noexcept;
+        [[nodiscard]] const CSharedPointer<IBuffer>&              buffer() const noexcept;
+        [[nodiscard]] const STiledAtomicFramebuffer&              framebuffer() const noexcept;
+        [[nodiscard]] bool                                        dead() const noexcept;
+
+      private:
+        CTiledAtomicFramebufferOwner(POutputBridgeObservation generationOwner, NTiledIncarnations::PBackendLifetime backend, CSharedPointer<CDRMFB> drmFramebuffer,
+                                     CSharedPointer<IBuffer> buffer, STiledAtomicFramebuffer framebuffer, bool dead) noexcept;
+
+        [[nodiscard]] static PAtomicFramebufferOwner createCurrent(const POutputBridgeObservation& generationOwner, const CSharedPointer<CDRMFB>& drmFramebuffer) noexcept;
+        [[nodiscard]] static PAtomicFramebufferOwner createFixture(const POutputBridgeObservation& generationOwner, const CSharedPointer<CDRMFB>& drmFramebuffer,
+                                                                   const CSharedPointer<IBuffer>& buffer, STiledAtomicFramebuffer framebuffer, bool dead = false) noexcept;
+
+        POutputBridgeObservation                     m_generationOwner;
+        NTiledIncarnations::PBackendLifetime         m_backend;
+        CSharedPointer<CDRMFB>                       m_drmFramebuffer;
+        CSharedPointer<IBuffer>                      m_buffer;
+        STiledAtomicFramebuffer                      m_framebuffer;
+        bool                                         m_dead = true;
+
+        friend class ::Aquamarine::NDRM::NTiledRuntimeAuthorityTest::CFixtureAuthority;
+        friend class ::Aquamarine::NDRM::NTiledDRMIntegrationTest::CFixtureAuthority;
+        friend class ::Aquamarine::NDRM::NTiledDRMIntegration::CTiledDRMIntegrationRegistry;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledPlaneInventoryResource {
+        uint32_t                   id = 0;
+        CSharedPointer<SDRMPlane>  owner;
+        eTiledReplacementPlaneRole role = eTiledReplacementPlaneRole::PRIMARY;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledPlaneInventoryState {
+        uint32_t                  id = 0;
+        CSharedPointer<SDRMPlane> owner;
+        uint32_t                  crtcId        = 0;
+        uint32_t                  framebufferId = 0;
+        PAtomicFramebufferOwner   framebufferOwner;
+    };
+
+    class CTiledReplacementPlaneIncarnation;
+    using PReplacementPlaneIncarnation = CSharedPointer<const CTiledReplacementPlaneIncarnation>;
+
+    class AQ_TILED_ATOMIC_PRIVATE CTiledReplacementPlaneIncarnation final {
+      public:
+        CTiledReplacementPlaneIncarnation(const CTiledReplacementPlaneIncarnation&)                        = delete;
+        CTiledReplacementPlaneIncarnation(CTiledReplacementPlaneIncarnation&&)                             = delete;
+        CTiledReplacementPlaneIncarnation&             operator=(const CTiledReplacementPlaneIncarnation&) = delete;
+        CTiledReplacementPlaneIncarnation&             operator=(CTiledReplacementPlaneIncarnation&&)      = delete;
+
+        [[nodiscard]] const POutputBridgeObservation&  generationOwner() const noexcept;
+        [[nodiscard]] const CSharedPointer<SDRMPlane>& plane() const noexcept;
+        [[nodiscard]] uint64_t                         serial() const noexcept;
+
+      private:
+        CTiledReplacementPlaneIncarnation(POutputBridgeObservation generationOwner, CSharedPointer<SDRMPlane> plane, uint64_t serial) noexcept;
+
+        POutputBridgeObservation  m_generationOwner;
+        CSharedPointer<SDRMPlane> m_plane;
+        uint64_t                  m_serial = 0;
+
+        friend struct SReplacementAssembler;
+        friend class CTiledAtomicPlaneInventory;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledReplacementConnector {
+        CSharedPointer<SDRMConnector>              owner;
+        CSharedPointer<const SResourceIncarnation> incarnation;
+        CSharedPointer<SDRMCRTC>                   attachedCrtc;
+        uint32_t                                   id             = 0;
+        uint32_t                                   attachedCrtcId = 0;
+        uint32_t                                   crtcIdProperty = 0;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledReplacementCrtc {
+        CSharedPointer<SDRMCRTC>                   owner;
+        CSharedPointer<const SResourceIncarnation> incarnation;
+        uint32_t                                   id             = 0;
+        uint32_t                                   modeIdProperty = 0;
+        uint32_t                                   activeProperty = 0;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledReplacementPlane {
+        CSharedPointer<SDRMPlane>                  owner;
+        PReplacementPlaneIncarnation               incarnation;
+        CSharedPointer<const SResourceIncarnation> allocatorIncarnation;
+        PAtomicFramebufferOwner                    framebufferOwner;
+        uint32_t                                   id             = 0;
+        uint32_t                                   crtcId         = 0;
+        uint32_t                                   framebufferId  = 0;
+        uint32_t                                   fbIdProperty   = 0;
+        uint32_t                                   crtcIdProperty = 0;
+        eTiledReplacementPlaneRole                 role           = eTiledReplacementPlaneRole::PRIMARY;
+    };
+
+    class CTiledAtomicPlaneInventory;
+    using PAtomicPlaneInventory = CSharedPointer<const CTiledAtomicPlaneInventory>;
+
+    // Minted only by a trusted current-gate adapter (or its friend fixture)
+    // from the backend's complete plane-resource list and an equal-size state
+    // capture. It includes inactive planes so cursor/overlay owners cannot be
+    // omitted merely because they are not currently scanning out.
+    class AQ_TILED_ATOMIC_PRIVATE CTiledAtomicPlaneInventory final {
+      public:
+        CTiledAtomicPlaneInventory(const CTiledAtomicPlaneInventory&)                                          = delete;
+        CTiledAtomicPlaneInventory(CTiledAtomicPlaneInventory&&)                                               = delete;
+        CTiledAtomicPlaneInventory&                               operator=(const CTiledAtomicPlaneInventory&) = delete;
+        CTiledAtomicPlaneInventory&                               operator=(CTiledAtomicPlaneInventory&&)      = delete;
+
+        [[nodiscard]] const POutputBridgeObservation&             generationOwner() const noexcept;
+        [[nodiscard]] const NTiledIncarnations::PBackendLifetime& backend() const noexcept;
+        [[nodiscard]] std::span<const STiledReplacementPlane>     planes() const noexcept;
+
+      private:
+        CTiledAtomicPlaneInventory(POutputBridgeObservation generationOwner, NTiledIncarnations::PBackendLifetime backend, std::vector<STiledReplacementPlane> planes) noexcept;
+
+        [[nodiscard]] static PAtomicPlaneInventory create(const POutputBridgeObservation& generationOwner, std::vector<STiledPlaneInventoryResource> resources,
+                                                          std::vector<STiledPlaneInventoryState> states) noexcept;
+
+        POutputBridgeObservation                   m_generationOwner;
+        NTiledIncarnations::PBackendLifetime       m_backend;
+        std::vector<STiledReplacementPlane>        m_planes;
+
+        friend class ::Aquamarine::NDRM::NTiledRuntimeAuthorityTest::CFixtureAuthority;
+        friend class ::Aquamarine::NDRM::NTiledDRMIntegrationTest::CFixtureAuthority;
+        friend class ::Aquamarine::NDRM::NTiledDRMIntegration::CTiledDRMIntegrationRegistry;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledAtomicReplacementCapture {
+        PResolvedTiledAtomicRoute                      targetRoute;
+        PAtomicFramebufferOwner                        targetFramebufferOwner;
+        PAtomicPlaneInventory                          planeInventory;
+        std::vector<STiledReplacementConnectorCapture> connectors;
+        std::vector<STiledReplacementCrtcCapture>      crtcs;
+    };
+
+    enum class eTiledAtomicPropertyValueSource : uint8_t {
+        FIXED = 0,
+        MODE_BLOB,
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledAtomicPropertyWrite {
+        uint32_t                        objectId    = 0;
+        uint32_t                        propertyId  = 0;
+        eTiledAtomicPropertyValueSource source      = eTiledAtomicPropertyValueSource::FIXED;
+        uint64_t                        value       = 0;
+        size_t                          memberIndex = 0;
+
+        bool                            operator==(const STiledAtomicPropertyWrite&) const = default;
+    };
+
+    class CResolvedTiledAtomicReplacement;
+    using PResolvedTiledAtomicReplacement = CSharedPointer<const CResolvedTiledAtomicReplacement>;
+
+    class AQ_TILED_ATOMIC_PRIVATE CResolvedTiledAtomicReplacement final {
+      public:
+        CResolvedTiledAtomicReplacement(const CResolvedTiledAtomicReplacement&)                                     = delete;
+        CResolvedTiledAtomicReplacement(CResolvedTiledAtomicReplacement&&)                                          = delete;
+        CResolvedTiledAtomicReplacement&                          operator=(const CResolvedTiledAtomicReplacement&) = delete;
+        CResolvedTiledAtomicReplacement&                          operator=(CResolvedTiledAtomicReplacement&&)      = delete;
+
+        [[nodiscard]] const PResolvedTiledAtomicRoute&            targetRoute() const noexcept;
+        [[nodiscard]] const PAtomicFramebufferOwner&              targetFramebufferOwner() const noexcept;
+        [[nodiscard]] const PAtomicPlaneInventory&                planeInventory() const noexcept;
+        [[nodiscard]] std::span<const STiledReplacementConnector> connectors() const noexcept;
+        [[nodiscard]] std::span<const STiledReplacementCrtc>      crtcs() const noexcept;
+        [[nodiscard]] std::span<const STiledReplacementPlane>     planes() const noexcept;
+        [[nodiscard]] std::span<const STiledAtomicPropertyWrite>  propertyGraph() const noexcept;
+
+      private:
+        CResolvedTiledAtomicReplacement(PResolvedTiledAtomicRoute targetRoute, PAtomicFramebufferOwner targetFramebufferOwner, PAtomicPlaneInventory planeInventory,
+                                        std::vector<STiledReplacementConnector> connectors, std::vector<STiledReplacementCrtc> crtcs,
+                                        std::vector<STiledAtomicPropertyWrite> propertyGraph) noexcept;
+
+        PResolvedTiledAtomicRoute               m_targetRoute;
+        PAtomicFramebufferOwner                 m_targetFramebufferOwner;
+        PAtomicPlaneInventory                   m_planeInventory;
+        std::vector<STiledReplacementConnector> m_connectors;
+        std::vector<STiledReplacementCrtc>      m_crtcs;
+        std::vector<STiledAtomicPropertyWrite>  m_propertyGraph;
+
+        friend struct SReplacementAssembler;
+    };
+
+    struct AQ_TILED_ATOMIC_PRIVATE STiledAtomicReplacementResolveResult {
+        PResolvedTiledAtomicReplacement replacement;
+        eTiledAtomicError               error = eTiledAtomicError::INVALID_INPUT;
+
+        explicit                        operator bool() const noexcept;
+    };
+
+    [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledAtomicReplacementResolveResult resolveTiledAtomicReplacement(STiledAtomicReplacementCapture capture) noexcept;
+
     class AQ_TILED_ATOMIC_PRIVATE ITiledAtomicFrameOperations {
       public:
         virtual ~ITiledAtomicFrameOperations() = default;
@@ -292,16 +527,19 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
         ~CPreparedTiledModesetRequest() noexcept;
 
         [[nodiscard]] const PResolvedTiledAtomicRoute&                     route() const noexcept;
+        [[nodiscard]] const PResolvedTiledAtomicReplacement&               replacement() 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:
-        CPreparedTiledModesetRequest(PResolvedTiledAtomicRoute route, CSharedPointer<ITiledAtomicRequestOperations> operations, PModeBlobCleanupRegistry cleanupRegistry,
-                                     drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs, std::vector<PModeBlobCleanupRecord> modeBlobOwners) noexcept;
+        CPreparedTiledModesetRequest(PResolvedTiledAtomicRoute route, PResolvedTiledAtomicReplacement replacement, CSharedPointer<ITiledAtomicRequestOperations> operations,
+                                     PModeBlobCleanupRegistry cleanupRegistry, drmModeAtomicReqPtr request, std::vector<uint32_t> modeBlobs,
+                                     std::vector<PModeBlobCleanupRecord> modeBlobOwners) noexcept;
 
         PResolvedTiledAtomicRoute                     m_route;
+        PResolvedTiledAtomicReplacement               m_replacement;
         CSharedPointer<ITiledAtomicRequestOperations> m_operations;
         PModeBlobCleanupRegistry                      m_cleanupRegistry;
         drmModeAtomicReqPtr                           m_request = nullptr;
@@ -323,9 +561,15 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
     [[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 buildTiledModesetRequest(const PResolvedTiledAtomicReplacement& replacement, 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;
+    [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledAtomicBuildResult buildTiledTestModeset(const PResolvedTiledAtomicReplacement& replacement, int drmFD,
+                                                                                        const CSharedPointer<ITiledAtomicRequestOperations>& operations,
+                                                                                        const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept;
 
     inline constexpr uint32_t                                     TILED_ATOMIC_TEST_MODESET_FLAGS = DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY;
 
@@ -354,6 +598,9 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
     [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledTestModesetExecutionResult executeTiledTestModeset(const PResolvedTiledAtomicRoute& route, int drmFD,
                                                                                                    const CSharedPointer<ITiledAtomicRequestOperations>& operations,
                                                                                                    const PModeBlobCleanupRegistry&                      cleanupRegistry) noexcept;
+    [[nodiscard]] AQ_TILED_ATOMIC_PRIVATE STiledTestModesetExecutionResult executeTiledTestModeset(const PResolvedTiledAtomicReplacement& replacement, int drmFD,
+                                                                                                   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_INITIAL_FRAME_FLAGS = TILED_ATOMIC_FRAME_FLAGS | DRM_MODE_ATOMIC_ALLOW_MODESET;
@@ -606,7 +853,7 @@ namespace Aquamarine::NDRM::NTiledAtomic { // NOLINT(readability-identifier-nami
     [[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)
+        if (!prepared || !prepared->replacement())
             return {.status = eTiledFrameTransactionStatus::INVALID_INPUT};
 
         auto result = NDetail::submitPreparedTiledFrameTransaction(prepared->route(), runtime, registry, std::move(frame), transactionId, deadlineNs, drmFD, prepared->operations(),
diff --git a/src/backend/drm/TiledDRMIntegration.cpp b/src/backend/drm/TiledDRMIntegration.cpp
index 5e668fe4854456ad0c6c6dea017f0dda8a1ec6ac..3cf40b36589ebf53abb2aadfab3d0d82f17daf6c 100644
--- a/src/backend/drm/TiledDRMIntegration.cpp
+++ b/src/backend/drm/TiledDRMIntegration.cpp
@@ -16,6 +16,7 @@ using namespace Aquamarine;
 using namespace Aquamarine::NDRM::NTiledDRMIntegration;
 using namespace Aquamarine::NDRM::NTiledIncarnations;
 using namespace Aquamarine::NDRM::NTiledCrtcAllocator;
+using namespace Aquamarine::NDRM::NTiledAtomic;
 using namespace Aquamarine::NDRM::NTiledOutputBridge;
 using namespace Aquamarine::NDRM::NTiledRuntimeAuthority;
 using namespace Aquamarine::NDRM::NTiledScan;
@@ -52,6 +53,15 @@ namespace {
         return expected;
     }
 
+    [[nodiscard]] bool exactReplacementRequest(const PResolvedTiledAtomicReplacement& replacement, const POutputBridgeObservation& expected, const PScanGroupDefinition& group,
+                                               const CSharedPointer<SOutputMode>& outputMode) noexcept {
+        if (!replacement || !expected || !group || !outputMode || !replacement->targetRoute() || !replacement->targetFramebufferOwner() || !replacement->planeInventory())
+            return false;
+        return replacement->targetRoute()->generationOwner().impl_ == expected.impl_ && replacement->targetFramebufferOwner()->generationOwner().impl_ == expected.impl_ &&
+            replacement->planeInventory()->generationOwner().impl_ == expected.impl_ && replacement->targetRoute()->groupDefinition().impl_ == group.impl_ &&
+            replacement->targetRoute()->outputMode().impl_ == outputMode.impl_;
+    }
+
     eScanBeginResult beginFailure(eBeginAttemptResult result) noexcept {
         switch (result) {
             case eBeginAttemptResult::WRONG_THREAD: return eScanBeginResult::WRONG_THREAD;
@@ -973,12 +983,12 @@ bool CTiledDRMIntegrationRegistry::withCurrentOutputBridge(const CWeakPointer<CD
 }
 
 SGroupedTestModesetResult CTiledDRMIntegrationRegistry::executeCurrentGroupedTestModesetKey(const void* key, const POutputBridgeObservation& expected,
-                                                                                            const PScanGroupDefinition&        group,
+                                                                                            const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
                                                                                             const CSharedPointer<SOutputMode>& outputMode) noexcept {
     const auto THREAD = m_impl->registeredThread(key);
     if (!THREAD || *THREAD != std::this_thread::get_id())
         return {.status = eGroupedTestModesetStatus::WRONG_THREAD};
-    if (!expected || !group || !outputMode)
+    if (!exactReplacementRequest(replacement, expected, group, outputMode))
         return {.status = eGroupedTestModesetStatus::INVALID_CURRENT};
     const auto ENTRY = m_impl->entries.find(key);
     if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun || !ENTRY->second.outputBridge || !ENTRY->second.groupedRuntime || !ENTRY->second.allocationShadow)
@@ -996,10 +1006,10 @@ SGroupedTestModesetResult CTiledDRMIntegrationRegistry::executeCurrentGroupedTes
             if (CURRENT_ENTRY == m_impl->entries.end() || !CURRENT_ENTRY->second.outputBridge || !CURRENT_ENTRY->second.groupedRuntime)
                 return;
             bridgeCurrent = CURRENT_ENTRY->second.outputBridge->withCurrentOwner(current, [&](const POutputBridgeObservation& observation) {
-                if (observation.impl_ != expected.impl_)
+                if (observation.impl_ != expected.impl_ || !exactReplacementRequest(replacement, observation, group, outputMode))
                     return;
                 invoked = true;
-                result  = CURRENT_ENTRY->second.groupedRuntime->executeCurrentTestModeset(observation, group, outputMode);
+                result  = CURRENT_ENTRY->second.groupedRuntime->executeCurrentTestModeset(observation, replacement, group, outputMode);
             });
         });
         return ALLOCATION_CURRENT && bridgeCurrent && invoked ? result : SGroupedTestModesetResult{.status = eGroupedTestModesetStatus::INVALID_CURRENT};
@@ -1007,20 +1017,21 @@ SGroupedTestModesetResult CTiledDRMIntegrationRegistry::executeCurrentGroupedTes
 }
 
 SGroupedTestModesetResult CTiledDRMIntegrationRegistry::executeCurrentGroupedTestModeset(const CWeakPointer<CDRMBackend>& backend, const POutputBridgeObservation& expected,
-                                                                                         const PScanGroupDefinition&        group,
+                                                                                         const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
                                                                                          const CSharedPointer<SOutputMode>& outputMode) noexcept {
-    return executeCurrentGroupedTestModesetKey(backend.impl_, expected, group, outputMode);
+    return executeCurrentGroupedTestModesetKey(backend.impl_, expected, replacement, group, outputMode);
 }
 
 SGroupedInitialFrameResult CTiledDRMIntegrationRegistry::submitCurrentGroupedInitialFrameKey(const void* key, const POutputBridgeObservation& expected,
-                                                                                             const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
+                                                                                             const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                                                             const CSharedPointer<SOutputMode>& outputMode,
                                                                                              const PGroupedPublicationInstance& publication,
                                                                                              const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer,
                                                                                              uintptr_t transactionId, uint64_t deadlineNs) noexcept {
     const auto THREAD = m_impl->registeredThread(key);
     if (!THREAD || *THREAD != std::this_thread::get_id())
         return {.status = eGroupedInitialFrameStatus::WRONG_THREAD};
-    if (!expected || !group || !outputMode || !publication || transactionId == 0 || deadlineNs == 0)
+    if (!exactReplacementRequest(replacement, expected, group, outputMode) || !publication || transactionId == 0 || deadlineNs == 0)
         return {.status = eGroupedInitialFrameStatus::INVALID_CURRENT};
     const auto ENTRY = m_impl->entries.find(key);
     if (ENTRY == m_impl->entries.end() || ENTRY->second.detachBegun || !ENTRY->second.outputBridge || !ENTRY->second.groupedRuntime || !ENTRY->second.allocationShadow)
@@ -1038,10 +1049,11 @@ SGroupedInitialFrameResult CTiledDRMIntegrationRegistry::submitCurrentGroupedIni
             if (CURRENT_ENTRY == m_impl->entries.end() || !CURRENT_ENTRY->second.outputBridge || !CURRENT_ENTRY->second.groupedRuntime)
                 return;
             bridgeCurrent = CURRENT_ENTRY->second.outputBridge->withCurrentOwner(current, [&](const POutputBridgeObservation& observation) {
-                if (observation.impl_ != expected.impl_)
+                if (observation.impl_ != expected.impl_ || !exactReplacementRequest(replacement, observation, group, outputMode))
                     return;
                 invoked = true;
-                result  = CURRENT_ENTRY->second.groupedRuntime->submitInitialCurrent(observation, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
+                result  = CURRENT_ENTRY->second.groupedRuntime->submitInitialCurrent(observation, replacement, group, outputMode, publication, framebuffer, buffer, transactionId,
+                                                                                     deadlineNs);
             });
         });
         return ALLOCATION_CURRENT && bridgeCurrent && invoked ? result : SGroupedInitialFrameResult{.status = eGroupedInitialFrameStatus::INVALID_CURRENT};
@@ -1049,11 +1061,12 @@ SGroupedInitialFrameResult CTiledDRMIntegrationRegistry::submitCurrentGroupedIni
 }
 
 SGroupedInitialFrameResult CTiledDRMIntegrationRegistry::submitCurrentGroupedInitialFrame(const CWeakPointer<CDRMBackend>& backend, const POutputBridgeObservation& expected,
-                                                                                          const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
+                                                                                          const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                                                          const CSharedPointer<SOutputMode>& outputMode,
                                                                                           const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
                                                                                           const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
                                                                                           uint64_t deadlineNs) noexcept {
-    return submitCurrentGroupedInitialFrameKey(backend.impl_, expected, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
+    return submitCurrentGroupedInitialFrameKey(backend.impl_, expected, replacement, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
 }
 
 SOrdinaryKMSGateResult CTiledDRMIntegrationRegistry::gateOrdinaryKMSKey(const void* key, const CWeakPointer<CDRMBackend>& backend, std::span<const SOrdinaryKMSCRTC> crtcs,
@@ -1133,16 +1146,18 @@ bool CTiledDRMIntegrationRegistry::configureInjectedTestModeset(const PBackendLi
 }
 
 SGroupedTestModesetResult CTiledDRMIntegrationRegistry::executeCurrentTestModeset(const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
-                                                                                  const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept {
-    return executeCurrentGroupedTestModesetKey(lifetime.impl_, expected, group, outputMode);
+                                                                                  const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                                                  const CSharedPointer<SOutputMode>& outputMode) noexcept {
+    return executeCurrentGroupedTestModesetKey(lifetime.impl_, expected, replacement, group, outputMode);
 }
 
 SGroupedInitialFrameResult CTiledDRMIntegrationRegistry::submitCurrentTestInitialFrame(const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
-                                                                                       const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
+                                                                                       const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                                                       const CSharedPointer<SOutputMode>& outputMode,
                                                                                        const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
                                                                                        const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
                                                                                        uint64_t deadlineNs) noexcept {
-    return submitCurrentGroupedInitialFrameKey(lifetime.impl_, expected, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
+    return submitCurrentGroupedInitialFrameKey(lifetime.impl_, expected, replacement, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
 }
 
 eSessionResult CTiledDRMIntegrationRegistry::rotateSessionKey(const void* key) noexcept {
diff --git a/src/backend/drm/TiledDRMIntegration.hpp b/src/backend/drm/TiledDRMIntegration.hpp
index 9b50451d93927b88c7b46962f8a906483ff350e2..d7072204e54ca5dba0578c5d4203911e40bbf259 100644
--- a/src/backend/drm/TiledDRMIntegration.hpp
+++ b/src/backend/drm/TiledDRMIntegration.hpp
@@ -223,70 +223,74 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
         explicit CTiledDRMIntegrationRegistry(std::thread::id eventThread = std::this_thread::get_id());
         ~CTiledDRMIntegrationRegistry() noexcept;
 
-        CTiledDRMIntegrationRegistry(const CTiledDRMIntegrationRegistry&)                      = delete;
-        CTiledDRMIntegrationRegistry(CTiledDRMIntegrationRegistry&&)                           = delete;
-        CTiledDRMIntegrationRegistry&           operator=(const CTiledDRMIntegrationRegistry&) = delete;
-        CTiledDRMIntegrationRegistry&           operator=(CTiledDRMIntegrationRegistry&&)      = delete;
+        CTiledDRMIntegrationRegistry(const CTiledDRMIntegrationRegistry&)                       = delete;
+        CTiledDRMIntegrationRegistry(CTiledDRMIntegrationRegistry&&)                            = delete;
+        CTiledDRMIntegrationRegistry&            operator=(const CTiledDRMIntegrationRegistry&) = delete;
+        CTiledDRMIntegrationRegistry&            operator=(CTiledDRMIntegrationRegistry&&)      = delete;
 
-        [[nodiscard]] SBeginConnectorScanResult beginConnectorScan(const CSharedPointer<CDRMBackend>& backend);
-        [[nodiscard]] eScanStageResult          stageConnectorScan(const PConnectorScan& scan, eScanCompleteness completeness, std::vector<SConnectorView> connectors) noexcept;
-        [[nodiscard]] eScanCommitResult         commitConnectorScan(const PConnectorScan& scan) noexcept;
-        void                                    abortConnectorScan(const PConnectorScan& scan) noexcept;
+        [[nodiscard]] SBeginConnectorScanResult  beginConnectorScan(const CSharedPointer<CDRMBackend>& backend);
+        [[nodiscard]] eScanStageResult           stageConnectorScan(const PConnectorScan& scan, eScanCompleteness completeness, std::vector<SConnectorView> connectors) noexcept;
+        [[nodiscard]] eScanCommitResult          commitConnectorScan(const PConnectorScan& scan) noexcept;
+        void                                     abortConnectorScan(const PConnectorScan& scan) noexcept;
 
-        [[nodiscard]] eAllocationCaptureResult  captureAllocationShadow(const CSharedPointer<CDRMBackend>& backend, SAllocationCapture capture) noexcept;
-        [[nodiscard]] PAllocationShadow         currentAllocationShadow(const CWeakPointer<CDRMBackend>& backend) noexcept;
-        [[nodiscard]] bool                      withCurrentAllocationShadow(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
-                                                                            const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
-        [[nodiscard]] bool                      withCurrentOutputBridge(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
-                                                                        const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
-        [[nodiscard]] SGroupedTestModesetResult executeCurrentGroupedTestModeset(const CWeakPointer<CDRMBackend>& backend, const POutputBridgeObservation& expected,
-                                                                                 const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
+        [[nodiscard]] eAllocationCaptureResult   captureAllocationShadow(const CSharedPointer<CDRMBackend>& backend, SAllocationCapture capture) noexcept;
+        [[nodiscard]] PAllocationShadow          currentAllocationShadow(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] bool                       withCurrentAllocationShadow(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
+                                                                             const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
+        [[nodiscard]] bool                       withCurrentOutputBridge(const CWeakPointer<CDRMBackend>& backend, const PAllocationShadow& expected,
+                                                                         const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
+        [[nodiscard]] SGroupedTestModesetResult  executeCurrentGroupedTestModeset(const CWeakPointer<CDRMBackend>& backend, const POutputBridgeObservation& expected,
+                                                                                  const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
+                                                                                  const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
         [[nodiscard]] SGroupedInitialFrameResult submitCurrentGroupedInitialFrame(const CWeakPointer<CDRMBackend>& backend, const POutputBridgeObservation& expected,
+                                                                                  const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
                                                                                   const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
                                                                                   const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
                                                                                   const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) noexcept;
-        [[nodiscard]] SOrdinaryKMSGateResult    gateOrdinaryKMS(const CWeakPointer<CDRMBackend>& backend, std::span<const SOrdinaryKMSCRTC> crtcs,
-                                                                const std::function<bool()>& callback) noexcept;
-        [[nodiscard]] SGroupedPageFlipResult    routeGroupedPageFlip(const CWeakPointer<CDRMBackend>& backend, uintptr_t transactionId, uint32_t crtcId, uint32_t sequence,
-                                                                     uint64_t timestampNs) noexcept;
+        [[nodiscard]] SOrdinaryKMSGateResult     gateOrdinaryKMS(const CWeakPointer<CDRMBackend>& backend, std::span<const SOrdinaryKMSCRTC> crtcs,
+                                                                 const std::function<bool()>& callback) noexcept;
+        [[nodiscard]] SGroupedPageFlipResult     routeGroupedPageFlip(const CWeakPointer<CDRMBackend>& backend, uintptr_t transactionId, uint32_t crtcId, uint32_t sequence,
+                                                                      uint64_t timestampNs) noexcept;
 
-        [[nodiscard]] eSessionResult            rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept;
-        [[nodiscard]] eDetachResult             beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept;
-        [[nodiscard]] eDetachResult             terminalizeDetached(const CWeakPointer<CDRMBackend>& backend, eDetachTerminalProof proof) noexcept;
-        [[nodiscard]] eDetachResult             eraseTerminalized(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] eSessionResult             rotateSession(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] eDetachResult              beginDetach(const CWeakPointer<CDRMBackend>& backend, eDetachReason reason) noexcept;
+        [[nodiscard]] eDetachResult              terminalizeDetached(const CWeakPointer<CDRMBackend>& backend, eDetachTerminalProof proof) noexcept;
+        [[nodiscard]] eDetachResult              eraseTerminalized(const CWeakPointer<CDRMBackend>& backend) noexcept;
 
-        [[nodiscard]] bool                      attached(const CWeakPointer<CDRMBackend>& backend) const noexcept;
-        [[nodiscard]] bool                      lastConnectorScanComplete(const CWeakPointer<CDRMBackend>& backend) const noexcept;
-        [[nodiscard]] PCommittedScan            currentComplete(const CWeakPointer<CDRMBackend>& backend) noexcept;
-        [[nodiscard]] SScanOutcome              outcome(const CWeakPointer<CDRMBackend>& backend) noexcept;
-        [[nodiscard]] bool                      readyForDestruction() const noexcept;
+        [[nodiscard]] bool                       attached(const CWeakPointer<CDRMBackend>& backend) const noexcept;
+        [[nodiscard]] bool                       lastConnectorScanComplete(const CWeakPointer<CDRMBackend>& backend) const noexcept;
+        [[nodiscard]] PCommittedScan             currentComplete(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] SScanOutcome               outcome(const CWeakPointer<CDRMBackend>& backend) noexcept;
+        [[nodiscard]] bool                       readyForDestruction() const noexcept;
 
         // Narrow source-private failure injection for lifecycle tests.
         void failNextAttachmentForTest() noexcept;
 
       private:
-        [[nodiscard]] SBeginConnectorScanResult beginAttached(const void* key);
-        [[nodiscard]] eSessionResult            rotateSessionKey(const void* key) noexcept;
-        [[nodiscard]] eDetachResult             beginDetachKey(const void* key, eDetachReason reason) noexcept;
-        [[nodiscard]] eDetachResult             terminalizeDetachedKey(const void* key, eDetachTerminalProof proof) noexcept;
-        [[nodiscard]] eDetachResult             eraseTerminalizedKey(const void* key) noexcept;
-        [[nodiscard]] bool                      attachedKey(const void* key) const noexcept;
-        [[nodiscard]] PCommittedScan            currentCompleteKey(const void* key) noexcept;
-        [[nodiscard]] SScanOutcome              outcomeKey(const void* key) noexcept;
-        [[nodiscard]] eAllocationCaptureResult  captureAllocationKey(const void* key, SAllocationCapture capture) noexcept;
-        [[nodiscard]] PAllocationShadow         currentAllocationKey(const void* key) noexcept;
-        [[nodiscard]] bool                      withCurrentAllocationKey(const void* key, const PAllocationShadow& expected,
-                                                                         const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
-        [[nodiscard]] bool                      withCurrentOutputBridgeKey(const void* key, const PAllocationShadow& expected,
-                                                                           const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
-        [[nodiscard]] SGroupedTestModesetResult executeCurrentGroupedTestModesetKey(const void* key, const POutputBridgeObservation& expected, const PScanGroupDefinition& group,
-                                                                                    const CSharedPointer<SOutputMode>& outputMode) noexcept;
-        [[nodiscard]] SGroupedInitialFrameResult submitCurrentGroupedInitialFrameKey(const void* key, const POutputBridgeObservation& expected, const PScanGroupDefinition& group,
-                                                                                     const CSharedPointer<SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
-                                                                                     const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer,
-                                                                                     uintptr_t transactionId, uint64_t deadlineNs) noexcept;
-        [[nodiscard]] SOrdinaryKMSGateResult    gateOrdinaryKMSKey(const void* key, const CWeakPointer<CDRMBackend>& backend, std::span<const SOrdinaryKMSCRTC> crtcs,
-                                                                   const std::function<bool()>& callback) noexcept;
+        [[nodiscard]] SBeginConnectorScanResult  beginAttached(const void* key);
+        [[nodiscard]] eSessionResult             rotateSessionKey(const void* key) noexcept;
+        [[nodiscard]] eDetachResult              beginDetachKey(const void* key, eDetachReason reason) noexcept;
+        [[nodiscard]] eDetachResult              terminalizeDetachedKey(const void* key, eDetachTerminalProof proof) noexcept;
+        [[nodiscard]] eDetachResult              eraseTerminalizedKey(const void* key) noexcept;
+        [[nodiscard]] bool                       attachedKey(const void* key) const noexcept;
+        [[nodiscard]] PCommittedScan             currentCompleteKey(const void* key) noexcept;
+        [[nodiscard]] SScanOutcome               outcomeKey(const void* key) noexcept;
+        [[nodiscard]] eAllocationCaptureResult   captureAllocationKey(const void* key, SAllocationCapture capture) noexcept;
+        [[nodiscard]] PAllocationShadow          currentAllocationKey(const void* key) noexcept;
+        [[nodiscard]] bool                       withCurrentAllocationKey(const void* key, const PAllocationShadow& expected,
+                                                                          const std::function<void(const CPlan&, const SCurrentState&)>& callback) noexcept;
+        [[nodiscard]] bool                       withCurrentOutputBridgeKey(const void* key, const PAllocationShadow& expected,
+                                                                            const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
+        [[nodiscard]] SGroupedTestModesetResult  executeCurrentGroupedTestModesetKey(const void* key, const POutputBridgeObservation& expected,
+                                                                                     const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
+                                                                                     const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
+        [[nodiscard]] SGroupedInitialFrameResult submitCurrentGroupedInitialFrameKey(const void* key, const POutputBridgeObservation& expected,
+                                                                                     const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement,
+                                                                                     const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
+                                                                                     const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                                     const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) noexcept;
+        [[nodiscard]] SOrdinaryKMSGateResult     gateOrdinaryKMSKey(const void* key, const CWeakPointer<CDRMBackend>& backend, std::span<const SOrdinaryKMSCRTC> crtcs,
+                                                                    const std::function<bool()>& callback) noexcept;
         [[nodiscard]] SGroupedPageFlipResult routeGroupedPageFlipKey(const void* key, uintptr_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept;
         void                                 abortConnectorScan(CConnectorScan& scan) noexcept;
 
@@ -308,13 +312,15 @@ namespace Aquamarine::NDRM::NTiledDRMIntegration { // NOLINT(readability-identif
                                                                             const std::function<void(const POutputBridgeObservation&)>& callback) noexcept;
         [[nodiscard]] bool configureInjectedTestModeset(const PBackendLifetime& lifetime, int drmFD, const CSharedPointer<NTiledAtomic::ITiledAtomicRequestOperations>& operations,
                                                         const CSharedPointer<IGroupedTestFramebufferSource>& framebufferSource) noexcept;
-        [[nodiscard]] SGroupedTestModesetResult executeCurrentTestModeset(const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
-                                                                          const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
+        [[nodiscard]] SGroupedTestModesetResult  executeCurrentTestModeset(const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
+                                                                           const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                                           const CSharedPointer<SOutputMode>& outputMode) noexcept;
         [[nodiscard]] SGroupedInitialFrameResult submitCurrentTestInitialFrame(const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
-                                                                               const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
-                                                                               const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
-                                                                               const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) noexcept;
-        [[nodiscard]] bool                      exhaustTestResourceEpoch(const PBackendLifetime& lifetime) noexcept;
+                                                                               const NTiledAtomic::PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                                               const CSharedPointer<SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
+                                                                               const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer,
+                                                                               uintptr_t transactionId, uint64_t deadlineNs) noexcept;
+        [[nodiscard]] bool                       exhaustTestResourceEpoch(const PBackendLifetime& lifetime) noexcept;
 
         class CImpl;
         Hyprutils::Memory::CUniquePointer<CImpl> m_impl;
diff --git a/src/backend/drm/TiledRuntime.hpp b/src/backend/drm/TiledRuntime.hpp
index b3b8f2ed4d1dff773955335d4a8e49900fe91d39..f8a118852c81ac96536aad26cd3b8fbb59b34975 100644
--- a/src/backend/drm/TiledRuntime.hpp
+++ b/src/backend/drm/TiledRuntime.hpp
@@ -424,6 +424,28 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
             return true;
         }
 
+        // A replacement attempt may need PUBLISHED_DISABLED semantics while
+        // constructing/reserving the first transaction, before KMS has
+        // accepted anything. Only this never-published arm can return to the
+        // operationally inert STAGED state.
+        [[nodiscard]] bool armInitialAttempt() noexcept {
+            if (m_state != eTiledRuntimeState::STAGED || m_everPublished || m_prepared || !m_currentFrames.empty() || !m_lastFrames.empty() ||
+                std::ranges::any_of(
+                    m_members, [](const auto& member) { return member.frontFramebuffer != 0 || member.backFramebuffer != 0 || member.frontBuffer != 0 || member.backBuffer != 0; }))
+                return false;
+            m_state = eTiledRuntimeState::PUBLISHED_DISABLED;
+            return true;
+        }
+
+        [[nodiscard]] bool rollbackInitialAttempt() noexcept {
+            if (m_state != eTiledRuntimeState::PUBLISHED_DISABLED || m_everPublished || m_prepared || !m_currentFrames.empty() || !m_lastFrames.empty() ||
+                std::ranges::any_of(
+                    m_members, [](const auto& member) { return member.frontFramebuffer != 0 || member.backFramebuffer != 0 || member.frontBuffer != 0 || member.backBuffer != 0; }))
+                return false;
+            m_state = eTiledRuntimeState::STAGED;
+            return true;
+        }
+
         [[nodiscard]] bool publishIdle(std::vector<SMemberFrame> frames) {
             if (m_state != eTiledRuntimeState::STAGED && m_state != eTiledRuntimeState::PUBLISHED_DISABLED)
                 return false;
@@ -522,7 +544,8 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
                 MEMBER.backBuffer      = m_prepared->frame.bufferId;
             }
 
-            m_state = eTiledRuntimeState::PUBLISHED_IN_FLIGHT;
+            m_state         = eTiledRuntimeState::PUBLISHED_IN_FLIGHT;
+            m_everPublished = true;
             return {.accepted = true, .schedulerSubmit = true};
         }
 
@@ -543,6 +566,7 @@ namespace Aquamarine::NDRM { // NOLINT(readability-identifier-naming): establish
             }
             static_cast<void>(m_prepared->barrier.cancel());
             m_state          = eTiledRuntimeState::QUIESCED;
+            m_everPublished  = true;
             m_quiesceReason  = eTiledQuiesceReason::EVENT_INVARIANT;
             m_restorePending = false;
             return true;
diff --git a/src/backend/drm/TiledRuntimeAuthority.cpp b/src/backend/drm/TiledRuntimeAuthority.cpp
index 0410f208731d4bcf51241ed8828fdbadd3eab360..7b5b8972c43a255c676c2f0dd1e9da328aa336e1 100644
--- a/src/backend/drm/TiledRuntimeAuthority.cpp
+++ b/src/backend/drm/TiledRuntimeAuthority.cpp
@@ -341,8 +341,8 @@ bool CGroupedRuntimeAuthority::validTestFramebuffer(const PGroupedTestFramebuffe
         ATTRS.modifier == framebuffer->atomic.modifier;
 }
 
-SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModeset(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
-                                                                              const CSharedPointer<SOutputMode>& outputMode) noexcept {
+SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModeset(const POutputBridgeObservation& current, const PResolvedTiledAtomicReplacement& replacement,
+                                                                              const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept {
     if (!onEventThread())
         return {.status = eGroupedTestModesetStatus::WRONG_THREAD};
     if (m_mutationActive)
@@ -355,9 +355,12 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModeset(co
     m_mutationActive = true;
     Hyprutils::Utils::CScopeGuard mutationGuard([&] { m_mutationActive = false; });
     try {
+        const auto& ROUTE    = replacement ? replacement->targetRoute() : PResolvedTiledAtomicRoute{};
         const auto& SNAPSHOT = current ? current->capturedSnapshot() : CSharedPointer<const CSnapshot>{};
         const auto* GROUP    = current ? current->findGroup(group) : nullptr;
-        if (!SNAPSHOT || !sameOwner(SNAPSHOT->device(), m_testDevice) || !GROUP || !sameOwner(GROUP->scanDefinition(), group) || !GROUP->definitionIdentity())
+        if (!SNAPSHOT || !sameOwner(SNAPSHOT->device(), m_testDevice) || !GROUP || !sameOwner(GROUP->scanDefinition(), group) || !GROUP->definitionIdentity() || !replacement ||
+            !exactCurrentRoute(current, ROUTE) || !sameOwner(ROUTE->groupDefinition(), group) || !sameOwner(ROUTE->definitionIdentity(), GROUP->definitionIdentity()) ||
+            !sameOwner(ROUTE->outputMode(), outputMode))
             return {.status = eGroupedTestModesetStatus::INVALID_CURRENT};
         if (GROUP->projection() != eGroupProjection::MULTI_STREAM_ALLOCATED)
             return {.status = eGroupedTestModesetStatus::NOT_ALLOCATED};
@@ -409,6 +412,15 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModeset(co
             return {.status = eGroupedTestModesetStatus::FRAMEBUFFER_UNAVAILABLE};
         }
 
+        const auto& FRAMEBUFFER_OWNER = replacement->targetFramebufferOwner();
+        const auto  LIFETIME          = SNAPSHOT->device()->backend().lock();
+        if (!FRAMEBUFFER_OWNER || !LIFETIME || FRAMEBUFFER_OWNER->dead() || !sameOwner(FRAMEBUFFER_OWNER->generationOwner(), current) ||
+            !sameOwner(FRAMEBUFFER_OWNER->backend(), LIFETIME) || FRAMEBUFFER_OWNER->framebuffer() != ROUTE->framebuffer() || ROUTE->framebuffer() != m_testFramebuffer->atomic)
+            return {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+        if (LIFETIME->binding() == eBackendBinding::PRODUCTION_BACKEND &&
+            (!sameOwner(FRAMEBUFFER_OWNER->drmFramebuffer(), m_testFramebuffer->framebuffer) || !sameOwner(FRAMEBUFFER_OWNER->buffer(), m_testFramebuffer->buffer)))
+            return {.status = eGroupedTestModesetStatus::ROUTE_INVALID, .routeError = eTiledAtomicError::FRAMEBUFFER_MISMATCH};
+
         SGroupedTestModesetResult result;
         result.cleanup = m_testCleanupRegistry->retryPending();
         if (!result.cleanup.complete()) {
@@ -416,20 +428,8 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModeset(co
             return result;
         }
 
-        const auto RESOLVED = resolveCapturedTiledAtomic({
-            .generationOwner    = current,
-            .groupDefinition    = group,
-            .definitionIdentity = GROUP->definitionIdentity(),
-            .outputMode         = outputMode,
-            .framebuffer        = m_testFramebuffer->atomic,
-        });
-        result.routeError   = RESOLVED.error;
-        if (!RESOLVED) {
-            result.status = eGroupedTestModesetStatus::ROUTE_INVALID;
-            return result;
-        }
-
-        const auto EXECUTION   = executeTiledTestModeset(RESOLVED.route, m_testDrmFD, m_testOperations, m_testCleanupRegistry);
+        result.routeError      = eTiledAtomicError::NONE;
+        const auto EXECUTION   = executeTiledTestModeset(replacement, m_testDrmFD, m_testOperations, m_testCleanupRegistry);
         result.executionStatus = EXECUTION.status;
         result.submission      = EXECUTION.submission;
         result.cleanup         = EXECUTION.cleanup;
@@ -446,10 +446,10 @@ SGroupedTestModesetResult CGroupedRuntimeAuthority::executeCurrentTestModeset(co
     } catch (...) { return {.status = eGroupedTestModesetStatus::ALLOCATION_FAILED}; }
 }
 
-SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
-                                                                          const CSharedPointer<SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
-                                                                          const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
-                                                                          uint64_t deadlineNs) noexcept {
+SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const POutputBridgeObservation& current, const PResolvedTiledAtomicReplacement& replacement,
+                                                                          const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
+                                                                          const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                          const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) noexcept {
     if (!onEventThread())
         return {.status = eGroupedInitialFrameStatus::WRONG_THREAD};
     if (m_mutationActive)
@@ -458,7 +458,7 @@ SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const
         return {.status = eGroupedInitialFrameStatus::TERMINAL};
     if (!m_testDevice || m_testDrmFD < 0 || !m_testOperations || !m_testCleanupRegistry || m_testCleanupRegistry->drmFD() != m_testDrmFD)
         return {.status = eGroupedInitialFrameStatus::NOT_CONFIGURED};
-    if (!current || !group || !outputMode || transactionId == 0 || deadlineNs == 0)
+    if (!current || !replacement || !group || !outputMode || transactionId == 0 || deadlineNs == 0)
         return {.status = eGroupedInitialFrameStatus::INVALID_CURRENT};
     if (!publication)
         return {.status = eGroupedInitialFrameStatus::INVALID_PUBLICATION};
@@ -467,12 +467,15 @@ SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const
 
     m_mutationActive = true;
     Hyprutils::Utils::CScopeGuard mutationGuard([&] { m_mutationActive = false; });
+    bool                          preacceptInvariantFailure = false;
     try {
+        const auto& ROUTE    = replacement->targetRoute();
         const auto& SNAPSHOT = current->capturedSnapshot();
         const auto* GROUP    = current->findGroup(group);
         const auto  LIFETIME = m_testDevice->backend().lock();
         const auto  BACKEND  = m_testBackend.lock();
-        if (!SNAPSHOT || !sameOwner(SNAPSHOT->device(), m_testDevice) || !GROUP || !sameOwner(GROUP->scanDefinition(), group) ||
+        if (!SNAPSHOT || !sameOwner(SNAPSHOT->device(), m_testDevice) || !GROUP || !sameOwner(GROUP->scanDefinition(), group) || !exactCurrentRoute(current, ROUTE) ||
+            !sameOwner(ROUTE->groupDefinition(), group) || !sameOwner(ROUTE->definitionIdentity(), GROUP->definitionIdentity()) || !sameOwner(ROUTE->outputMode(), outputMode) ||
             GROUP->projection() != eGroupProjection::MULTI_STREAM_ALLOCATED || !GROUP->definitionIdentity() ||
             !sameOwner(publication->definitionIdentity(), GROUP->definitionIdentity()) || !LIFETIME || LIFETIME->binding() != eBackendBinding::PRODUCTION_BACKEND || !BACKEND ||
             BACKEND->drmFD() != m_testDrmFD || LIFETIME->drmBackend().impl_ != m_testBackend.impl_)
@@ -500,75 +503,110 @@ SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const
             .format   = ATTRS.format,
             .modifier = ATTRS.modifier,
         };
-        const auto RESOLVED = resolveCapturedTiledAtomic({
-            .generationOwner    = current,
-            .groupDefinition    = group,
-            .definitionIdentity = GROUP->definitionIdentity(),
-            .outputMode         = outputMode,
-            .framebuffer        = ATOMIC_FRAMEBUFFER,
-        });
-        result.routeError   = RESOLVED.error;
-        if (!RESOLVED) {
-            result.status = eGroupedInitialFrameStatus::ROUTE_INVALID;
+        const auto& TARGET_FRAMEBUFFER = replacement->targetFramebufferOwner();
+        if (!TARGET_FRAMEBUFFER || TARGET_FRAMEBUFFER->dead() || !sameOwner(TARGET_FRAMEBUFFER->generationOwner(), current) ||
+            !sameOwner(TARGET_FRAMEBUFFER->backend(), LIFETIME) || !sameOwner(TARGET_FRAMEBUFFER->drmFramebuffer(), framebuffer) ||
+            !sameOwner(TARGET_FRAMEBUFFER->buffer(), buffer) || TARGET_FRAMEBUFFER->framebuffer() != ATOMIC_FRAMEBUFFER || ROUTE->framebuffer() != ATOMIC_FRAMEBUFFER) {
+            result.routeError = eTiledAtomicError::FRAMEBUFFER_MISMATCH;
+            result.status     = eGroupedInitialFrameStatus::ROUTE_INVALID;
             return result;
         }
+        result.routeError = eTiledAtomicError::NONE;
 
-        result.stageResult = stageRecord(current, RESOLVED.route);
+        result.stageResult = stageRecord(current, ROUTE);
         auto* const RECORD = recordFor(GROUP->definitionIdentity());
         if (!RECORD || !RECORD->runtime || !RECORD->activeRoute || !synchronizeRoute(*RECORD)) {
             result.status = eGroupedInitialFrameStatus::RUNTIME_STAGE_FAILED;
             return result;
         }
-        if (RECORD->runtime->state() == eTiledRuntimeState::STAGED && !RECORD->runtime->publishDisabled()) {
-            result.status = eGroupedInitialFrameStatus::RUNTIME_STAGE_FAILED;
-            return result;
+        bool attemptSettled = false;
+        if (RECORD->runtime->state() == eTiledRuntimeState::STAGED) {
+            if (!RECORD->runtime->armInitialAttempt()) {
+                result.status = eGroupedInitialFrameStatus::RUNTIME_STAGE_FAILED;
+                return result;
+            }
+            result.runtimeAttemptArmed = true;
         }
+        const auto ROLLBACK_ATTEMPT = [&]() noexcept -> bool {
+            if (!attemptSettled && result.runtimeAttemptArmed) {
+                result.runtimeAttemptRolledBack = RECORD->runtime->rollbackInitialAttempt();
+                attemptSettled                  = true;
+                if (!result.runtimeAttemptRolledBack) {
+                    preacceptInvariantFailure = true;
+                    return false;
+                }
+            }
+            return true;
+        };
+        Hyprutils::Utils::CScopeGuard attemptGuard([&] { static_cast<void>(ROLLBACK_ATTEMPT()); });
         if (RECORD->runtime->state() != eTiledRuntimeState::PUBLISHED_DISABLED || RECORD->runtime->preparedRoute() || !RECORD->runtime->currentFrames().empty() ||
-            !RESOLVED.route->matchesRuntimePlan(RECORD->runtime->activePlan())) {
-            result.status = eGroupedInitialFrameStatus::RUNTIME_STAGE_FAILED;
+            !ROUTE->matchesRuntimePlan(RECORD->runtime->activePlan())) {
+            result.status = ROLLBACK_ATTEMPT() ? eGroupedInitialFrameStatus::RUNTIME_STAGE_FAILED : eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE;
             return result;
         }
-        RECORD->activeRoute = RESOLVED.route;
+        RECORD->activeRoute = ROUTE;
 
-        const auto BUILT    = buildTiledModesetRequest(RESOLVED.route, m_testDrmFD, m_testOperations, m_testCleanupRegistry);
+        const auto BUILT    = buildTiledModesetRequest(replacement, m_testDrmFD, m_testOperations, m_testCleanupRegistry);
         result.requestError = BUILT.error;
         if (!BUILT) {
-            result.cleanup = BUILT.cleanup;
-            result.status  = result.cleanup.complete() ? eGroupedInitialFrameStatus::REQUEST_BUILD_FAILED : eGroupedInitialFrameStatus::CLEANUP_PENDING;
+            result.cleanup         = BUILT.cleanup;
+            const auto ROLLED_BACK = ROLLBACK_ATTEMPT();
+            result.status          = !ROLLED_BACK ? eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE :
+                result.cleanup.complete()         ? eGroupedInitialFrameStatus::REQUEST_BUILD_FAILED :
+                                                    eGroupedInitialFrameStatus::CLEANUP_PENDING;
             return result;
         }
 
         const auto MAKE_OWNER = [&](eGroupedFrameOwnerRole role, const CSharedPointer<CDRMFB>& retainedFramebuffer,
                                     const CSharedPointer<IBuffer>& retainedBuffer) -> PGroupedFrameOwner {
-            CSharedPointer<CGroupedFrameOwner>       mutableOwner{new CGroupedFrameOwner{role, RESOLVED.route, publication, retainedFramebuffer, retainedBuffer}};
+            CSharedPointer<CGroupedFrameOwner>       mutableOwner{new CGroupedFrameOwner{role, ROUTE, publication, retainedFramebuffer, retainedBuffer}};
             CSharedPointer<const CGroupedFrameOwner> retained = mutableOwner;
             return PGroupedFrameOwner{std::move(retained)};
         };
         const auto FRAMEBUFFER_OWNER = MAKE_OWNER(eGroupedFrameOwnerRole::FRAMEBUFFER, framebuffer, {});
         const auto BUFFER_OWNER      = MAKE_OWNER(eGroupedFrameOwnerRole::BUFFER, {}, buffer);
         const auto BUFFER_ID         = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(buffer.impl_));
-        if (!FRAMEBUFFER_OWNER || !BUFFER_OWNER || BUFFER_ID == 0 || !publication->arm(transactionId)) {
+        if (!FRAMEBUFFER_OWNER || !BUFFER_OWNER || BUFFER_ID == 0) {
             result.cleanup = BUILT.prepared->cleanup();
-            result.status  = eGroupedInitialFrameStatus::INVALID_PUBLICATION;
+            result.status  = ROLLBACK_ATTEMPT() ? eGroupedInitialFrameStatus::INVALID_FRAMEBUFFER : eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE;
             return result;
         }
+        bool publicationArmed = publication->arm(transactionId);
+        if (!publicationArmed) {
+            result.cleanup = BUILT.prepared->cleanup();
+            result.status  = ROLLBACK_ATTEMPT() ? eGroupedInitialFrameStatus::INVALID_PUBLICATION : eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE;
+            return result;
+        }
+        bool                          kmsAccepted = false;
+        Hyprutils::Utils::CScopeGuard publicationGuard([&] {
+            if (publicationArmed && !kmsAccepted && !publication->rollback(transactionId)) {
+                preacceptInvariantFailure = true;
+            }
+        });
 
-        auto       transaction  = submitInitialTiledFrameTransaction(BUILT.prepared, *RECORD->runtime, m_reservations,
-                                                                     {
-                                                                         .framebufferId    = framebuffer->id,
-                                                                         .bufferId         = BUFFER_ID,
-                                                                         .framebufferOwner = FRAMEBUFFER_OWNER,
-                                                                         .bufferOwner      = BUFFER_OWNER,
-                                                                     },
-                                                                     transactionId, deadlineNs, m_testDrmFD);
-        const bool KMS_ACCEPTED = transaction.effects.kmsAccepted;
-        if (!KMS_ACCEPTED) {
-            static_cast<void>(publication->rollback(transactionId));
-            result.transaction = transaction;
-            result.cleanup     = BUILT.prepared->cleanup();
-            result.status      = eGroupedInitialFrameStatus::TRANSACTION_FAILED;
+        auto                          transaction = submitInitialTiledFrameTransaction(BUILT.prepared, *RECORD->runtime, m_reservations,
+                                                                                       {
+                                                                                           .framebufferId    = framebuffer->id,
+                                                                                           .bufferId         = BUFFER_ID,
+                                                                                           .framebufferOwner = FRAMEBUFFER_OWNER,
+                                                                                           .bufferOwner      = BUFFER_OWNER,
+                                                                                       },
+                                                                                       transactionId, deadlineNs, m_testDrmFD);
+        kmsAccepted                               = transaction.effects.kmsAccepted;
+        if (!kmsAccepted) {
+            const bool PUBLICATION_ROLLED_BACK = publication->rollback(transactionId);
+            publicationArmed                   = false;
+            result.transaction                 = transaction;
+            result.cleanup                     = BUILT.prepared->cleanup();
+            const bool ATTEMPT_ROLLED_BACK     = ROLLBACK_ATTEMPT();
+            if (!PUBLICATION_ROLLED_BACK) {
+                preacceptInvariantFailure = true;
+            }
+            result.status =
+                PUBLICATION_ROLLED_BACK && ATTEMPT_ROLLED_BACK ? eGroupedInitialFrameStatus::TRANSACTION_FAILED : eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE;
             return result;
         }
+        attemptSettled = true;
 
         buffer->lockedByBackend         = true;
         result.bufferLocked             = true;
@@ -585,7 +623,7 @@ SGroupedInitialFrameResult CGroupedRuntimeAuthority::submitInitialCurrent(const
         result.status                 = PUBLICATION_ACCEPTED && TRANSACTION_STATUS == eTiledFrameTransactionStatus::ACCEPTED ? eGroupedInitialFrameStatus::ACCEPTED :
                                                                                                                                eGroupedInitialFrameStatus::ACCEPTED_INVARIANT_FAILURE;
         return result;
-    } catch (...) { return {.status = eGroupedInitialFrameStatus::ALLOCATION_FAILED}; }
+    } catch (...) { return {.status = preacceptInvariantFailure ? eGroupedInitialFrameStatus::PREACCEPT_INVARIANT_FAILURE : eGroupedInitialFrameStatus::ALLOCATION_FAILED}; }
 }
 
 bool CGroupedRuntimeAuthority::prepareTestModesetDetach() noexcept {
diff --git a/src/backend/drm/TiledRuntimeAuthority.hpp b/src/backend/drm/TiledRuntimeAuthority.hpp
index 77be9f997bc536aed435f576b1616b4e6aaf2e95..b0144763e77ec2952d98598aea5668e69d70a916 100644
--- a/src/backend/drm/TiledRuntimeAuthority.hpp
+++ b/src/backend/drm/TiledRuntimeAuthority.hpp
@@ -39,6 +39,7 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
     using NTiledAtomic::ITiledAtomicRequestOperations;
     using NTiledAtomic::STiledAtomicFramebuffer;
     using NTiledAtomic::STiledModeBlobCleanupOutcome;
+    using NTiledAtomic::PResolvedTiledAtomicReplacement;
     using NTiledAtomic::PResolvedTiledAtomicRoute;
     using NTiledIncarnations::PDeviceIncarnation;
     using NTiledOutputBridge::POutputBridgeObservation;
@@ -60,26 +61,26 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
     // while retaining the old KMS FB for the runtime's last-frame lifetime.
     class AQ_TILED_RUNTIME_AUTHORITY_PRIVATE CGroupedFrameOwner final {
       public:
-        CGroupedFrameOwner(const CGroupedFrameOwner&)                                       = delete;
-        CGroupedFrameOwner(CGroupedFrameOwner&&)                                            = delete;
-        CGroupedFrameOwner&                            operator=(const CGroupedFrameOwner&) = delete;
-        CGroupedFrameOwner&                            operator=(CGroupedFrameOwner&&)      = delete;
+        CGroupedFrameOwner(const CGroupedFrameOwner&)                                         = delete;
+        CGroupedFrameOwner(CGroupedFrameOwner&&)                                              = delete;
+        CGroupedFrameOwner&                              operator=(const CGroupedFrameOwner&) = delete;
+        CGroupedFrameOwner&                              operator=(CGroupedFrameOwner&&)      = delete;
 
         [[nodiscard]] eGroupedFrameOwnerRole             role() const noexcept;
-        [[nodiscard]] const PResolvedTiledAtomicRoute& route() const noexcept;
+        [[nodiscard]] const PResolvedTiledAtomicRoute&   route() const noexcept;
         [[nodiscard]] const PGroupedPublicationInstance& publication() const noexcept;
-        [[nodiscard]] const CSharedPointer<CDRMFB>&    framebuffer() const noexcept;
-        [[nodiscard]] const CSharedPointer<IBuffer>&   buffer() const noexcept;
+        [[nodiscard]] const CSharedPointer<CDRMFB>&      framebuffer() const noexcept;
+        [[nodiscard]] const CSharedPointer<IBuffer>&     buffer() const noexcept;
 
       private:
         CGroupedFrameOwner(eGroupedFrameOwnerRole role, PResolvedTiledAtomicRoute route, PGroupedPublicationInstance publication, CSharedPointer<CDRMFB> framebuffer,
                            CSharedPointer<IBuffer> buffer) noexcept;
 
         eGroupedFrameOwnerRole      m_role = eGroupedFrameOwnerRole::FRAMEBUFFER;
-        PResolvedTiledAtomicRoute m_route;
+        PResolvedTiledAtomicRoute   m_route;
         PGroupedPublicationInstance m_publication;
-        CSharedPointer<CDRMFB>    m_framebuffer;
-        CSharedPointer<IBuffer>   m_buffer;
+        CSharedPointer<CDRMFB>      m_framebuffer;
+        CSharedPointer<IBuffer>     m_buffer;
 
         friend class CGroupedRuntimeAuthority;
         friend class ::Aquamarine::NDRM::NTiledRuntimeAuthorityTest::CFixtureAuthority;
@@ -232,7 +233,7 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
         POutputDefinitionIdentity   definitionIdentity;
         PResolvedTiledAtomicRoute   route;
         PGroupedPublicationInstance publication;
-        bool                        reservationRetired = false;
+        bool                        reservationRetired  = false;
         bool                        completionDelivered = false;
         size_t                      releasesDelivered   = 0;
         bool                        successorAdopted    = false;
@@ -254,6 +255,7 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
         RUNTIME_STAGE_FAILED,
         REQUEST_BUILD_FAILED,
         TRANSACTION_FAILED,
+        PREACCEPT_INVARIANT_FAILURE,
         ALLOCATION_FAILED,
     };
 
@@ -264,8 +266,10 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
         eGroupedStageResult                        stageResult  = eGroupedStageResult::INVALID_CURRENT;
         NTiledAtomic::STiledFrameTransactionResult transaction;
         STiledModeBlobCleanupOutcome               cleanup;
-        bool                                       bufferLocked          = false;
-        bool                                       submitEffectDelivered = false;
+        bool                                       bufferLocked             = false;
+        bool                                       submitEffectDelivered    = false;
+        bool                                       runtimeAttemptArmed      = false;
+        bool                                       runtimeAttemptRolledBack = false;
 
         explicit                                   operator bool() const noexcept;
     };
@@ -363,26 +367,26 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
         explicit CGroupedRuntimeAuthority(std::thread::id eventThread = std::this_thread::get_id());
         ~CGroupedRuntimeAuthority() noexcept;
 
-        CGroupedRuntimeAuthority(const CGroupedRuntimeAuthority&)                         = delete;
-        CGroupedRuntimeAuthority(CGroupedRuntimeAuthority&&)                              = delete;
-        CGroupedRuntimeAuthority&              operator=(const CGroupedRuntimeAuthority&) = delete;
-        CGroupedRuntimeAuthority&              operator=(CGroupedRuntimeAuthority&&)      = delete;
+        CGroupedRuntimeAuthority(const CGroupedRuntimeAuthority&)                           = delete;
+        CGroupedRuntimeAuthority(CGroupedRuntimeAuthority&&)                                = delete;
+        CGroupedRuntimeAuthority&                operator=(const CGroupedRuntimeAuthority&) = delete;
+        CGroupedRuntimeAuthority&                operator=(CGroupedRuntimeAuthority&&)      = delete;
 
-        [[nodiscard]] eGroupedStageResult      stageCurrent(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) noexcept;
-        [[nodiscard]] SGroupedReconcileResult  reconcileCurrent(const POutputBridgeObservation& current) noexcept;
-        [[nodiscard]] SGroupedInitialFrameResult submitInitialCurrent(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
-                                                                      const CSharedPointer<SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
-                                                                      const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
-                                                                      uint64_t deadlineNs) noexcept;
-        [[nodiscard]] SOrdinaryKMSGateResult   gateOrdinaryKMS(std::span<const SOrdinaryKMSCRTC> crtcs, const std::function<bool()>& callback) noexcept;
-        [[nodiscard]] SGroupedPageFlipResult   routePageFlip(uintptr_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept;
-        [[nodiscard]] SGroupedQuiesceResult    quiesceAll(eTiledQuiesceReason reason) noexcept;
-        [[nodiscard]] SGroupedRetirementResult retire(const POutputDefinitionIdentity& identity, eTiledRetirementProof proof) noexcept;
+        [[nodiscard]] eGroupedStageResult        stageCurrent(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) noexcept;
+        [[nodiscard]] SGroupedReconcileResult    reconcileCurrent(const POutputBridgeObservation& current) noexcept;
+        [[nodiscard]] SGroupedInitialFrameResult submitInitialCurrent(const POutputBridgeObservation& current, const PResolvedTiledAtomicReplacement& replacement,
+                                                                      const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode,
+                                                                      const PGroupedPublicationInstance& publication, const CSharedPointer<CDRMFB>& framebuffer,
+                                                                      const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) noexcept;
+        [[nodiscard]] SOrdinaryKMSGateResult     gateOrdinaryKMS(std::span<const SOrdinaryKMSCRTC> crtcs, const std::function<bool()>& callback) noexcept;
+        [[nodiscard]] SGroupedPageFlipResult     routePageFlip(uintptr_t transactionId, uint32_t crtcId, uint32_t sequence, uint64_t timestampNs) noexcept;
+        [[nodiscard]] SGroupedQuiesceResult      quiesceAll(eTiledQuiesceReason reason) noexcept;
+        [[nodiscard]] SGroupedRetirementResult   retire(const POutputDefinitionIdentity& identity, eTiledRetirementProof proof) noexcept;
 
-        [[nodiscard]] bool                     terminalShutdown(eTiledRegistryShutdownProof registryProof, eTiledRetirementProof runtimeProof) noexcept;
-        [[nodiscard]] bool                     busy() const noexcept;
-        [[nodiscard]] bool                     readyForDestruction() const noexcept;
-        [[nodiscard]] size_t                   runtimeCount() const noexcept;
+        [[nodiscard]] bool                       terminalShutdown(eTiledRegistryShutdownProof registryProof, eTiledRetirementProof runtimeProof) noexcept;
+        [[nodiscard]] bool                       busy() const noexcept;
+        [[nodiscard]] bool                       readyForDestruction() const noexcept;
+        [[nodiscard]] size_t                     runtimeCount() const noexcept;
 
       private:
         struct SCompletionDebt {
@@ -406,22 +410,22 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthority { // NOLINT(readability-ident
 
         using TRuntimeMap = std::map<const void*, SRuntimeRecord>;
 
-        [[nodiscard]] bool                     onEventThread() const noexcept;
-        [[nodiscard]] bool                     exactCurrentRoute(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) const noexcept;
-        [[nodiscard]] eGroupedStageResult      stageRecord(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route);
-        [[nodiscard]] bool                     applyReservationEffects(const CGroupedRuntime::SEffects& effects) noexcept;
-        [[nodiscard]] bool                     synchronizeRoute(SRuntimeRecord& record) noexcept;
+        [[nodiscard]] bool                            onEventThread() const noexcept;
+        [[nodiscard]] bool                            exactCurrentRoute(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) const noexcept;
+        [[nodiscard]] eGroupedStageResult             stageRecord(const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route);
+        [[nodiscard]] bool                            applyReservationEffects(const CGroupedRuntime::SEffects& effects) noexcept;
+        [[nodiscard]] bool                            synchronizeRoute(SRuntimeRecord& record) noexcept;
         [[nodiscard]] eGroupedCompletionConsumeResult consumeCompletionDebt(SRuntimeRecord& record, SGroupedPageFlipResult& result) noexcept;
-        [[nodiscard]] bool                     claimsPageFlip(uintptr_t transactionId, uint32_t crtcId) const noexcept;
-        [[nodiscard]] SGroupedQuiesceResult    quiesceAllUnguarded(eTiledQuiesceReason reason) noexcept;
-        [[nodiscard]] SGroupedRetirementResult retireUnguarded(SRuntimeRecord& record, eTiledRetirementProof proof);
-        [[nodiscard]] SRuntimeRecord*          recordFor(const POutputDefinitionIdentity& identity) noexcept;
-        [[nodiscard]] const SRuntimeRecord*    recordFor(const POutputDefinitionIdentity& identity) const noexcept;
-        [[nodiscard]] bool                     configureProductionTestModeset(const PDeviceIncarnation& device, const CWeakPointer<CDRMBackend>& backend, int drmFD) noexcept;
+        [[nodiscard]] bool                            claimsPageFlip(uintptr_t transactionId, uint32_t crtcId) const noexcept;
+        [[nodiscard]] SGroupedQuiesceResult           quiesceAllUnguarded(eTiledQuiesceReason reason) noexcept;
+        [[nodiscard]] SGroupedRetirementResult        retireUnguarded(SRuntimeRecord& record, eTiledRetirementProof proof);
+        [[nodiscard]] SRuntimeRecord*                 recordFor(const POutputDefinitionIdentity& identity) noexcept;
+        [[nodiscard]] const SRuntimeRecord*           recordFor(const POutputDefinitionIdentity& identity) const noexcept;
+        [[nodiscard]] bool configureProductionTestModeset(const PDeviceIncarnation& device, const CWeakPointer<CDRMBackend>& backend, int drmFD) noexcept;
         [[nodiscard]] bool configureInjectedTestModeset(const PDeviceIncarnation& device, int drmFD, const CSharedPointer<ITiledAtomicRequestOperations>& operations,
                                                         const CSharedPointer<IGroupedTestFramebufferSource>& framebufferSource) noexcept;
-        [[nodiscard]] SGroupedTestModesetResult       executeCurrentTestModeset(const POutputBridgeObservation& current, const PScanGroupDefinition& group,
-                                                                                const CSharedPointer<SOutputMode>& outputMode) noexcept;
+        [[nodiscard]] SGroupedTestModesetResult       executeCurrentTestModeset(const POutputBridgeObservation& current, const PResolvedTiledAtomicReplacement& replacement,
+                                                                                const PScanGroupDefinition& group, const CSharedPointer<SOutputMode>& outputMode) noexcept;
         [[nodiscard]] bool                            prepareTestModesetDetach() noexcept;
         [[nodiscard]] bool                            validTestFramebuffer(const PGroupedTestFramebuffer& framebuffer, const SPlaneFramebufferSize& size,
                                                                            std::span<const SDRMFormat> commonFormats) const noexcept;
diff --git a/tests/TiledAtomic.cpp b/tests/TiledAtomic.cpp
index 0a83eb41d2b0163deede0854c8a18a50e0650f8d..1b92d627a9ebc1b5507e85ff320b599d9f964287 100644
--- a/tests/TiledAtomic.cpp
+++ b/tests/TiledAtomic.cpp
@@ -151,6 +151,16 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
             return resource;
         }
 
+        static PAtomicFramebufferOwner framebufferOwner(const POutputBridgeObservation& generation, const CSharedPointer<CDRMFB>& framebuffer,
+                                                        const CSharedPointer<IBuffer>& buffer, STiledAtomicFramebuffer metadata, bool dead = false) {
+            return CTiledAtomicFramebufferOwner::createFixture(generation, framebuffer, buffer, metadata, dead);
+        }
+
+        static PAtomicPlaneInventory planeInventory(const POutputBridgeObservation& generation, std::vector<STiledPlaneInventoryResource> resources,
+                                                    std::vector<STiledPlaneInventoryState> states) {
+            return CTiledAtomicPlaneInventory::create(generation, std::move(resources), std::move(states));
+        }
+
         static PGroupedFrameOwner owner(eGroupedFrameOwnerRole role, const PResolvedTiledAtomicRoute& route, const PGroupedPublicationInstance& publication,
                                         const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer) {
             CSharedPointer<CGroupedFrameOwner>       mutableOwner{new CGroupedFrameOwner{role, route, publication, framebuffer, buffer}};
@@ -267,6 +277,40 @@ namespace Aquamarine::NDRM::NTiledRuntimeAuthorityTest {
             return RECORD && RECORD->runtime ? RECORD->runtime->activePlan().generation : 0;
         }
 
+        static bool armInitialAttempt(CGroupedRuntimeAuthority& authority, const POutputDefinitionIdentity& identity) {
+            auto* const RECORD = authority.recordFor(identity);
+            return RECORD && RECORD->runtime && RECORD->runtime->armInitialAttempt();
+        }
+
+        static bool rollbackInitialAttempt(CGroupedRuntimeAuthority& authority, const POutputDefinitionIdentity& identity) {
+            auto* const RECORD = authority.recordFor(identity);
+            return RECORD && RECORD->runtime && RECORD->runtime->rollbackInitialAttempt();
+        }
+
+        static eTiledRuntimeState runtimeState(CGroupedRuntimeAuthority& authority, const POutputDefinitionIdentity& identity) {
+            const auto* RECORD = authority.recordFor(identity);
+            return RECORD && RECORD->runtime ? RECORD->runtime->state() : eTiledRuntimeState::TEARDOWN;
+        }
+
+        static STiledFrameTransactionResult submitInitialAttempt(CGroupedRuntimeAuthority& authority, const POutputDefinitionIdentity& identity,
+                                                                 const PPreparedTiledModesetRequest& prepared, const PGroupedPublicationInstance& publication,
+                                                                 const CSharedPointer<CDRMFB>& framebuffer, const CSharedPointer<IBuffer>& buffer, uintptr_t transactionId,
+                                                                 uint64_t deadlineNs, int drmFD) {
+            auto* const RECORD = authority.recordFor(identity);
+            if (!RECORD || !RECORD->runtime || !RECORD->activeRoute || !prepared || !publication || !framebuffer || !buffer)
+                return {};
+            const auto FRAMEBUFFER_OWNER = owner(eGroupedFrameOwnerRole::FRAMEBUFFER, RECORD->activeRoute, publication, framebuffer, {});
+            const auto BUFFER_OWNER      = owner(eGroupedFrameOwnerRole::BUFFER, RECORD->activeRoute, publication, {}, buffer);
+            return submitInitialTiledFrameTransaction(prepared, *RECORD->runtime, authority.m_reservations,
+                                                      {
+                                                          .framebufferId    = RECORD->activeRoute->framebuffer().id,
+                                                          .bufferId         = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(buffer.impl_)),
+                                                          .framebufferOwner = FRAMEBUFFER_OWNER,
+                                                          .bufferOwner      = BUFFER_OWNER,
+                                                      },
+                                                      transactionId, deadlineNs, drmFD);
+        }
+
         static eGroupedStageResult nestedStage(CGroupedRuntimeAuthority& authority, const POutputBridgeObservation& current, const PResolvedTiledAtomicRoute& route) {
             authority.m_mutationActive = true;
             const auto RESULT          = authority.stageCurrent(current, route);
@@ -444,6 +488,8 @@ namespace {
     struct SRecorder final : ITiledAtomicRequestOperations {
         drmModeAtomicReqPtr allocateRequest() noexcept override {
             ++allocations;
+            if (failAllocation)
+                return nullptr;
             // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): opaque fake request identity for the injected test boundary
             return reinterpret_cast<drmModeAtomicReqPtr>(this);
         }
@@ -502,6 +548,7 @@ namespace {
         size_t                       failPropertyAt           = static_cast<size_t>(-1);
         size_t                       destroyFailuresRemaining = 0;
         bool                         duplicateBlob            = false;
+        bool                         failAllocation           = false;
         uint32_t                     nextBlob                 = 900;
         int                          submitResult             = 0;
         int                          submitErrno              = 0;
@@ -539,6 +586,11 @@ namespace {
         append(member.primaryPlaneId, PLANE.crtcH, VIEWPORT.crtcH);
     }
 
+    void sortExpected(std::vector<SPropertyWrite>& expected) {
+        std::ranges::sort(expected,
+                          [](const auto& lhs, const auto& rhs) { return std::tie(lhs.objectId, lhs.propertyId, lhs.value) < std::tie(rhs.objectId, rhs.propertyId, rhs.value); });
+    }
+
     struct SForeignIdentityCarrier {};
 
     struct SFrameOwner {
@@ -703,10 +755,30 @@ namespace {
 }
 
 int main() {
-    const auto         backend = CBackendLifetime::createTestToken(1);
-    const auto         device  = CDeviceIncarnation::create(backend, 900, 9, 27, 2);
-    const auto         session = CSessionIncarnation::create(backend, device, std::this_thread::get_id(), 17, 1, 3);
-    SResources         resources;
+    const auto backend = CBackendLifetime::createTestToken(1);
+    const auto device  = CDeviceIncarnation::create(backend, 900, 9, 27, 2);
+    const auto session = CSessionIncarnation::create(backend, device, std::this_thread::get_id(), 17, 1, 3);
+    SResources resources;
+    auto       displacedCrtc               = makeShared<SDRMCRTC>();
+    displacedCrtc->id                      = 103;
+    displacedCrtc->props.values.mode_id    = 2'020;
+    displacedCrtc->props.values.active     = 2'021;
+    auto displacedPrimary                  = makeShared<SDRMPlane>();
+    displacedPrimary->id                   = 203;
+    displacedPrimary->type                 = DRM_PLANE_TYPE_PRIMARY;
+    displacedPrimary->formats              = {{.drmFormat = DRM_FORMAT_XRGB8888, .modifiers = {DRM_FORMAT_MOD_LINEAR}}};
+    displacedPrimary->props.values.fb_id   = 3'040;
+    displacedPrimary->props.values.crtc_id = 3'041;
+    displacedPrimary->props.values.src_x   = 3'042;
+    displacedPrimary->props.values.src_y   = 3'043;
+    displacedPrimary->props.values.src_w   = 3'044;
+    displacedPrimary->props.values.src_h   = 3'045;
+    displacedPrimary->props.values.crtc_x  = 3'046;
+    displacedPrimary->props.values.crtc_y  = 3'047;
+    displacedPrimary->props.values.crtc_w  = 3'048;
+    displacedPrimary->props.values.crtc_h  = 3'049;
+    resources.crtcs.push_back(displacedCrtc);
+    resources.planes.push_back(displacedPrimary);
     const auto         scan     = CScanFixtureAuthority::mint(session, {1, 2}, tiledGroup(device->deviceId()), 10);
     const auto         snapshot = snapshotFor(scan, resources, 41);
     const auto         plan     = planFor(snapshot);
@@ -787,6 +859,185 @@ int main() {
     CHECK(runtimePlan.crtcIds == std::vector<uint32_t>(resolved.route->crtcIds().begin(), resolved.route->crtcIds().end()));
     CHECK(runtimePlan.memberRoutes.size() == resolved.route->members().size());
 
+    PResolvedTiledAtomicReplacement replacement;
+    {
+        const auto& REUSED_MEMBER          = resolved.route->members().back();
+        const auto  targetFramebuffer      = CFixtureAuthority::opaqueResource<CDRMFB>();
+        const auto  targetBuffer           = CFixtureAuthority::opaqueResource<IBuffer>();
+        const auto  targetFramebufferOwner = CFixtureAuthority::framebufferOwner(installed, targetFramebuffer, targetBuffer, input.framebuffer);
+        CHECK(static_cast<bool>(targetFramebufferOwner));
+
+        auto       oldFramebuffer      = CFixtureAuthority::opaqueResource<CDRMFB>();
+        auto       oldBuffer           = CFixtureAuthority::opaqueResource<IBuffer>();
+        auto       reusedFramebuffer   = CFixtureAuthority::opaqueResource<CDRMFB>();
+        auto       reusedBuffer        = CFixtureAuthority::opaqueResource<IBuffer>();
+        auto       cursorFramebuffer   = CFixtureAuthority::opaqueResource<CDRMFB>();
+        auto       cursorBuffer        = CFixtureAuthority::opaqueResource<IBuffer>();
+        auto       overlayFramebuffer  = CFixtureAuthority::opaqueResource<CDRMFB>();
+        auto       overlayBuffer       = CFixtureAuthority::opaqueResource<IBuffer>();
+        const auto framebufferMetadata = [](uint32_t id) {
+            return STiledAtomicFramebuffer{
+                .id       = id,
+                .size     = {.width = 64, .height = 64},
+                .format   = DRM_FORMAT_XRGB8888,
+                .modifier = DRM_FORMAT_MOD_LINEAR,
+            };
+        };
+        const auto oldFramebufferOwner     = CFixtureAuthority::framebufferOwner(installed, oldFramebuffer, oldBuffer, framebufferMetadata(8'002));
+        const auto reusedFramebufferOwner  = CFixtureAuthority::framebufferOwner(installed, reusedFramebuffer, reusedBuffer, framebufferMetadata(8'001));
+        const auto cursorFramebufferOwner  = CFixtureAuthority::framebufferOwner(installed, cursorFramebuffer, cursorBuffer, framebufferMetadata(8'003));
+        const auto overlayFramebufferOwner = CFixtureAuthority::framebufferOwner(installed, overlayFramebuffer, overlayBuffer, framebufferMetadata(8'004));
+        CHECK(oldFramebufferOwner && reusedFramebufferOwner && cursorFramebufferOwner && overlayFramebufferOwner);
+
+        displacedPrimary->front           = oldFramebuffer;
+        displacedCrtc->primary            = displacedPrimary;
+        REUSED_MEMBER.primaryPlane->front = reusedFramebuffer;
+        REUSED_MEMBER.crtc->primary       = REUSED_MEMBER.primaryPlane;
+
+        auto cursor                  = makeShared<SDRMPlane>();
+        cursor->id                   = 301;
+        cursor->type                 = DRM_PLANE_TYPE_CURSOR;
+        cursor->props.values.fb_id   = 4'000;
+        cursor->props.values.crtc_id = 4'001;
+        cursor->front                = cursorFramebuffer;
+        displacedCrtc->cursor        = cursor;
+
+        auto overlay                  = makeShared<SDRMPlane>();
+        overlay->id                   = 302;
+        overlay->type                 = DRM_PLANE_TYPE_OVERLAY;
+        overlay->props.values.fb_id   = 4'010;
+        overlay->props.values.crtc_id = 4'011;
+        overlay->front                = overlayFramebuffer;
+
+        std::vector<STiledPlaneInventoryResource> planeResources;
+        std::vector<STiledPlaneInventoryState>    planeStates;
+        for (const auto& PRIMARY : snapshot->primaryPlanes()) {
+            planeResources.push_back({.id = PRIMARY.plane->id, .owner = PRIMARY.plane, .role = eTiledReplacementPlaneRole::PRIMARY});
+            STiledPlaneInventoryState state{.id = PRIMARY.plane->id, .owner = PRIMARY.plane};
+            if (sameOwner(PRIMARY.plane, REUSED_MEMBER.primaryPlane)) {
+                state.crtcId           = REUSED_MEMBER.crtcId;
+                state.framebufferId    = 8'001;
+                state.framebufferOwner = reusedFramebufferOwner;
+            } else if (sameOwner(PRIMARY.plane, displacedPrimary)) {
+                state.crtcId           = displacedCrtc->id;
+                state.framebufferId    = 8'002;
+                state.framebufferOwner = oldFramebufferOwner;
+            }
+            planeStates.push_back(std::move(state));
+        }
+        planeResources.push_back({.id = cursor->id, .owner = cursor, .role = eTiledReplacementPlaneRole::CURSOR});
+        planeResources.push_back({.id = overlay->id, .owner = overlay, .role = eTiledReplacementPlaneRole::OVERLAY});
+        planeStates.push_back({.id = cursor->id, .owner = cursor, .crtcId = displacedCrtc->id, .framebufferId = 8'003, .framebufferOwner = cursorFramebufferOwner});
+        planeStates.push_back({.id = overlay->id, .owner = overlay, .crtcId = REUSED_MEMBER.crtcId, .framebufferId = 8'004, .framebufferOwner = overlayFramebufferOwner});
+        std::ranges::reverse(planeResources);
+        std::ranges::rotate(planeStates, planeStates.begin() + 1);
+
+        const auto planeInventory = CFixtureAuthority::planeInventory(installed, planeResources, planeStates);
+        CHECK(static_cast<bool>(planeInventory));
+
+        const auto makeCapture = [&] {
+            STiledAtomicReplacementCapture capture{
+                .targetRoute            = resolved.route,
+                .targetFramebufferOwner = targetFramebufferOwner,
+                .planeInventory         = planeInventory,
+            };
+            capture.connectors.reserve(snapshot->connectors().size());
+            for (const auto& CONNECTOR : snapshot->connectors()) {
+                const auto MEMBER = std::ranges::find(resolved.route->members(), CONNECTOR.connector->id, &STiledAtomicMember::connectorId);
+                CHECK(MEMBER != resolved.route->members().end());
+                capture.connectors.push_back({
+                    .connector    = CONNECTOR.connector,
+                    .attachedCrtc = CONNECTOR.connector->id == resolved.route->members().front().connectorId ? displacedCrtc : MEMBER->crtc,
+                });
+            }
+            for (const auto& CRTC : snapshot->crtcs())
+                capture.crtcs.push_back({.crtc = CRTC.crtc});
+            return capture;
+        };
+
+        auto incompleteStates = planeStates;
+        incompleteStates.pop_back();
+        CHECK(!CFixtureAuthority::planeInventory(installed, planeResources, incompleteStates));
+
+        auto unknownStates          = planeStates;
+        unknownStates.back().crtcId = 99'999;
+        CHECK(!CFixtureAuthority::planeInventory(installed, planeResources, unknownStates));
+
+        auto       mismatchedStates = planeStates;
+        const auto MISMATCHED       = std::ranges::find(mismatchedStates, overlay->id, &STiledPlaneInventoryState::id);
+        CHECK(MISMATCHED != mismatchedStates.end());
+        if (MISMATCHED != mismatchedStates.end()) {
+            const auto mismatchedOwner   = CFixtureAuthority::framebufferOwner(installed, overlayFramebuffer, overlayBuffer, framebufferMetadata(9'999));
+            MISMATCHED->framebufferOwner = mismatchedOwner;
+            CHECK(!CFixtureAuthority::planeInventory(installed, planeResources, mismatchedStates));
+            const auto deadOwner         = CFixtureAuthority::framebufferOwner(installed, overlayFramebuffer, overlayBuffer, framebufferMetadata(8'004), true);
+            MISMATCHED->framebufferOwner = deadOwner;
+            CHECK(!CFixtureAuthority::planeInventory(installed, planeResources, mismatchedStates));
+        }
+
+        auto foreignBackend = CFixtureAuthority::opaqueResource<CDRMBackend>();
+        overlay->backend    = foreignBackend;
+        CHECK(!CFixtureAuthority::planeInventory(installed, planeResources, planeStates));
+        overlay->backend = {};
+
+        const auto REPLACEMENT = resolveTiledAtomicReplacement(makeCapture());
+        CHECK(static_cast<bool>(REPLACEMENT));
+        replacement = REPLACEMENT.replacement;
+        CHECK(sameOwner(replacement->targetRoute(), resolved.route));
+        CHECK(replacement->connectors().size() == snapshot->connectors().size());
+        CHECK(replacement->crtcs().size() == snapshot->crtcs().size());
+        CHECK(sameOwner(replacement->targetFramebufferOwner(), targetFramebufferOwner));
+        CHECK(sameOwner(replacement->planeInventory(), planeInventory));
+        CHECK(replacement->planes().size() == planeResources.size());
+        CHECK(std::ranges::is_sorted(replacement->planes(), {}, &STiledReplacementPlane::id));
+        CHECK(std::ranges::all_of(replacement->planes(), [&](const auto& plane) {
+            return plane.incarnation && sameOwner(plane.incarnation->generationOwner(), installed) && sameOwner(plane.incarnation->plane(), plane.owner);
+        }));
+
+        auto                                          replacementRecorder   = makeShared<SRecorder>();
+        auto                                          replacementCleanup    = CTiledModeBlobCleanupRegistry::create(18);
+        CSharedPointer<ITiledAtomicRequestOperations> replacementOperations = replacementRecorder;
+        const auto                                    replacementBuilt      = buildTiledTestModeset(replacement, 18, replacementOperations, replacementCleanup);
+        CHECK(static_cast<bool>(replacementBuilt));
+        CHECK(sameOwner(replacementBuilt.prepared->replacement(), replacement));
+
+        std::vector<SPropertyWrite> replacementExpected;
+        for (size_t index = 0; index < resolved.route->members().size(); ++index)
+            appendExpected(replacementExpected, resolved.route->members().subspan(index, 1).front(), resolved.route->framebuffer().id, replacementRecorder->createdBlobs.at(index));
+        replacementExpected.push_back({.objectId = displacedCrtc->id, .propertyId = displacedCrtc->props.values.mode_id, .value = 0});
+        replacementExpected.push_back({.objectId = displacedCrtc->id, .propertyId = displacedCrtc->props.values.active, .value = 0});
+        replacementExpected.push_back({.objectId = displacedPrimary->id, .propertyId = displacedPrimary->props.values.fb_id, .value = 0});
+        replacementExpected.push_back({.objectId = displacedPrimary->id, .propertyId = displacedPrimary->props.values.crtc_id, .value = 0});
+        replacementExpected.push_back({.objectId = cursor->id, .propertyId = cursor->props.values.fb_id, .value = 0});
+        replacementExpected.push_back({.objectId = cursor->id, .propertyId = cursor->props.values.crtc_id, .value = 0});
+        replacementExpected.push_back({.objectId = overlay->id, .propertyId = overlay->props.values.fb_id, .value = 0});
+        replacementExpected.push_back({.objectId = overlay->id, .propertyId = overlay->props.values.crtc_id, .value = 0});
+        sortExpected(replacementExpected);
+        CHECK(replacementRecorder->properties == replacementExpected);
+        CHECK(replacementBuilt.prepared->cleanup().complete());
+        CHECK(replacementRecorder->frees == 1);
+
+        // The immutable replacement retains all displaced resource and FB
+        // owners independently of mutable ordinary caches.
+        displacedPrimary->front.reset();
+        displacedCrtc->primary.reset();
+        displacedCrtc->cursor.reset();
+        REUSED_MEMBER.primaryPlane->front.reset();
+        overlay->front.reset();
+        oldFramebuffer.reset();
+        reusedFramebuffer.reset();
+        cursorFramebuffer.reset();
+        overlayFramebuffer.reset();
+        oldBuffer.reset();
+        reusedBuffer.reset();
+        cursorBuffer.reset();
+        overlayBuffer.reset();
+        CHECK(std::ranges::all_of(replacement->planes(), [](const auto& plane) {
+            return plane.owner && ((plane.crtcId == 0 && !plane.framebufferOwner) || (plane.crtcId != 0 && plane.framebufferOwner));
+        }));
+    }
+    CHECK(static_cast<bool>(replacement));
+
     auto foreignMode            = makeShared<SOutputMode>();
     foreignMode->pixelSize      = MODE->pixelSize;
     foreignMode->refreshRate    = MODE->refreshRate;
@@ -814,6 +1065,7 @@ int main() {
     std::vector<SPropertyWrite> expected;
     for (size_t index = 0; index < resolved.route->members().size(); ++index)
         appendExpected(expected, resolved.route->members().subspan(index, 1).front(), resolved.route->framebuffer().id, recorder->createdBlobs.at(index));
+    sortExpected(expected);
     CHECK(recorder->properties == expected);
     CHECK(recorder->allocations == 1);
     CHECK(recorder->frees == 0);
@@ -946,7 +1198,7 @@ int main() {
         auto                                          initialRecorder   = makeShared<SFrameRecorder>();
         auto                                          initialCleanup    = CTiledModeBlobCleanupRegistry::create(31);
         CSharedPointer<ITiledAtomicRequestOperations> initialOperations = initialRecorder;
-        const auto                                    initialBuilt      = buildTiledModesetRequest(resolved.route, 31, initialOperations, initialCleanup);
+        const auto                                    initialBuilt      = buildTiledModesetRequest(replacement, 31, initialOperations, initialCleanup);
         CHECK(static_cast<bool>(initialBuilt));
 
         initialRecorder->runtime        = &runtime;
@@ -965,8 +1217,11 @@ int main() {
         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));
+        expectedInitial.reserve(replacement->propertyGraph().size());
+        for (const auto& WRITE : replacement->propertyGraph()) {
+            const auto VALUE = WRITE.source == eTiledAtomicPropertyValueSource::MODE_BLOB ? initialRecorder->createdBlobs.at(WRITE.memberIndex) : WRITE.value;
+            expectedInitial.push_back({.objectId = WRITE.objectId, .propertyId = WRITE.propertyId, .value = VALUE});
+        }
         CHECK(initialRecorder->properties == expectedInitial);
         const auto cleanup = initialBuilt.prepared->cleanup();
         CHECK(cleanup.complete());
@@ -984,7 +1239,7 @@ int main() {
         auto                                          blockedRecorder   = makeShared<SFrameRecorder>();
         auto                                          blockedCleanup    = CTiledModeBlobCleanupRegistry::create(32);
         CSharedPointer<ITiledAtomicRequestOperations> blockedOperations = blockedRecorder;
-        const auto                                    blockedBuilt      = buildTiledModesetRequest(resolved.route, 32, blockedOperations, blockedCleanup);
+        const auto                                    blockedBuilt      = buildTiledModesetRequest(replacement, 32, blockedOperations, blockedCleanup);
         CHECK(static_cast<bool>(blockedBuilt));
         auto& PENDING      = resolved.route->members().front().crtc->pendingFlip.id;
         PENDING            = 77;
@@ -1001,7 +1256,7 @@ int main() {
         auto failedCleanup                                             = CTiledModeBlobCleanupRegistry::create(33);
         failedRecorder->submitResult                                   = -EBUSY;
         CSharedPointer<ITiledAtomicRequestOperations> failedOperations = failedRecorder;
-        const auto                                    failedBuilt      = buildTiledModesetRequest(resolved.route, 33, failedOperations, failedCleanup);
+        const auto                                    failedBuilt      = buildTiledModesetRequest(replacement, 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);
@@ -1019,12 +1274,12 @@ int main() {
     // event tombstoned after proven retirement.
     {
         SFrameRuntime runtime(resolved.route->runtimePlan<PFrameOwner>());
-        CHECK(runtime.publishDisabled());
+        CHECK(runtime.armInitialAttempt());
         CTiledFlipReservationRegistry                 registry;
         auto                                          recoveryRecorder   = makeShared<SFrameRecorder>();
         auto                                          recoveryCleanup    = CTiledModeBlobCleanupRegistry::create(34);
         CSharedPointer<ITiledAtomicRequestOperations> recoveryOperations = recoveryRecorder;
-        const auto                                    recoveryBuilt      = buildTiledModesetRequest(resolved.route, 34, recoveryOperations, recoveryCleanup);
+        const auto                                    recoveryBuilt      = buildTiledModesetRequest(replacement, 34, recoveryOperations, recoveryCleanup);
         CHECK(static_cast<bool>(recoveryBuilt));
         recoveryRecorder->runtime                   = &runtime;
         recoveryRecorder->registry                  = &registry;
@@ -1040,6 +1295,7 @@ int main() {
         CHECK(!recovered.effects.runtimeAccept.schedulerSubmit);
         CHECK(recoveryRecorder->runtimeAcceptDuringSubmit.accepted);
         CHECK(runtime.state() == eTiledRuntimeState::QUIESCED);
+        CHECK(!runtime.rollbackInitialAttempt());
         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{});
@@ -1069,7 +1325,7 @@ int main() {
         auto                                          recoveryRecorder   = makeShared<SFrameRecorder>();
         auto                                          recoveryCleanup    = CTiledModeBlobCleanupRegistry::create(35);
         CSharedPointer<ITiledAtomicRequestOperations> recoveryOperations = recoveryRecorder;
-        const auto                                    recoveryBuilt      = buildTiledModesetRequest(resolved.route, 35, recoveryOperations, recoveryCleanup);
+        const auto                                    recoveryBuilt      = buildTiledModesetRequest(replacement, 35, recoveryOperations, recoveryCleanup);
         CHECK(static_cast<bool>(recoveryBuilt));
         recoveryRecorder->runtime                    = &runtime;
         recoveryRecorder->registry                   = &registry;
@@ -1105,7 +1361,7 @@ int main() {
         auto                          debtCleanup                    = CTiledModeBlobCleanupRegistry::create(36);
         debtRecorder->destroyFailuresRemaining                       = 1;
         CSharedPointer<ITiledAtomicRequestOperations> debtOperations = debtRecorder;
-        const auto                                    debtBuilt      = buildTiledModesetRequest(resolved.route, 36, debtOperations, debtCleanup);
+        const auto                                    debtBuilt      = buildTiledModesetRequest(replacement, 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);
@@ -1387,6 +1643,79 @@ int main() {
         CHECK(authority.stageCurrent(installed, resolved.route) == eGroupedStageResult::STAGED);
         CHECK(CFixtureAuthority::nestedStage(authority, installed, resolved.route) == eGroupedStageResult::BUSY);
 
+        std::vector<SOrdinaryKMSCRTC> ordinaryCRTCs;
+        ordinaryCRTCs.reserve(resolved.route->members().size());
+        for (const auto& MEMBER : resolved.route->members())
+            ordinaryCRTCs.push_back({.owner = MEMBER.crtc, .id = MEMBER.crtcId});
+
+        size_t     rollbackGateCallbacks = 0;
+        const auto verifyStagedGate      = [&] {
+            CHECK(CFixtureAuthority::runtimeState(authority, GROUP.definitionIdentity()) == eTiledRuntimeState::STAGED);
+            const auto GATE = authority.gateOrdinaryKMS(ordinaryCRTCs, [&] {
+                ++rollbackGateCallbacks;
+                return true;
+            });
+            CHECK(GATE.status == eOrdinaryKMSGateStatus::EXECUTED);
+            CHECK(GATE.callbackResult);
+        };
+
+        // Request allocation and property construction failures are both
+        // preaccept: their attempt-only arm returns to inert STAGED, and all
+        // request/blob ownership is cleaned exactly once.
+        {
+            CHECK(CFixtureAuthority::armInitialAttempt(authority, GROUP.definitionIdentity()));
+            auto allocationRecorder                                            = makeShared<SRecorder>();
+            allocationRecorder->failAllocation                                 = true;
+            auto                                          allocationCleanup    = CTiledModeBlobCleanupRegistry::create(40);
+            CSharedPointer<ITiledAtomicRequestOperations> allocationOperations = allocationRecorder;
+            const auto                                    allocationFailure    = buildTiledModesetRequest(replacement, 40, allocationOperations, allocationCleanup);
+            CHECK(allocationFailure.error == eTiledAtomicError::REQUEST_ALLOCATION_FAILED);
+            CHECK(allocationRecorder->allocations == 1);
+            CHECK(allocationRecorder->frees == 0);
+            CHECK(CFixtureAuthority::rollbackInitialAttempt(authority, GROUP.definitionIdentity()));
+            verifyStagedGate();
+        }
+        {
+            CHECK(CFixtureAuthority::armInitialAttempt(authority, GROUP.definitionIdentity()));
+            auto propertyRecorder                                            = makeShared<SRecorder>();
+            propertyRecorder->failPropertyAt                                 = 0;
+            auto                                          propertyCleanup    = CTiledModeBlobCleanupRegistry::create(41);
+            CSharedPointer<ITiledAtomicRequestOperations> propertyOperations = propertyRecorder;
+            const auto                                    propertyFailure    = buildTiledModesetRequest(replacement, 41, propertyOperations, propertyCleanup);
+            CHECK(propertyFailure.error == eTiledAtomicError::PROPERTY_ADD_FAILED);
+            CHECK(propertyRecorder->frees == 1);
+            CHECK(propertyRecorder->destroyedBlobs.size() == resolved.route->members().size());
+            CHECK(propertyCleanup->pendingCount() == 0);
+            CHECK(CFixtureAuthority::rollbackInitialAttempt(authority, GROUP.definitionIdentity()));
+            verifyStagedGate();
+        }
+        {
+            auto submitRecorder                                            = makeShared<SRecorder>();
+            submitRecorder->submitResult                                   = -EBUSY;
+            auto                                          submitCleanup    = CTiledModeBlobCleanupRegistry::create(42);
+            CSharedPointer<ITiledAtomicRequestOperations> submitOperations = submitRecorder;
+            const auto                                    submitBuilt      = buildTiledModesetRequest(replacement, 42, submitOperations, submitCleanup);
+            CHECK(static_cast<bool>(submitBuilt));
+            auto                                          submitSink        = makeShared<CRecordingPublicationSink>();
+            CSharedPointer<IGroupedPublicationEffectSink> submitSinkOwner   = submitSink;
+            const auto                                    submitPublication = CGroupedPublicationInstance::create(GROUP.definitionIdentity(), submitSinkOwner);
+            const auto                                    submitFramebuffer = CFixtureAuthority::opaqueResource<CDRMFB>();
+            const auto                                    submitBuffer      = CFixtureAuthority::opaqueResource<IBuffer>();
+            CHECK(CFixtureAuthority::armInitialAttempt(authority, GROUP.definitionIdentity()));
+            const auto failed = CFixtureAuthority::submitInitialAttempt(authority, GROUP.definitionIdentity(), submitBuilt.prepared, submitPublication, submitFramebuffer,
+                                                                        submitBuffer, 4'899, 80'000, 42);
+            CHECK(failed.status == eTiledFrameTransactionStatus::SUBMISSION_FAILED);
+            CHECK(failed.effects.runtimeRolledBack);
+            CHECK(failed.effects.registryRolledBack);
+            CHECK(CFixtureAuthority::runtimeState(authority, GROUP.definitionIdentity()) == eTiledRuntimeState::PUBLISHED_DISABLED);
+            CHECK(CFixtureAuthority::rollbackInitialAttempt(authority, GROUP.definitionIdentity()));
+            CHECK(submitBuilt.prepared->cleanup().complete());
+            CHECK(submitRecorder->frees == 1);
+            CHECK(submitRecorder->destroyedBlobs.size() == resolved.route->members().size());
+            verifyStagedGate();
+        }
+        CHECK(rollbackGateCallbacks == 3);
+
         auto                                          rollbackSink        = makeShared<CRecordingPublicationSink>();
         CSharedPointer<IGroupedPublicationEffectSink> rollbackSinkOwner   = rollbackSink;
         const auto                                    rollbackPublication = CGroupedPublicationInstance::create(GROUP.definitionIdentity(), rollbackSinkOwner);
@@ -1433,11 +1762,6 @@ int main() {
         CHECK(CFixtureAuthority::consume(releasePublication, 4'903, resolved.route, releaseEffects) == eGroupedCompletionConsumeResult::DELIVERED);
         CHECK(releaseSink->completions == 1);
 
-        std::vector<SOrdinaryKMSCRTC> ordinaryCRTCs;
-        ordinaryCRTCs.reserve(resolved.route->members().size());
-        for (const auto& MEMBER : resolved.route->members())
-            ordinaryCRTCs.push_back({.owner = MEMBER.crtc, .id = MEMBER.crtcId});
-
         size_t     callbackCount  = 0;
         const auto CALLBACK_FALSE = authority.gateOrdinaryKMS(ordinaryCRTCs, [&] {
             ++callbackCount;
diff --git a/tests/TiledDRMIntegration.cpp b/tests/TiledDRMIntegration.cpp
index 15f68cf20dcd5dd4c203ce86f16fc4acd0be2f54..9aeb10295e6873aa25749764fa0d7d79a3526e6e 100644
--- a/tests/TiledDRMIntegration.cpp
+++ b/tests/TiledDRMIntegration.cpp
@@ -93,16 +93,28 @@ namespace Aquamarine::NDRM::NTiledDRMIntegrationTest {
             return registry.configureInjectedTestModeset(lifetime, drmFD, operations, framebufferSource);
         }
 
+        static PAtomicFramebufferOwner framebufferProof(const POutputBridgeObservation& generationOwner, const CSharedPointer<Aquamarine::CDRMFB>& framebuffer,
+                                                        const CSharedPointer<Aquamarine::IBuffer>& buffer, STiledAtomicFramebuffer atomic, bool dead = false) {
+            return CTiledAtomicFramebufferOwner::createFixture(generationOwner, framebuffer, buffer, atomic, dead);
+        }
+
+        static PAtomicPlaneInventory planeInventory(const POutputBridgeObservation& generationOwner, std::vector<STiledPlaneInventoryResource> resources,
+                                                    std::vector<STiledPlaneInventoryState> states) {
+            return CTiledAtomicPlaneInventory::create(generationOwner, std::move(resources), std::move(states));
+        }
+
         static SGroupedTestModesetResult executeTestModeset(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
-                                                            const PScanGroupDefinition& group, const CSharedPointer<Aquamarine::SOutputMode>& outputMode) {
-            return registry.executeCurrentTestModeset(lifetime, expected, group, outputMode);
+                                                            const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                            const CSharedPointer<Aquamarine::SOutputMode>& outputMode) {
+            return registry.executeCurrentTestModeset(lifetime, expected, replacement, group, outputMode);
         }
 
         static SGroupedInitialFrameResult submitInitialFrame(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime, const POutputBridgeObservation& expected,
-                                                             const PScanGroupDefinition& group, const CSharedPointer<Aquamarine::SOutputMode>& outputMode,
-                                                             const PGroupedPublicationInstance& publication, const CSharedPointer<Aquamarine::CDRMFB>& framebuffer,
-                                                             const CSharedPointer<Aquamarine::IBuffer>& buffer, uintptr_t transactionId, uint64_t deadlineNs) {
-            return registry.submitCurrentTestInitialFrame(lifetime, expected, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
+                                                             const PResolvedTiledAtomicReplacement& replacement, const PScanGroupDefinition& group,
+                                                             const CSharedPointer<Aquamarine::SOutputMode>& outputMode, const PGroupedPublicationInstance& publication,
+                                                             const CSharedPointer<Aquamarine::CDRMFB>& framebuffer, const CSharedPointer<Aquamarine::IBuffer>& buffer,
+                                                             uintptr_t transactionId, uint64_t deadlineNs) {
+            return registry.submitCurrentTestInitialFrame(lifetime, expected, replacement, group, outputMode, publication, framebuffer, buffer, transactionId, deadlineNs);
         }
 
         static bool exhaustResourceEpoch(CTiledDRMIntegrationRegistry& registry, const PBackendLifetime& lifetime) {
@@ -295,6 +307,8 @@ namespace {
         crtc1->id                       = 11;
         plane0->id                      = 100;
         plane1->id                      = 102;
+        plane0->type                    = DRM_PLANE_TYPE_PRIMARY;
+        plane1->type                    = DRM_PLANE_TYPE_PRIMARY;
         left->props.values.crtc_id      = 1000;
         left->props.values.link_status  = 1001;
         right->props.values.crtc_id     = 1010;
@@ -366,6 +380,90 @@ namespace {
             observation->groups(), [](const auto& candidate) { return candidate.scanDefinition()->group().kind == Aquamarine::NTiling::eTileGroupKind::MULTI_STREAM; });
         return GROUP == observation->groups().end() ? nullptr : &*GROUP;
     }
+
+    PResolvedTiledAtomicReplacement replacementFixture(const POutputBridgeObservation& observation, const PScanGroupDefinition& group,
+                                                       const CSharedPointer<Aquamarine::SOutputMode>& outputMode, STiledAtomicFramebuffer targetFramebuffer) {
+        const auto ROUTE = resolveCapturedTiledAtomic({
+            .generationOwner    = observation,
+            .groupDefinition    = group,
+            .definitionIdentity = observation && group && observation->findGroup(group) ? observation->findGroup(group)->definitionIdentity() : POutputDefinitionIdentity{},
+            .outputMode         = outputMode,
+            .framebuffer        = targetFramebuffer,
+        });
+        if (!ROUTE)
+            return {};
+
+        const auto TARGET_DRM_FB = opaqueResource<Aquamarine::CDRMFB>();
+        const auto TARGET_BUFFER = opaqueResource<Aquamarine::IBuffer>();
+        const auto TARGET_PROOF  = CFixtureAuthority::framebufferProof(observation, TARGET_DRM_FB, TARGET_BUFFER, targetFramebuffer);
+        if (!TARGET_PROOF)
+            return {};
+
+        const auto& SNAPSHOT = observation->capturedSnapshot();
+        if (!SNAPSHOT)
+            return {};
+
+        std::vector<STiledPlaneInventoryResource> planeResources;
+        std::vector<STiledPlaneInventoryState>    planeStates;
+        planeResources.reserve(SNAPSHOT->primaryPlanes().size() + 2);
+        planeStates.reserve(SNAPSHOT->primaryPlanes().size() + 2);
+
+        uint32_t   oldFramebufferId = 710;
+        const auto addLivePlane     = [&](const CSharedPointer<Aquamarine::SDRMPlane>& plane, eTiledReplacementPlaneRole role, uint32_t crtcId) {
+            auto oldFramebuffer = opaqueResource<Aquamarine::CDRMFB>();
+            auto oldBuffer      = opaqueResource<Aquamarine::IBuffer>();
+            auto oldAtomic      = targetFramebuffer;
+            oldAtomic.id        = oldFramebufferId++;
+            const auto oldProof = CFixtureAuthority::framebufferProof(observation, oldFramebuffer, oldBuffer, oldAtomic);
+            plane->front        = oldFramebuffer;
+            planeResources.push_back({.id = plane->id, .owner = plane, .role = role});
+            planeStates.push_back({.id = plane->id, .owner = plane, .crtcId = crtcId, .framebufferId = oldAtomic.id, .framebufferOwner = oldProof});
+            return !!oldProof;
+        };
+
+        for (const auto& PRIMARY : SNAPSHOT->primaryPlanes()) {
+            const auto MEMBER = std::ranges::find_if(ROUTE.route->members(), [&](const auto& candidate) { return candidate.primaryPlane.impl_ == PRIMARY.plane.impl_; });
+            if (MEMBER == ROUTE.route->members().end() || !addLivePlane(PRIMARY.plane, eTiledReplacementPlaneRole::PRIMARY, MEMBER->crtcId))
+                return {};
+        }
+
+        auto cursor                   = makeShared<Aquamarine::SDRMPlane>();
+        cursor->id                    = 103;
+        cursor->type                  = DRM_PLANE_TYPE_CURSOR;
+        cursor->props.values.fb_id    = 3040;
+        cursor->props.values.crtc_id  = 3041;
+        auto overlay                  = makeShared<Aquamarine::SDRMPlane>();
+        overlay->id                   = 104;
+        overlay->type                 = DRM_PLANE_TYPE_OVERLAY;
+        overlay->props.values.fb_id   = 3050;
+        overlay->props.values.crtc_id = 3051;
+        if (!addLivePlane(cursor, eTiledReplacementPlaneRole::CURSOR, ROUTE.route->members().front().crtcId) ||
+            !addLivePlane(overlay, eTiledReplacementPlaneRole::OVERLAY, ROUTE.route->members().back().crtcId))
+            return {};
+
+        const auto INVENTORY = CFixtureAuthority::planeInventory(observation, std::move(planeResources), std::move(planeStates));
+        if (!INVENTORY)
+            return {};
+
+        STiledAtomicReplacementCapture capture{
+            .targetRoute            = ROUTE.route,
+            .targetFramebufferOwner = TARGET_PROOF,
+            .planeInventory         = INVENTORY,
+        };
+        capture.connectors.reserve(SNAPSHOT->connectors().size());
+        for (const auto& CONNECTOR : SNAPSHOT->connectors()) {
+            const auto MEMBER = std::ranges::find_if(ROUTE.route->members(), [&](const auto& candidate) { return candidate.connector.impl_ == CONNECTOR.connector.impl_; });
+            if (MEMBER == ROUTE.route->members().end())
+                return {};
+            capture.connectors.push_back({.connector = CONNECTOR.connector, .attachedCrtc = MEMBER->crtc});
+        }
+        capture.crtcs.reserve(SNAPSHOT->crtcs().size());
+        for (const auto& CRTC : SNAPSHOT->crtcs())
+            capture.crtcs.push_back({.crtc = CRTC.crtc});
+
+        const auto REPLACEMENT = resolveTiledAtomicReplacement(std::move(capture));
+        return REPLACEMENT.replacement;
+    }
 }
 
 int main() {
@@ -547,8 +645,16 @@ int main() {
         CSharedPointer<ITiledAtomicRequestOperations> atomicOperationsInterface  = atomicOperations;
         EXPECT(CFixtureAuthority::configureTestModeset(registry, LIFETIME, 73, atomicOperationsInterface, framebufferSourceInterface), true);
 
-        const auto TEST_MODESET =
-            CFixtureAuthority::executeTestModeset(registry, LIFETIME, BRIDGE, ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE);
+        const auto ATOMIC_REPLACEMENT =
+            replacementFixture(BRIDGE, ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE, testFramebuffer->atomic);
+        EXPECT(!!ATOMIC_REPLACEMENT, true);
+        const auto MISSING_REPLACEMENT =
+            CFixtureAuthority::executeTestModeset(registry, LIFETIME, BRIDGE, {}, ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE);
+        EXPECT(value(MISSING_REPLACEMENT.status), value(eGroupedTestModesetStatus::INVALID_CURRENT));
+        EXPECT(atomicOperations->submits, 0U);
+
+        const auto TEST_MODESET = CFixtureAuthority::executeTestModeset(registry, LIFETIME, BRIDGE, ATOMIC_REPLACEMENT,
+                                                                        ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE);
         EXPECT(value(TEST_MODESET.status), value(eGroupedTestModesetStatus::SUCCEEDED));
         EXPECT(TEST_MODESET.routeError == eTiledAtomicError::NONE, true);
         EXPECT(TEST_MODESET.executionStatus.value_or(eTiledTestModesetStatus::INVALID_INPUT) == eTiledTestModesetStatus::SUCCEEDED, true);
@@ -613,16 +719,16 @@ int main() {
         EXPECT(FALLBACK_GROUP && FALLBACK_GROUP->projection() == eGroupProjection::MULTI_STREAM_FALLBACK, true);
         EXPECT(FALLBACK_GROUP && FALLBACK_GROUP->definitionIdentity() == DEFINITION_IDENTITY, true);
         EXPECT(FALLBACK_GROUP && FALLBACK_GROUP->modeSet() && FALLBACK_GROUP->modeSet()->modes().front().outputMode == OUTPUT_MODE, true);
-        const auto STALE_TEST_MODESET =
-            CFixtureAuthority::executeTestModeset(registry, LIFETIME, BRIDGE, ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE);
+        const auto STALE_TEST_MODESET = CFixtureAuthority::executeTestModeset(registry, LIFETIME, BRIDGE, ATOMIC_REPLACEMENT,
+                                                                              ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE);
         EXPECT(value(STALE_TEST_MODESET.status), value(eGroupedTestModesetStatus::INVALID_CURRENT));
         EXPECT(atomicOperations->submits, 1U);
         auto                                          staleSink        = makeShared<CNoopPublicationSink>();
         CSharedPointer<IGroupedPublicationEffectSink> staleSinkOwner   = staleSink;
         const auto                                    stalePublication = CGroupedPublicationInstance::create(DEFINITION_IDENTITY, staleSinkOwner);
         const auto                                    STALE_INITIAL =
-            CFixtureAuthority::submitInitialFrame(registry, LIFETIME, BRIDGE, ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{}, OUTPUT_MODE,
-                                                  stalePublication, opaqueResource<Aquamarine::CDRMFB>(), opaqueResource<Aquamarine::IBuffer>(), 8'001, 100'000);
+            CFixtureAuthority::submitInitialFrame(registry, LIFETIME, BRIDGE, ATOMIC_REPLACEMENT, ALLOCATED_GROUP ? ALLOCATED_GROUP->scanDefinition() : PScanGroupDefinition{},
+                                                  OUTPUT_MODE, stalePublication, opaqueResource<Aquamarine::CDRMFB>(), opaqueResource<Aquamarine::IBuffer>(), 8'001, 100'000);
         EXPECT(STALE_INITIAL.status == eGroupedInitialFrameStatus::INVALID_CURRENT, true);
         EXPECT(atomicOperations->submits, 1U);
         EXPECT(CFixtureAuthority::withCurrent(registry, LIFETIME, SHADOW, [&](const CPlan&, const SCurrentState&) { ++callbacks; }), false);
@@ -702,9 +808,11 @@ int main() {
         const auto* FINAL_GROUP  = multiStreamGroup(FINAL_BRIDGE);
         const auto  FINAL_MODE   = FINAL_GROUP && FINAL_GROUP->modeSet() ? FINAL_GROUP->modeSet()->modes().front().outputMode : CSharedPointer<Aquamarine::SOutputMode>{};
         EXPECT(!!FINAL_BRIDGE, true);
+        const auto FINAL_REPLACEMENT = replacementFixture(FINAL_BRIDGE, FINAL_GROUP ? FINAL_GROUP->scanDefinition() : PScanGroupDefinition{}, FINAL_MODE, testFramebuffer->atomic);
+        EXPECT(!!FINAL_REPLACEMENT, true);
         atomicOperations->destroyFailuresRemaining = 1;
-        const auto RETAINED_CLEANUP =
-            CFixtureAuthority::executeTestModeset(registry, LIFETIME, FINAL_BRIDGE, FINAL_GROUP ? FINAL_GROUP->scanDefinition() : PScanGroupDefinition{}, FINAL_MODE);
+        const auto RETAINED_CLEANUP                = CFixtureAuthority::executeTestModeset(registry, LIFETIME, FINAL_BRIDGE, FINAL_REPLACEMENT,
+                                                                                           FINAL_GROUP ? FINAL_GROUP->scanDefinition() : PScanGroupDefinition{}, FINAL_MODE);
         EXPECT(value(RETAINED_CLEANUP.status), value(eGroupedTestModesetStatus::CLEANUP_PENDING));
         EXPECT(RETAINED_CLEANUP.cleanup.retained, 1U);
         EXPECT(atomicOperations->submits, 2U);
diff --git a/tests/TiledRuntime.cpp b/tests/TiledRuntime.cpp
index 5288750baf383354a145dbeb30f4680434589a33..d422d34a9eef779bd2ab5d463e64d2f32f067786 100644
--- a/tests/TiledRuntime.cpp
+++ b/tests/TiledRuntime.cpp
@@ -154,6 +154,22 @@ int main() {
     static_assert(std::is_nothrow_destructible_v<SFrame>);
     static_assert(noexcept(std::declval<const SStrongOwner&>().get()));
 
+    {
+        auto     planOwner = owner("initial-attempt");
+        SRuntime runtime(plan(6, planOwner));
+        EXPECT(runtime.armInitialAttempt(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::PUBLISHED_DISABLED));
+        EXPECT(runtime.readyForDestruction(), true);
+        EXPECT(runtime.rollbackInitialAttempt(), true);
+        EXPECT(enumValue(runtime.state()), enumValue(eTiledRuntimeState::STAGED));
+        EXPECT(runtime.armInitialAttempt(), true);
+        EXPECT(runtime.publishDisabled(), false);
+        EXPECT(runtime.rollbackInitialAttempt(), true);
+        EXPECT(runtime.publishDisabled(), true);
+        EXPECT(runtime.rollbackInitialAttempt(), false);
+        EXPECT(terminalTeardown(runtime), true);
+    }
+
     {
         CTiledFlipReservationRegistry registry;
         EXPECT(registry.readyForDestruction(), true);