diff --git a/QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs b/QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs
new file mode 100644
index 000000000..a8dbcdba8
--- /dev/null
+++ b/QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs
@@ -0,0 +1,196 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using QuickFiler.Controllers;
+using QuickFiler.Viewers;
+using UtilitiesCS;
+using UtilitiesCS.OutlookObjects.Folder;
+
+namespace QuickFiler.Test.Controllers
+{
+ ///
+ /// Regression tests for issue #792 on : a failed
+ /// CoreWebView2 initialization discards the stashed document, clears the selection and
+ /// navigates the error banner; a later initialization must not replay the stale stash. The
+ /// arrangement mirrors BreadcrumbBridgeRouterQueueTests . No timers, sleeps or temp files.
+ ///
+ [TestClass]
+ public sealed class BreadcrumbBridgeRouterIssue792Tests
+ {
+ private const string LeafPath = "Inbox\\Projects\\Alpha";
+ private const string RowSelectedPayload = "{\"type\":\"rowSelected\",\"rowId\":\"row-0\"}";
+ private const string ErrorBannerToken = "Folder list unavailable";
+ private const string StaleRowToken = "Alpha";
+
+ private Mock _provider;
+ private Mock _host;
+ private bool _initialized;
+ private List _navigated;
+ private List _posted;
+ private BreadcrumbBridgeRouter _router;
+
+ [TestInitialize]
+ public void Setup()
+ {
+ _provider = new Mock();
+ _host = new Mock();
+ _initialized = false;
+ _navigated = new List();
+ _posted = new List();
+ _host.SetupGet(h => h.IsCoreInitialized).Returns(() => _initialized);
+ _host
+ .Setup(h => h.NavigateToString(It.IsAny()))
+ .Callback(html => _navigated.Add(html));
+ _host
+ .Setup(h => h.PostMessageJson(It.IsAny()))
+ .Callback(json => _posted.Add(json));
+ _provider
+ .Setup(p =>
+ p.ResolveLeafKeyAsync(It.IsAny(), It.IsAny())
+ )
+ .ReturnsAsync(
+ (string path, CancellationToken ct) =>
+ new FolderTreeNodeKey("store-1", "entry", path)
+ );
+ _provider
+ .Setup(p =>
+ p.GetAncestorChainAsync(
+ It.IsAny(),
+ It.IsAny()
+ )
+ )
+ .ReturnsAsync(
+ new[] { Segment("Inbox", "Inbox", true), Segment(LeafPath, "Alpha", true) }
+ );
+ _router = new BreadcrumbBridgeRouter(
+ _provider.Object,
+ _host.Object,
+ new BreadcrumbMessageCodec(),
+ new BreadcrumbHtmlRenderer(),
+ new BreadcrumbOutboundQueue(_host.Object)
+ );
+ }
+
+ private static FolderBreadcrumbSegment Segment(string path, string name, bool hasChildren)
+ {
+ return new FolderBreadcrumbSegment(
+ new FolderTreeNodeKey("store-1", "entry", path),
+ name,
+ path,
+ hasChildren
+ );
+ }
+
+ private void Bind()
+ {
+ _router
+ .BindRowsAsync(
+ new[] { LeafPath },
+ Enumerable.Empty(),
+ CancellationToken.None
+ )
+ .GetAwaiter()
+ .GetResult();
+ }
+
+ private void Inbound(string json)
+ {
+ _router.ProcessInboundAsync(json).GetAwaiter().GetResult();
+ }
+
+ ///
+ /// AC-U1/AC-U2: with a stashed document and a live selection, the failure entry point
+ /// navigates exactly one document (the banner, not the stale folder document) and clears
+ /// the selection, notifying subscribers with null. Before the fix the declaration-only body
+ /// navigates nothing, so the first assertion fails.
+ ///
+ [TestMethod]
+ public void NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner()
+ {
+ // Arrange: the uninitialized host stashes the bound document; a selection exists.
+ Bind();
+ _navigated.Should().BeEmpty("the bound document is stashed while uninitialized");
+ Inbound(RowSelectedPayload);
+ _router.SelectedFolderPath.Should().NotBeNull("a selection must exist to be cleared");
+ string observed = "sentinel";
+ _router.SelectedFolderPathChanged += (s, path) => observed = path;
+
+ // Act
+ _router.NotifyInitializationFailed(new InvalidOperationException("boom"));
+
+ // Assert
+ _navigated
+ .Should()
+ .ContainSingle("the failure must navigate exactly one document, the error banner")
+ .Which.Should()
+ .Contain(ErrorBannerToken, "the navigated document must be the error banner")
+ .And.NotContain(StaleRowToken, "the stashed folder document must be discarded");
+ _router
+ .SelectedFolderPath.Should()
+ .BeNull("a failed initialization clears the selection");
+ observed.Should().BeNull("clearing a selection must notify subscribers with null");
+ }
+
+ ///
+ /// AC-U2: after the failure, a later initialization must find no stash to replay. Before
+ /// the fix the stash survives, so the only navigation is the stale folder document, which
+ /// contains the leaf name: the count assertion passes and the content assertion fails.
+ ///
+ [TestMethod]
+ public void NotifyInitializationFailed_LeavesNoStashForALaterInitialization()
+ {
+ // Arrange
+ Bind();
+ Inbound(RowSelectedPayload);
+
+ // Act
+ _router.NotifyInitializationFailed(new InvalidOperationException("boom"));
+ _initialized = true;
+ _router.NotifyCoreInitialized();
+
+ // Assert
+ _navigated.Should().HaveCount(1, "only the error banner may be navigated");
+ _navigated[0]
+ .Should()
+ .Contain(ErrorBannerToken, "the single navigation must be the error banner")
+ .And.NotContain(StaleRowToken, "the stale stash must not be replayed");
+ }
+
+ /// Control: a null failure is rejected at the boundary.
+ [TestMethod]
+ public void NotifyInitializationFailed_WithNullFailure_Throws()
+ {
+ // Arrange
+ Action act = () => _router.NotifyInitializationFailed(null);
+
+ // Act and Assert
+ act.Should()
+ .Throw("the failure is required")
+ .Which.ParamName.Should()
+ .Be("failure");
+ }
+
+ /// Retained-behaviour control: a stash is still delivered on initialization.
+ [TestMethod]
+ public void NotifyCoreInitialized_AfterAnEarlierStash_StillNavigatesIt()
+ {
+ // Arrange
+ Bind();
+ _initialized = true;
+
+ // Act
+ _router.NotifyCoreInitialized();
+
+ // Assert
+ _navigated
+ .Should()
+ .ContainSingle("the stashed document is delivered once on initialization")
+ .Which.Should()
+ .Contain(StaleRowToken, "the delivered document is the bound folder document");
+ }
+ }
+}
diff --git a/QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs b/QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs
new file mode 100644
index 000000000..cd3a96b08
--- /dev/null
+++ b/QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs
@@ -0,0 +1,113 @@
+using System;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using QuickFiler.Controllers;
+using QuickFiler.Viewers;
+using UtilitiesCS.OutlookObjects.Folder;
+
+namespace QuickFiler.Test.Controllers
+{
+ ///
+ /// Regression tests for issue #792 on
+ /// (AC-U7): when CoreWebView2 initialization fails, buffered payloads are discarded rather
+ /// than drained, because the host cannot post to a core that does not exist. No timers,
+ /// sleeps or temp files are used.
+ ///
+ [TestClass]
+ public sealed class BreadcrumbOutboundQueueIssue792Tests
+ {
+ private const string RenderPayload = "{\"type\":\"render\"}";
+ private const string FocusPayload = "{\"type\":\"focusSearch\"}";
+ private const string ThemePayload = "{\"type\":\"theme\"}";
+
+ private static Mock CreateUninitializedHost()
+ {
+ var host = new Mock();
+ host.SetupGet(h => h.IsCoreInitialized).Returns(false);
+ return host;
+ }
+
+ ///
+ /// Three buffered payloads are discarded: the method reports three, nothing remains
+ /// pending and nothing was posted. Before the fix the stub returns zero and keeps them.
+ ///
+ [TestMethod]
+ public void DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending()
+ {
+ // Arrange
+ var host = CreateUninitializedHost();
+ var queue = new BreadcrumbOutboundQueue(host.Object);
+ queue.PostOrQueue(RenderPayload);
+ queue.PostOrQueue(FocusPayload);
+ queue.PostOrQueue(ThemePayload);
+ queue.PendingCount.Should().Be(3, "the uninitialized host must buffer every payload");
+
+ // Act
+ int discarded = queue.DiscardPending();
+
+ // Assert
+ discarded.Should().Be(3, "the discarded count must equal the number buffered");
+ queue.PendingCount.Should().Be(0, "a discard must leave nothing pending");
+ host.Verify(
+ h => h.PostMessageJson(It.IsAny()),
+ Times.Never,
+ "a discard must not post to a core that does not exist"
+ );
+ }
+
+ /// Control: discarding an empty buffer reports zero and posts nothing.
+ [TestMethod]
+ public void DiscardPending_OnAnEmptyQueue_ReturnsZero()
+ {
+ // Arrange
+ var host = CreateUninitializedHost();
+ var queue = new BreadcrumbOutboundQueue(host.Object);
+
+ // Act
+ int discarded = queue.DiscardPending();
+
+ // Assert
+ discarded.Should().Be(0, "an empty buffer has nothing to discard");
+ queue.PendingCount.Should().Be(0, "an empty buffer stays empty");
+ host.Verify(h => h.PostMessageJson(It.IsAny()), Times.Never);
+ }
+
+ ///
+ /// AC-U7 through the router: the failure entry point discards the router's own outbound
+ /// queue without posting. Before the fix the declaration-only body leaves both payloads
+ /// pending.
+ ///
+ [TestMethod]
+ public void NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting()
+ {
+ // Arrange
+ var host = CreateUninitializedHost();
+ var queue = new BreadcrumbOutboundQueue(host.Object);
+ var provider = new Mock(MockBehavior.Loose);
+ var router = new BreadcrumbBridgeRouter(
+ provider.Object,
+ host.Object,
+ new BreadcrumbMessageCodec(),
+ new BreadcrumbHtmlRenderer(),
+ queue
+ );
+ queue.PostOrQueue(RenderPayload);
+ queue.PostOrQueue(FocusPayload);
+ queue.PendingCount.Should().Be(2, "the uninitialized host must buffer both payloads");
+
+ // Act
+ router.NotifyInitializationFailed(new InvalidOperationException("boom"));
+
+ // Assert
+ queue
+ .PendingCount.Should()
+ .Be(0, "a failed initialization must discard the buffered payloads");
+ host.Verify(
+ h => h.PostMessageJson(It.IsAny()),
+ Times.Never,
+ "discarded payloads must never be posted"
+ );
+ }
+ }
+}
diff --git a/QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs b/QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs
new file mode 100644
index 000000000..a1092da39
--- /dev/null
+++ b/QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs
@@ -0,0 +1,175 @@
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using UtilitiesCS;
+
+namespace QuickFiler.Controllers.Tests
+{
+ ///
+ /// Regression tests for issue #792 AC-U3 on : a folder handler
+ /// carried from a pop-out source item is adopted when it is a concrete predictor and no
+ /// explicit list is supplied; otherwise the existing initialization path runs. In both cases
+ /// the carry is released afterwards. Data models are allocated without a constructor, so no
+ /// Outlook COM context is required; the one test that runs the existing path supplies a
+ /// mocked globals so the predictor constructor can read Ol.App .
+ ///
+ [TestClass]
+ public sealed class EfcDataModelIssue792CarryTests
+ {
+ private static EfcDataModel CreateUninitializedModel()
+ {
+ return (EfcDataModel)FormatterServices.GetUninitializedObject(typeof(EfcDataModel));
+ }
+
+ private static FolderPredictor CreateUninitializedPredictor()
+ {
+ return (FolderPredictor)
+ FormatterServices.GetUninitializedObject(typeof(FolderPredictor));
+ }
+
+ private static void SetPrivateField(object target, string fieldName, object value)
+ {
+ var field = target
+ .GetType()
+ .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
+ field.Should().NotBeNull($"{fieldName} must remain available for this headless seam");
+ field.SetValue(target, value);
+ }
+
+ ///
+ /// A null list with a concrete predictor carry is adopted as-is. Before the fix the stub
+ /// always declines, so the first assertion fails.
+ ///
+ [TestMethod]
+ public void TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts()
+ {
+ // Arrange
+ var carried = CreateUninitializedPredictor();
+
+ // Act
+ bool adopts = EfcDataModel.TryAdoptCarriedFolderHandler(
+ null,
+ carried,
+ out FolderPredictor adopted
+ );
+
+ // Assert
+ adopts.Should().BeTrue("a concrete predictor with no explicit list must be adopted");
+ adopted.Should().BeSameAs(carried, "the adopted instance is the carried instance");
+ }
+
+ /// Control: with nothing carried there is nothing to adopt.
+ [TestMethod]
+ public void TryAdoptCarriedFolderHandler_WithNullCarry_DoesNotAdopt()
+ {
+ // Act
+ bool adopts = EfcDataModel.TryAdoptCarriedFolderHandler(
+ null,
+ null,
+ out FolderPredictor adopted
+ );
+
+ // Assert
+ adopts.Should().BeFalse("a null carry cannot be adopted");
+ adopted.Should().BeNull("nothing was adopted");
+ }
+
+ ///
+ /// Control: an interface-only handler is not a predictor and cannot be adopted.
+ ///
+ [TestMethod]
+ public void TryAdoptCarriedFolderHandler_WithNonPredictorHandler_DoesNotAdopt()
+ {
+ // Arrange
+ var carried = new Mock().Object;
+
+ // Act
+ bool adopts = EfcDataModel.TryAdoptCarriedFolderHandler(
+ null,
+ carried,
+ out FolderPredictor adopted
+ );
+
+ // Assert
+ adopts.Should().BeFalse("only a concrete predictor can be adopted");
+ adopted.Should().BeNull("nothing was adopted");
+ }
+
+ /// Control: an explicit list always wins over a carried predictor.
+ [TestMethod]
+ public void TryAdoptCarriedFolderHandler_WithExplicitListAndPredictor_DoesNotAdopt()
+ {
+ // Arrange
+ var carried = CreateUninitializedPredictor();
+ var folderList = new[] { "Inbox" };
+
+ // Act
+ bool adopts = EfcDataModel.TryAdoptCarriedFolderHandler(
+ folderList,
+ carried,
+ out FolderPredictor adopted
+ );
+
+ // Assert
+ adopts.Should().BeFalse("an explicit list must run the existing list path");
+ adopted.Should().BeNull("nothing was adopted");
+ }
+
+ ///
+ /// A carried predictor becomes the model's folder helper without constructing a new one,
+ /// and the carry is released. Before the fix the existing path runs against a null
+ /// globals, so this fails either on the assertion or with the construction exception.
+ ///
+ [TestMethod]
+ public async Task InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry()
+ {
+ // Arrange
+ var model = CreateUninitializedModel();
+ var carried = CreateUninitializedPredictor();
+ model.CarriedFolderHandler = carried;
+
+ // Act
+ await model.InitFolderHandlerAsync();
+
+ // Assert
+ model.FolderHelper.Should().BeSameAs(carried, "the carried predictor must be adopted");
+ model
+ .CarriedFolderHandler.Should()
+ .BeNull("the carry must be released once it has been consumed");
+ model.CarriedMailHelper.Should().BeNull("no mail helper was carried");
+ }
+
+ ///
+ /// A non-predictor carry runs the existing null-list path (a fresh predictor over the
+ /// globals) and is released afterwards. Before the fix the moved body never consults the
+ /// adoption decision and never releases the carry, so the release assertion fails.
+ ///
+ [TestMethod]
+ public async Task InitFolderHandlerAsync_WithNonPredictorCarry_RunsTheExistingPathAndReleasesTheCarry()
+ {
+ // Arrange
+ var model = CreateUninitializedModel();
+ var ol = new Mock();
+ var globals = new Mock();
+ globals.SetupGet(g => g.Ol).Returns(ol.Object);
+ SetPrivateField(model, "_globals", globals.Object);
+ var carried = new Mock().Object;
+ model.CarriedFolderHandler = carried;
+
+ // Act
+ await model.InitFolderHandlerAsync();
+
+ // Assert
+ model.FolderHelper.Should().NotBeNull("the existing path must construct a predictor");
+ model
+ .FolderHelper.Should()
+ .NotBeSameAs(carried, "a non-predictor carry must not become the folder helper");
+ model
+ .CarriedFolderHandler.Should()
+ .BeNull("the carry must be released after the existing path has run");
+ }
+ }
+}
diff --git a/QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs b/QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs
new file mode 100644
index 000000000..7d188b720
--- /dev/null
+++ b/QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs
@@ -0,0 +1,348 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using QuickFiler.Viewers;
+using UtilitiesCS.OutlookObjects.Folder;
+
+namespace QuickFiler.Controllers.Tests
+{
+ ///
+ /// Regression tests for issue #792 on . Every test builds a
+ /// minimal controller through the private no-arg constructor, so no Outlook COM context and no
+ /// WinForms window is required. The user-facing surface is observed through
+ /// , which is per-async-flow storage, so a
+ /// capture installed here is invisible to tests running in parallel.
+ ///
+ [TestClass]
+ public sealed class EfcFormControllerIssue792Tests
+ {
+ ///
+ /// Creates an EfcFormController via the private no-arg constructor, which allocates the
+ /// object without initializing any sub-components, leaving all fields null.
+ ///
+ private static EfcFormController CreateMinimalController()
+ {
+ var ctor = typeof(EfcFormController).GetConstructor(
+ BindingFlags.NonPublic | BindingFlags.Instance,
+ null,
+ Type.EmptyTypes,
+ null
+ );
+ ctor.Should().NotBeNull("private no-arg constructor must exist on EfcFormController");
+ return (EfcFormController)ctor.Invoke(Array.Empty());
+ }
+
+ private static void SetPrivateField(object target, string fieldName, object value)
+ {
+ var field = target
+ .GetType()
+ .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
+ field.Should().NotBeNull($"{fieldName} must remain available for this headless seam");
+ field.SetValue(target, value);
+ }
+
+ ///
+ /// Routes for the current async flow into
+ /// and returns a scope that restores the previous value.
+ ///
+ private static IDisposable CaptureUserFaults(List captured)
+ {
+ var previous = EfcFormController.UserFaultNotifier;
+ EfcFormController.UserFaultNotifier = captured.Add;
+ return new NotifierScope(previous);
+ }
+
+ private sealed class NotifierScope : IDisposable
+ {
+ private readonly Action _previous;
+
+ internal NotifierScope(Action previous)
+ {
+ _previous = previous;
+ }
+
+ public void Dispose()
+ {
+ EfcFormController.UserFaultNotifier = _previous;
+ }
+ }
+
+ ///
+ /// AC-U4, PopulateFolderCombobox half (strengthened user-surface test). The sink is left
+ /// at its default so the fault must reach the user through the notifier; the existing
+ /// call-count test cannot see whether the default sink notifies anyone. This test passes
+ /// before the fix and is mutation-proven in Phase 5.
+ ///
+ [TestMethod]
+ public async Task PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var viewer = (EfcViewer)FormatterServices.GetUninitializedObject(typeof(EfcViewer));
+ SetPrivateField(controller, "_formViewer", viewer);
+ var captured = new List();
+ using (CaptureUserFaults(captured))
+ {
+ // Act
+ Func act = () => controller.PopulateFolderCombobox();
+
+ // Assert
+ await act.Should()
+ .NotThrowAsync(
+ "a fire-and-forget call site cannot observe a faulted Task, so the method"
+ + " must contain its own fault"
+ );
+ captured
+ .Should()
+ .ContainSingle(
+ "the default boundary sink must surface the contained fault to the user"
+ + " exactly once"
+ );
+ }
+ }
+
+ ///
+ /// AC-U4, InitializeBreadcrumbHostAsync half. With no host, no router and no viewer, every
+ /// attempt faults; after the attempt limit the failure must be reported through the
+ /// boundary sink to the user, naming the attempt count. Before the fix the single attempt
+ /// raises NullReferenceException, which the catch only logs, so nothing reaches the user.
+ ///
+ [TestMethod]
+ public async Task InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var method = typeof(EfcFormController).GetMethod(
+ "InitializeBreadcrumbHostAsync",
+ BindingFlags.Instance | BindingFlags.NonPublic
+ );
+ method.Should().NotBeNull("InitializeBreadcrumbHostAsync must remain available");
+ var captured = new List();
+ using (CaptureUserFaults(captured))
+ {
+ // Act
+ Func act = () => (Task)method.Invoke(controller, Array.Empty());
+
+ // Assert
+ await act.Should()
+ .NotThrowAsync(
+ "the host initializer is fire-and-forget, so it must contain its own fault"
+ );
+ captured
+ .Should()
+ .ContainSingle(
+ "the final initialization failure must be reported to the user exactly"
+ + " once"
+ )
+ .Which.Should()
+ .Contain(
+ "after 3 attempts",
+ "the report must name the exhausted attempt limit"
+ );
+ }
+ }
+
+ ///
+ /// Recording seam for . Every
+ /// invocation is counted and resolves per the scripted outcomes: a scripted exception is
+ /// returned as a faulted task, a null entry completes, and the last entry repeats once the
+ /// script is exhausted. No invocation yields, so no continuation needs a pumped thread.
+ ///
+ private sealed class ScriptedInitializer
+ {
+ private readonly Exception[] _script;
+
+ internal ScriptedInitializer(params Exception[] script)
+ {
+ _script = script;
+ }
+
+ internal int Invocations { get; private set; }
+
+ internal Task InvokeAsync()
+ {
+ int index = Math.Min(Invocations, _script.Length - 1);
+ Invocations++;
+ Exception outcome = _script[index];
+ return outcome == null ? Task.CompletedTask : Task.FromException(outcome);
+ }
+ }
+
+ private static ScriptedInitializer InstallAlwaysFailingInitializer(
+ EfcFormController controller
+ )
+ {
+ var initializer = new ScriptedInitializer(new InvalidOperationException("boom"));
+ controller.BreadcrumbHostInitializer = initializer.InvokeAsync;
+ return initializer;
+ }
+
+ ///
+ /// AC-U1: the host initializer is retried up to the attempt limit and the exhausted limit
+ /// is reported to the user exactly once. Before the fix the seam is never consulted (the
+ /// single attempt goes straight to the null host), so the invocation count is zero.
+ ///
+ [TestMethod]
+ public async Task InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var initializer = InstallAlwaysFailingInitializer(controller);
+ var captured = new List();
+ using (CaptureUserFaults(captured))
+ {
+ // Act
+ Func act = () => controller.InitializeBreadcrumbHostAsync();
+
+ // Assert
+ await act.Should().NotThrowAsync("the initializer must contain its own fault");
+ initializer
+ .Invocations.Should()
+ .Be(
+ 3,
+ "the host initializer must be attempted exactly the limit of three times"
+ );
+ captured
+ .Should()
+ .ContainSingle("the exhausted limit must be reported to the user exactly once")
+ .Which.Should()
+ .Contain(
+ "after 3 attempts",
+ "the report must name the exhausted attempt limit"
+ );
+ }
+ }
+
+ ///
+ /// AC-U1: a failure followed by a success stops the loop after the second attempt and
+ /// reports nothing. Before the fix the seam is never consulted, so the count is zero.
+ ///
+ [TestMethod]
+ public async Task InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var initializer = new ScriptedInitializer(new InvalidOperationException("boom"), null);
+ controller.BreadcrumbHostInitializer = initializer.InvokeAsync;
+ var captured = new List();
+ using (CaptureUserFaults(captured))
+ {
+ // Act
+ Func act = () => controller.InitializeBreadcrumbHostAsync();
+
+ // Assert
+ await act.Should().NotThrowAsync("a successful retry must not surface anything");
+ initializer
+ .Invocations.Should()
+ .Be(2, "the loop must stop on the first successful attempt");
+ captured.Should().BeEmpty("a recovered initialization must not be reported");
+ }
+ }
+
+ ///
+ /// AC-U1: cancellation is not a fault. It stops the loop after the first attempt and is
+ /// neither retried nor reported. Before the fix the seam is never consulted.
+ ///
+ [TestMethod]
+ public async Task InitializeBreadcrumbHostAsync_WhenCanceled_DoesNotRetryOrReport()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var initializer = new ScriptedInitializer(new OperationCanceledException());
+ controller.BreadcrumbHostInitializer = initializer.InvokeAsync;
+ var captured = new List();
+ using (CaptureUserFaults(captured))
+ {
+ // Act
+ Func act = () => controller.InitializeBreadcrumbHostAsync();
+
+ // Assert
+ await act.Should().NotThrowAsync("cancellation must be absorbed at the boundary");
+ initializer.Invocations.Should().Be(1, "a canceled attempt must not be retried");
+ captured.Should().BeEmpty("cancellation is not a fault and must not be reported");
+ }
+ }
+
+ ///
+ /// AC-U1 visible error state (D4): on final failure the folder-area label carries the
+ /// failure text. Before the fix nothing writes the label, so its text stays empty.
+ ///
+ [TestMethod]
+ public async Task InitializeBreadcrumbHostAsync_OnFinalFailure_ShowsTheErrorTextInTheFolderAreaLabel()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var viewer = (EfcViewer)FormatterServices.GetUninitializedObject(typeof(EfcViewer));
+ var label = new System.Windows.Forms.Label();
+
+ // Constructing a WinForms control installs WindowsFormsSynchronizationContext on this
+ // thread; clear it so a genuine await in the code under test cannot post its
+ // continuation to a thread that no test host pumps.
+ SynchronizationContext.SetSynchronizationContext(null);
+ SetPrivateField(viewer, "label2", label);
+ SetPrivateField(controller, "_formViewer", viewer);
+ InstallAlwaysFailingInitializer(controller);
+ using (CaptureUserFaults(new List()))
+ {
+ // Act
+ Func act = () => controller.InitializeBreadcrumbHostAsync();
+
+ // Assert
+ await act.Should().NotThrowAsync("the initializer must contain its own fault");
+ label
+ .Text.Should()
+ .Be(
+ EfcFormController.FolderAreaInitializationFailedText,
+ "the folder-area label is the visible carrier of the final failure"
+ );
+ }
+ }
+
+ ///
+ /// AC-U1/AC-U7: on final failure the router is notified, which navigates the error
+ /// banner and discards the outbound queue. Before the fix the router is never notified.
+ ///
+ [TestMethod]
+ public async Task InitializeBreadcrumbHostAsync_OnFinalFailure_NotifiesTheRouter()
+ {
+ // Arrange
+ var controller = CreateMinimalController();
+ var host = new Mock();
+ host.SetupGet(h => h.IsCoreInitialized).Returns(false);
+ var navigated = new List();
+ host.Setup(h => h.NavigateToString(It.IsAny()))
+ .Callback(html => navigated.Add(html));
+ var queue = new BreadcrumbOutboundQueue(host.Object);
+ queue.PostOrQueue("{\"type\":\"render\"}");
+ var router = new BreadcrumbBridgeRouter(
+ new Mock().Object,
+ host.Object,
+ new BreadcrumbMessageCodec(),
+ new BreadcrumbHtmlRenderer(),
+ queue
+ );
+ SetPrivateField(controller, "_router", router);
+ InstallAlwaysFailingInitializer(controller);
+ using (CaptureUserFaults(new List()))
+ {
+ // Act
+ Func act = () => controller.InitializeBreadcrumbHostAsync();
+
+ // Assert
+ await act.Should().NotThrowAsync("the initializer must contain its own fault");
+ navigated
+ .Should()
+ .ContainSingle("the router must navigate exactly one document on failure")
+ .Which.Should()
+ .Contain("Folder list unavailable", "the navigated document is the banner");
+ queue.PendingCount.Should().Be(0, "the failure must discard the outbound queue");
+ }
+ }
+ }
+}
diff --git a/QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs b/QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs
new file mode 100644
index 000000000..f561e5dc0
--- /dev/null
+++ b/QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Concurrent;
+using System.Reflection;
+using System.Runtime.Serialization;
+using FluentAssertions;
+using Microsoft.Office.Interop.Outlook;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using QuickFiler.Interfaces;
+using QuickFiler.Viewers;
+using UtilitiesCS;
+
+namespace QuickFiler.Controllers.Tests
+{
+ ///
+ /// Regression tests for issue #792 AC-U3 on the pop-out carry: the folder handler and mail
+ /// helper of the popped-out item are read from its group before the group is torn down, the
+ /// pop-out home controller is built through a named factory seam, and the home controller
+ /// deposits the carry on the data model before the form controller (whose factory fires the
+ /// carry consumer) is constructed. Controllers are allocated without a constructor, so no
+ /// Outlook COM context and no WinForms window is required.
+ ///
+ [TestClass]
+ public sealed class QfcCollectionControllerIssue792PopOutTests
+ {
+ private const string ProductionFactoryName = "CreatePopOutHomeController";
+
+ private static T CreateUninitialized()
+ where T : class
+ {
+ return (T)FormatterServices.GetUninitializedObject(typeof(T));
+ }
+
+ private static void SetPrivateField(object target, string fieldName, object value)
+ {
+ var field = target
+ .GetType()
+ .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
+ field.Should().NotBeNull($"{fieldName} must remain available for this headless seam");
+ field.SetValue(target, value);
+ }
+
+ ///
+ /// A concrete item controller exposes both its folder handler and its mail helper.
+ /// Before the fix the stub returns a null pair, so the first assertion fails.
+ ///
+ [TestMethod]
+ public void ReadPopOutCarry_WithConcreteItemController_ReturnsHandlerAndHelper()
+ {
+ // Arrange
+ var handler = new Mock().Object;
+ var helper = new Mock(MockBehavior.Loose).Object;
+ var itemController = CreateUninitialized();
+ SetPrivateField(itemController, "_folderHandler", handler);
+ SetPrivateField(itemController, "_itemInfo", helper);
+ var group = new QfcItemGroup { ItemController = itemController };
+
+ // Act
+ var carry = QfcCollectionController.ReadPopOutCarry(group);
+
+ // Assert
+ carry
+ .FolderHandler.Should()
+ .BeSameAs(handler, "the concrete controller's folder handler must be carried");
+ carry.MailHelper.Should().BeSameAs(helper, "the item helper must be carried");
+ }
+
+ ///
+ /// An interface-only controller has no folder-handler accessor, so only the helper is
+ /// carried. Before the fix the stub returns a null pair, so the helper assertion fails.
+ ///
+ [TestMethod]
+ public void ReadPopOutCarry_WithInterfaceOnlyController_ReturnsNullHandlerAndTheHelper()
+ {
+ // Arrange
+ var helper = new Mock(MockBehavior.Loose).Object;
+ var itemController = new Mock();
+ itemController.SetupGet(c => c.ItemHelper).Returns(helper);
+ var group = new QfcItemGroup { ItemController = itemController.Object };
+
+ // Act
+ var carry = QfcCollectionController.ReadPopOutCarry(group);
+
+ // Assert
+ carry
+ .FolderHandler.Should()
+ .BeNull("the interface exposes no folder handler to carry");
+ carry.MailHelper.Should().BeSameAs(helper, "the interface helper must be carried");
+ }
+
+ /// Control: a group with no controller carries nothing.
+ [TestMethod]
+ public void ReadPopOutCarry_WithNullController_ReturnsNulls()
+ {
+ // Arrange
+ var group = new QfcItemGroup();
+
+ // Act
+ var carry = QfcCollectionController.ReadPopOutCarry(group);
+
+ // Assert
+ carry.FolderHandler.Should().BeNull("there is no controller to read from");
+ carry.MailHelper.Should().BeNull("there is no controller to read from");
+ }
+
+ ///
+ /// Control: the factory seam defaults to the named production factory, accepts a
+ /// substitute by reference, and reverts to the named default when reset to null.
+ ///
+ [TestMethod]
+ public void PopOutHomeControllerFactory_DefaultIsTheNamedProductionFactory()
+ {
+ // Arrange
+ var controller = CreateUninitialized();
+ Func<
+ IApplicationGlobals,
+ System.Action,
+ MailItem,
+ IFolderSearchHandler,
+ MailItemHelper,
+ EfcHomeController
+ > recording = (globals, cleanup, mail, handler, helper) => null;
+
+ // Act and Assert
+ controller
+ .PopOutHomeControllerFactory.Method.Name.Should()
+ .Be(ProductionFactoryName, "the default must be the named production factory");
+ controller.PopOutHomeControllerFactory = recording;
+ controller
+ .PopOutHomeControllerFactory.Should()
+ .BeSameAs(recording, "a substituted factory must be returned by reference");
+ controller.PopOutHomeControllerFactory = null;
+ controller
+ .PopOutHomeControllerFactory.Method.Name.Should()
+ .Be(ProductionFactoryName, "resetting to null must restore the named default");
+ }
+
+ ///
+ /// Control after Phase 2 (mutation-proven in Phase 5): the home controller deposits the
+ /// carried handler and helper on the data model before the form-controller factory runs,
+ /// so the factory observes both at call time.
+ ///
+ [TestMethod]
+ public void EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController()
+ {
+ // Arrange
+ var mail = new Mock(MockBehavior.Loose).Object;
+ var handler = new Mock().Object;
+ var helper = new Mock(MockBehavior.Loose).Object;
+ var fileSystem = new Mock();
+ fileSystem
+ .SetupGet(f => f.SpecialFolders)
+ .Returns(new ConcurrentDictionary());
+ var globals = new Mock();
+ globals.SetupGet(g => g.FS).Returns(fileSystem.Object);
+ bool formFactoryCalled = false;
+ IFolderSearchHandler capturedHandler = null;
+ MailItemHelper capturedHelper = null;
+ var dependencies = new EfcHomeControllerDependencies(
+ dataModelFactory: (g, selectedMail, tokenSource, token) =>
+ {
+ var dataModel = CreateUninitialized();
+ SetPrivateField(dataModel, "_mail", selectedMail);
+ return dataModel;
+ },
+ viewerFactory: () => CreateUninitialized(),
+ keyboardHandlerFactory: (viewer, controller) =>
+ new Mock(MockBehavior.Loose).Object,
+ explorerControllerFactory: (initType, g, controller) =>
+ new Mock(MockBehavior.Loose).Object,
+ formControllerWithDataFactory: (
+ g,
+ dataModel,
+ viewer,
+ controller,
+ cleanup,
+ initType,
+ token
+ ) =>
+ {
+ formFactoryCalled = true;
+ capturedHandler = dataModel.CarriedFolderHandler;
+ capturedHelper = dataModel.CarriedMailHelper;
+ return CreateUninitialized();
+ }
+ );
+
+ // Act
+ var homeController = new EfcHomeController(
+ globals.Object,
+ () => { },
+ dependencies,
+ mail,
+ handler,
+ helper
+ );
+
+ // Assert
+ formFactoryCalled
+ .Should()
+ .BeTrue("a data model with mail must build the form controller");
+ capturedHandler
+ .Should()
+ .BeSameAs(handler, "the carried handler must be on the data model at factory time");
+ capturedHelper
+ .Should()
+ .BeSameAs(helper, "the carried helper must be on the data model at factory time");
+ homeController
+ .DataModel.CarriedFolderHandler.Should()
+ .BeSameAs(handler, "the deposit must persist on the constructed controller");
+ }
+ }
+}
diff --git a/QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs b/QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs
new file mode 100644
index 000000000..2a459e35a
--- /dev/null
+++ b/QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs
@@ -0,0 +1,40 @@
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using QuickFiler;
+
+namespace QuickFiler.Test.HelperClasses
+{
+ ///
+ /// Regression test for issue #792 on : the UI-thread half of the
+ /// pop-out contract is verifiable only as a scheduler-delegate identity assertion. The test
+ /// reads the delegate and writes nothing, because the only writer of these statics is a
+ /// serialized test class and a concurrent write from the parallel bucket would race it.
+ ///
+ [TestClass]
+ public sealed class EfcViewerQueueIssue792Tests
+ {
+ ///
+ /// The production blocking scheduler must be the named static method
+ /// InvokeOnUiDispatcher , not an inline lambda. The delegate is never invoked here:
+ /// the named method reaches UiThread.Dispatcher , which throws when no UI thread has
+ /// been initialized. Before the fix the default is a compiler-generated lambda whose
+ /// method name is not InvokeOnUiDispatcher .
+ ///
+ [TestMethod]
+ public void ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke()
+ {
+ // Arrange / Act - a read only; no static is written.
+ var scheduler = EfcViewerQueue.ProductionBlockingPriorityScheduler;
+
+ // Assert
+ scheduler.Should().NotBeNull("the production blocking scheduler must have a default");
+ scheduler
+ .Method.Name.Should()
+ .Be(
+ "InvokeOnUiDispatcher",
+ "the blocking scheduler must be the named UI-dispatcher invoke, not a lambda"
+ );
+ scheduler.Target.Should().BeNull("a static method group carries no target instance");
+ }
+ }
+}
diff --git a/QuickFiler.Test/QuickFiler.Test.csproj b/QuickFiler.Test/QuickFiler.Test.csproj
index cc2abb610..b3bbb2f38 100644
--- a/QuickFiler.Test/QuickFiler.Test.csproj
+++ b/QuickFiler.Test/QuickFiler.Test.csproj
@@ -57,6 +57,8 @@
+
+
@@ -123,8 +125,10 @@
+
+
@@ -165,6 +169,7 @@
+
@@ -216,6 +221,8 @@
+
+
@@ -228,6 +235,7 @@
+
diff --git a/QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs b/QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs
new file mode 100644
index 000000000..40e254cd2
--- /dev/null
+++ b/QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs
@@ -0,0 +1,153 @@
+using System;
+using System.IO;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.Web.WebView2.Core;
+using Microsoft.Web.WebView2.WinForms;
+using Moq;
+using QuickFiler.Test.TestSupport;
+using QuickFiler.Viewers;
+
+namespace QuickFiler.Test.Viewers
+{
+ ///
+ /// Regression tests for issue #792 on the WebView2 breadcrumb host. Every test constructs its
+ /// own control on , so the process-wide
+ /// per-control owner registry cannot couple one test to another. No test drives
+ /// EnsureCoreWebView2Async or CoreWebView2Environment.CreateAsync to completion,
+ /// so no Evergreen WebView2 runtime is required.
+ ///
+ [TestClass]
+ public sealed class WebView2BreadcrumbHostIssue792Tests
+ {
+ private const int PumpTimeoutMs = 60000;
+
+ ///
+ /// #792 site 1: the host must hand the shared cache folder and the shared
+ /// --incognito browser argument to the seam.
+ /// Before the fix the host builds a parameterless options object, so the captured
+ /// AdditionalBrowserArguments is null and the second assertion fails.
+ ///
+ [TestMethod]
+ [Timeout(PumpTimeoutMs)]
+ public async Task InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam()
+ {
+ // Arrange
+ using (var pump = new WinFormsPumpHost())
+ {
+ WebView2 control = await pump.InvokeAsync(() => new WebView2())
+ .ConfigureAwait(false);
+ try
+ {
+ string capturedFolder = null;
+ CoreWebView2EnvironmentOptions capturedOptions = null;
+ var initializer = new Mock();
+ initializer
+ .Setup(seam =>
+ seam.CreateEnvironmentAsync(
+ It.IsAny(),
+ It.IsAny()
+ )
+ )
+ .Callback(
+ (folder, options) =>
+ {
+ capturedFolder = folder;
+ capturedOptions = options;
+ }
+ )
+ .Returns(Task.FromResult(null));
+ initializer
+ .Setup(seam =>
+ seam.EnsureCoreWebView2Async(
+ It.IsAny(),
+ It.IsAny()
+ )
+ )
+ .Returns(Task.CompletedTask);
+ WebView2BreadcrumbHost subject = await pump.InvokeAsync(() =>
+ new WebView2BreadcrumbHost(control, initializer.Object, null)
+ )
+ .ConfigureAwait(false);
+ string expectedFolder = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "WindowsFormsWebView2"
+ );
+
+ // Act
+ await subject.InitializeAsync(pump.SyncContext).ConfigureAwait(false);
+
+ // Assert
+ capturedFolder
+ .Should()
+ .Be(
+ expectedFolder,
+ because: "the host must use the shared WindowsFormsWebView2 cache folder under LocalApplicationData"
+ );
+ capturedOptions
+ .Should()
+ .NotBeNull(
+ because: "the host must pass an options object through the seam"
+ );
+ capturedOptions
+ .AdditionalBrowserArguments.Should()
+ .Be(
+ "--incognito ",
+ because: "every WebView2 site must share the same incognito browser argument"
+ );
+ }
+ finally
+ {
+ await pump.InvokeAsync(() => control.Dispose()).ConfigureAwait(false);
+ }
+ }
+ }
+
+ ///
+ /// #792: a document handed to the host before its CoreWebView2 exists must be logged and
+ /// dropped, not forwarded. Before the fix the inline forward reaches
+ /// WebView2.NavigateToString on a control with no core, which throws
+ /// .
+ ///
+ [TestMethod]
+ [Timeout(PumpTimeoutMs)]
+ public async Task NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing()
+ {
+ // Arrange
+ using (var pump = new WinFormsPumpHost())
+ {
+ WebView2 control = await pump.InvokeAsync(() => new WebView2())
+ .ConfigureAwait(false);
+ try
+ {
+ WebView2BreadcrumbHost subject = await pump.InvokeAsync(() =>
+ new WebView2BreadcrumbHost(
+ control,
+ Mock.Of(),
+ null
+ )
+ )
+ .ConfigureAwait(false);
+
+ // Act - called from the MSTest thread; InitializeAsync never ran, so no
+ // dispatcher exists and no core exists.
+ Action act = () => subject.NavigateToString("");
+
+ // Assert
+ act.Should()
+ .NotThrow(
+ because: "a document navigated before core initialization must be dropped, not forwarded to a control with no core"
+ );
+ subject
+ .IsCoreInitialized.Should()
+ .BeFalse(because: "nothing in this test initializes the core");
+ }
+ finally
+ {
+ await pump.InvokeAsync(() => control.Dispose()).ConfigureAwait(false);
+ }
+ }
+ }
+ }
+}
diff --git a/QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs b/QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs
new file mode 100644
index 000000000..ec34d967c
--- /dev/null
+++ b/QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs
@@ -0,0 +1,192 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.Web.WebView2.Core;
+using Microsoft.Web.WebView2.WinForms;
+using Moq;
+using QuickFiler.Controllers;
+using QuickFiler.Viewers;
+
+namespace QuickFiler.Test.Viewers
+{
+ ///
+ /// Contract tests for (#792 AC-U6), the single owner
+ /// of the WebView2 environment values shared by every host in QuickFiler. All three pass
+ /// before the fix because the contract type is declared in Phase 2; their non-vacuity is
+ /// proven by mutation in Phase 5. No test touches the filesystem: the folder assertion
+ /// compares two computed strings.
+ ///
+ [TestClass]
+ public sealed class WebView2EnvironmentContractTests
+ {
+ private const string SharedLeafName = "WindowsFormsWebView2";
+
+ ///
+ /// The shared browser argument is the ASCII double-hyphen incognito switch with its
+ /// trailing space, mirroring the #463 pin on EfcItemController.IncognitoArgument .
+ ///
+ [TestMethod]
+ public void AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace()
+ {
+ // Arrange
+ const string expected = "--incognito ";
+
+ // Act
+ string actual = WebView2EnvironmentContract.AdditionalBrowserArguments;
+
+ // Assert
+ actual
+ .Should()
+ .Be(
+ expected,
+ "Chromium command-line switches are introduced by two ASCII hyphen-minus characters"
+ );
+ actual
+ .ToCharArray()
+ .Should()
+ .OnlyContain(
+ character => character <= 0x7F,
+ "a non-ASCII character in a machine-parsed switch is silently ignored"
+ );
+ actual[0].Should().Be('-', "the first character must be ASCII HYPHEN-MINUS");
+ actual[1].Should().Be('-', "the second character must be ASCII HYPHEN-MINUS");
+ }
+
+ ///
+ /// The user-data folder is LocalApplicationData joined with the shared leaf name. The
+ /// resolver is pure, so the expected value is computed the same way and compared.
+ ///
+ [TestMethod]
+ public void ResolveUserDataFolder_CombinesLocalApplicationDataWithTheSharedLeafName()
+ {
+ // Arrange
+ string expected = Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ SharedLeafName
+ );
+
+ // Act
+ string actual = WebView2EnvironmentContract.ResolveUserDataFolder();
+
+ // Assert
+ actual
+ .Should()
+ .Be(
+ expected,
+ "every WebView2 host must resolve the same user-data folder or the shared browser"
+ + " process rejects the second environment"
+ );
+ }
+
+ ///
+ /// Each call returns a distinct options instance (the SDK type is mutable) and every
+ /// instance carries the shared browser arguments.
+ ///
+ [TestMethod]
+ public void CreateOptions_CarriesTheSharedArgumentsOnAFreshInstance()
+ {
+ // Act
+ CoreWebView2EnvironmentOptions first = WebView2EnvironmentContract.CreateOptions();
+ CoreWebView2EnvironmentOptions second = WebView2EnvironmentContract.CreateOptions();
+
+ // Assert
+ first
+ .Should()
+ .NotBeSameAs(second, "the options type is mutable, so callers must not share one");
+ first
+ .AdditionalBrowserArguments.Should()
+ .Be(
+ WebView2EnvironmentContract.AdditionalBrowserArguments,
+ "the first instance must carry the shared arguments"
+ );
+ second
+ .AdditionalBrowserArguments.Should()
+ .Be(
+ WebView2EnvironmentContract.AdditionalBrowserArguments,
+ "the second instance must carry the shared arguments"
+ );
+ }
+
+ private static void SetPrivateField(object target, string fieldName, object value)
+ {
+ FieldInfo field = target
+ .GetType()
+ .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
+ field.Should().NotBeNull($"{fieldName} must remain available for this headless seam");
+ field.SetValue(target, value);
+ }
+
+ ///
+ /// #792 site 3: EfcItemController.InitializeWebViewAsync hands the contract's folder
+ /// and options to the seam; a shared context lets the UI-context await complete inline.
+ ///
+ [TestMethod]
+ public async Task EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam()
+ {
+ // Arrange
+ SynchronizationContext previous = SynchronizationContext.Current;
+ var context = new SynchronizationContext();
+ SynchronizationContext.SetSynchronizationContext(context);
+ try
+ {
+ var controller = (EfcItemController)
+ FormatterServices.GetUninitializedObject(typeof(EfcItemController));
+ var viewer = (ItemViewer)
+ FormatterServices.GetUninitializedObject(typeof(ItemViewer));
+ SetPrivateField(viewer, "_context", context);
+ SetPrivateField(controller, "_itemViewer", viewer);
+ string capturedFolder = null;
+ CoreWebView2EnvironmentOptions capturedOptions = null;
+ var initializer = new Mock();
+ initializer
+ .Setup(seam =>
+ seam.CreateEnvironmentAsync(
+ It.IsAny(),
+ It.IsAny()
+ )
+ )
+ .Callback(
+ (folder, options) =>
+ {
+ capturedFolder = folder;
+ capturedOptions = options;
+ }
+ )
+ .Returns(Task.FromResult(null));
+ initializer
+ .Setup(seam =>
+ seam.EnsureCoreWebView2Async(
+ It.IsAny(),
+ It.IsAny()
+ )
+ )
+ .Returns(Task.CompletedTask);
+ controller.WebViewInitializer = initializer.Object;
+
+ // Act
+ await controller.InitializeWebViewAsync();
+
+ // Assert
+ string expectedFolder = WebView2EnvironmentContract.ResolveUserDataFolder();
+ capturedFolder.Should().Be(expectedFolder, "the shared user-data folder");
+ capturedOptions.Should().NotBeNull("site 3 must pass an options object");
+ string expectedArguments = WebView2EnvironmentContract.AdditionalBrowserArguments;
+ string actualArguments = capturedOptions.AdditionalBrowserArguments;
+ actualArguments.Should().Be(expectedArguments, "the shared browser arguments");
+
+ // The uninitialized viewer's control and the mocked environment are both null, so
+ // the exact-argument form pins the one awaited seam call.
+ initializer.Verify(seam => seam.EnsureCoreWebView2Async(null, null), Times.Once);
+ }
+ finally
+ {
+ SynchronizationContext.SetSynchronizationContext(previous);
+ }
+ }
+ }
+}
diff --git a/QuickFiler/Controllers/BreadcrumbBridgeRouter.cs b/QuickFiler/Controllers/BreadcrumbBridgeRouter.cs
index e8d1dedd9..7037bf0b5 100644
--- a/QuickFiler/Controllers/BreadcrumbBridgeRouter.cs
+++ b/QuickFiler/Controllers/BreadcrumbBridgeRouter.cs
@@ -328,6 +328,52 @@ public void NotifyCoreInitialized()
_outboundQueue.OnInitializationCompleted();
}
+ /// Banner row text shown when initialization fails. Body lands in Phase 4 (#792).
+ internal const string InitializationFailedBannerText =
+ BreadcrumbRowBuilder.BannerPrefix
+ + " Folder list unavailable: breadcrumb initialization failed";
+
+ /// Signals that CoreWebView2 initialization failed. Body lands in Phase 4 (#792).
+ ///
+ /// Sibling of for the failure outcome (#792 D5). The
+ /// stashed document is discarded (never replayed by a later initialization), the outbound
+ /// queue is discarded rather than drained (the host cannot post to a core that does not
+ /// exist), the rows become a single banner row, the selection is cleared, and the rendered
+ /// error document is handed to the host, whose pre-initialization guard drops it without
+ /// throwing. One error line records both discard facts.
+ ///
+ /// The final initialization failure. Required.
+ public void NotifyInitializationFailed(Exception failure)
+ {
+ if (failure == null)
+ {
+ throw new ArgumentNullException(nameof(failure));
+ }
+
+ bool hadPendingDocument = _pendingDocument != null;
+ _pendingDocument = null;
+ int discardedPayloads = _outboundQueue.DiscardPending();
+ _rows = _builder.BuildRows(
+ new[] { InitializationFailedBannerText },
+ _ => null,
+ Array.Empty()
+ );
+ _selectedRowId = null;
+ if (SelectedFolderPath != null)
+ {
+ SelectedFolderPath = null;
+ SelectedFolderPathChanged?.Invoke(this, null);
+ }
+
+ _host.NavigateToString(_renderer.RenderDocument(_rows, _darkMode, null));
+ log.Error(
+ $"Breadcrumb CoreWebView2 initialization failed: {failure.Message} "
+ + $"(pending document discarded: {hadPendingDocument}; "
+ + $"outbound payloads discarded: {discardedPayloads}).",
+ failure
+ );
+ }
+
///
/// Routes one inbound bridge payload. Malformed payloads fail fast with the codec's
/// (already logged) and leave state unchanged.
diff --git a/QuickFiler/Controllers/BreadcrumbOutboundQueue.cs b/QuickFiler/Controllers/BreadcrumbOutboundQueue.cs
index eee68beb2..96e653b50 100644
--- a/QuickFiler/Controllers/BreadcrumbOutboundQueue.cs
+++ b/QuickFiler/Controllers/BreadcrumbOutboundQueue.cs
@@ -63,5 +63,18 @@ public void OnInitializationCompleted()
_host.PostMessageJson(_pending.Dequeue());
}
}
+
+ ///
+ /// Discards every buffered payload without posting and returns how many were dropped. Used
+ /// when CoreWebView2 initialization has finally failed: a never-initialized host has no core
+ /// to post to, so draining would only forward into the log-and-drop path (#792 AC-U7).
+ ///
+ /// The number of payloads that were pending before the discard.
+ public int DiscardPending()
+ {
+ int discarded = _pending.Count;
+ _pending.Clear();
+ return discarded;
+ }
}
}
diff --git a/QuickFiler/Controllers/EfcDataModel.Carry.cs b/QuickFiler/Controllers/EfcDataModel.Carry.cs
new file mode 100644
index 000000000..8b84a86b1
--- /dev/null
+++ b/QuickFiler/Controllers/EfcDataModel.Carry.cs
@@ -0,0 +1,100 @@
+using System.Threading.Tasks;
+using UtilitiesCS;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcDataModel
+ {
+ ///
+ /// Folder handler carried from a pop-out source item (#792 D7); consumed and released by
+ /// .
+ ///
+ internal IFolderSearchHandler CarriedFolderHandler { get; set; }
+
+ ///
+ /// Mail helper carried from a pop-out source item (#792 D7); used as the scoring input when
+ /// no conversation helper exists yet, then released.
+ ///
+ internal MailItemHelper CarriedMailHelper { get; set; }
+
+ ///
+ /// Pure adoption decision for a carried folder handler (#792 D7): true only when no explicit
+ /// folder list was supplied and the carry is a concrete , in
+ /// which case is that instance; otherwise false and null.
+ ///
+ internal static bool TryAdoptCarriedFolderHandler(
+ object folderList,
+ IFolderSearchHandler carried,
+ out FolderPredictor adopted
+ )
+ {
+ if (folderList is null && carried is FolderPredictor predictor)
+ {
+ adopted = predictor;
+ return true;
+ }
+
+ adopted = null;
+ return false;
+ }
+
+ public async Task InitFolderHandlerAsync(object folderList = null)
+ {
+ if (
+ TryAdoptCarriedFolderHandler(
+ folderList,
+ CarriedFolderHandler,
+ out FolderPredictor adopted
+ )
+ )
+ {
+ FolderHelper = adopted;
+ ReleaseCarry();
+ return;
+ }
+
+ if (folderList is null)
+ {
+ // Identical to the pre-#792 path whenever nothing was carried.
+ MailItemHelper scoringInput = MailInfo ?? CarriedMailHelper;
+ if (scoringInput is null)
+ {
+ FolderHelper = await Task.Run(() => new FolderPredictor(Globals), Token);
+ }
+ else
+ {
+ FolderHelper = await Task.Run(
+ async () =>
+ await new FolderPredictor(
+ Globals,
+ scoringInput,
+ FolderPredictor.InitOptions.FromField
+ ).InitAsync(scoringInput, FolderPredictor.InitOptions.FromField),
+ Token
+ );
+ }
+
+ ReleaseCarry();
+ }
+ else
+ {
+ FolderHelper = await Task.Run(
+ async () =>
+ await new FolderPredictor(
+ Globals,
+ folderList,
+ FolderPredictor.InitOptions.FromArrayOrString
+ ).InitAsync(folderList, FolderPredictor.InitOptions.FromArrayOrString),
+ Token
+ );
+ }
+ }
+
+ // The carry is single-use: once consulted it must not survive into a later re-initialization.
+ private void ReleaseCarry()
+ {
+ CarriedFolderHandler = null;
+ CarriedMailHelper = null;
+ }
+ }
+}
diff --git a/QuickFiler/Controllers/EfcDataModel.cs b/QuickFiler/Controllers/EfcDataModel.cs
index b516da416..846b4bc5a 100644
--- a/QuickFiler/Controllers/EfcDataModel.cs
+++ b/QuickFiler/Controllers/EfcDataModel.cs
@@ -185,41 +185,6 @@ public FolderPredictor FolderHelper
protected set => _folderHelper = value;
}
- public async Task InitFolderHandlerAsync(object folderList = null)
- {
- if (folderList is null)
- {
- if (MailInfo is null)
- {
- FolderHelper = await Task.Run(() => new FolderPredictor(Globals), Token);
- }
- else
- {
- FolderHelper = await Task.Run(
- async () =>
- await new FolderPredictor(
- Globals,
- MailInfo,
- FolderPredictor.InitOptions.FromField
- ).InitAsync(MailInfo, FolderPredictor.InitOptions.FromField),
- Token
- );
- }
- }
- else
- {
- FolderHelper = await Task.Run(
- async () =>
- await new FolderPredictor(
- Globals,
- folderList,
- FolderPredictor.InitOptions.FromArrayOrString
- ).InitAsync(folderList, FolderPredictor.InitOptions.FromArrayOrString),
- Token
- );
- }
- }
-
ConversationResolver _conversationResolver;
public ConversationResolver ConversationResolver
{
diff --git a/QuickFiler/Controllers/EfcFormController.Actions.cs b/QuickFiler/Controllers/EfcFormController.Actions.cs
new file mode 100644
index 000000000..921f3f6dc
--- /dev/null
+++ b/QuickFiler/Controllers/EfcFormController.Actions.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Microsoft.Office.Interop.Outlook;
+using QuickFiler.Helper_Classes;
+using QuickFiler.Interfaces;
+using QuickFiler.Properties;
+using QuickFiler.Viewers;
+using TaskVisualization;
+using ToDoModel;
+using UtilitiesCS;
+using UtilitiesCS.Interfaces.IWinForm;
+using UtilitiesCS.Threading;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcFormController
+ {
+ #region Major Actions
+
+ async public Task ActionOkAsync()
+ {
+ if (SynchronizationContext.Current is null)
+ SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
+
+ var selectedFolder = SelectedFolder;
+ // Classifies through the single owner and retains #614's rooted-path rejection.
+ if (
+ selectedFolder is null
+ || IsBannerRow(selectedFolder)
+ || !EfcSelectionGuard.IsValidFilingSelection(selectedFolder)
+ )
+ {
+ MessageBox.Show("Please select a valid folder.");
+ return;
+ }
+ else
+ {
+ _formViewer.Hide();
+ if (_initType.HasFlag(QfEnums.InitTypeEnum.Sort))
+ {
+ await _homeController.ExecuteMovesAsync();
+ }
+ else if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
+ {
+ await _homeController.OpenOlFolderAsync(SelectedFolder);
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ _formViewer.Dispose();
+ Cleanup();
+ }
+ }
+
+ public async Task ActionCancelAsync()
+ {
+ //Debug.WriteLine($"Thread Id before await: {Thread.CurrentThread.ManagedThreadId}");
+ await _formViewer.UiSyncContext;
+ //Debug.WriteLine($"Thread Id after await: {Thread.CurrentThread.ManagedThreadId}");
+ _formViewer.Close();
+ Cleanup();
+ }
+
+ /// The pseudo-row that marks the delete target.
+ internal const string TrashRowText = "Trash to Delete";
+
+ /// Prepends the trash pseudo-row, idempotently.
+ internal static string[] WithTrashRow(string[] rows)
+ {
+ if (rows is null)
+ {
+ return new[] { TrashRowText };
+ }
+ if (rows.Length > 0 && rows[0] == TrashRowText)
+ {
+ return rows;
+ }
+ var itemList = rows.ToList();
+ itemList.Insert(0, TrashRowText);
+ return itemList.ToArray();
+ }
+
+ /// Retains the delete-gesture rows, then binds them.
+ internal void ApplyDeleteGesture()
+ {
+ _folderRows = WithTrashRow(_folderRows);
+ BindFolderRows(_folderRows);
+ }
+
+ public async Task ActionDeleteAsync()
+ {
+ await _formViewer.UiSyncContext;
+ ApplyDeleteGesture();
+ }
+
+ public async Task CreateFolderAsync()
+ {
+ if (!IsValidSelection)
+ {
+ MessageBox.Show("Please select a valid folder");
+ }
+ else if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
+ {
+ await _homeController.OpenFsFolderAsync(SelectedFolder);
+ }
+ else
+ {
+ await _formViewer.UiSyncContext;
+ _formViewer.Hide();
+ if (!_globals.FS.SpecialFolders.TryGetValue("OneDrive", out var oneDrive))
+ {
+ return;
+ }
+ var folder = await Task.FromResult(
+ _dataModel.FolderHelper.CreateFolder(
+ SelectedFolder,
+ _globals.Ol.ArchiveRootPath,
+ oneDrive
+ )
+ )
+ .ConfigureAwait(false);
+ if (folder is not null)
+ {
+ await _dataModel
+ .MoveToFolderAsync(
+ folder,
+ _globals.Ol.ArchiveRootPath,
+ SaveAttachments,
+ SaveEmail,
+ SavePictures,
+ MoveConversation
+ )
+ .ConfigureAwait(false);
+ await _formViewer.UiSyncContext;
+ _formViewer.Dispose();
+ Cleanup();
+ }
+ }
+ }
+
+ /// Applies a match delegate to a search string; never returns null.
+ internal static string[] MatchesForSearchText(
+ System.Func findMatches,
+ string searchText
+ )
+ {
+ if (findMatches is null)
+ {
+ return Array.Empty();
+ }
+ return findMatches(searchText ?? string.Empty) ?? Array.Empty();
+ }
+
+ ///
+ /// #465 B (RC8): the control read happens here, on the UI thread, before any
+ /// Task.Run , carrying an unchanged value into the worker.
+ ///
+ public async Task RefreshSuggestionsAsync()
+ {
+ var searchText = _formViewer.SearchText.Text;
+
+ await Task.Run(() => _dataModel.RefreshSuggestions(), Token);
+ var matches = await Task.Run(
+ () => MatchesForSearchText(_dataModel.FindMatches, searchText),
+ Token
+ );
+
+ BindSourceFolderRows(matches);
+ }
+
+ #endregion
+ }
+}
diff --git a/QuickFiler/Controllers/EfcFormController.Breadcrumb.cs b/QuickFiler/Controllers/EfcFormController.Breadcrumb.cs
new file mode 100644
index 000000000..7c7d37cd7
--- /dev/null
+++ b/QuickFiler/Controllers/EfcFormController.Breadcrumb.cs
@@ -0,0 +1,178 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Microsoft.Office.Interop.Outlook;
+using QuickFiler.Helper_Classes;
+using QuickFiler.Interfaces;
+using QuickFiler.Properties;
+using QuickFiler.Viewers;
+using TaskVisualization;
+using ToDoModel;
+using UtilitiesCS;
+using UtilitiesCS.Interfaces.IWinForm;
+using UtilitiesCS.Threading;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcFormController
+ {
+ /// Fixed number of host initialization attempts before the failure is reported (#792).
+ internal const int BreadcrumbInitializationAttemptLimit = 3;
+
+ /// Folder-area label text shown when initialization finally fails (#792).
+ internal const string FolderAreaInitializationFailedText =
+ "Matched Folders: unavailable (breadcrumb initialization failed)";
+
+ /// Seam for the host initialization call; null selects the production host (#792).
+ internal Func BreadcrumbHostInitializer { get; set; }
+
+ // Wiring-only breadcrumb setup (#349): constructs the exempt WebView2 host adapter and the
+ // non-exempt router where ConfigureFolderTreeView previously wired the TreeListView, then
+ // connects the router's events back to the form. All breadcrumb logic lives in the router.
+ private void ConfigureBreadcrumbControl()
+ {
+ _breadcrumbHost = new WebView2BreadcrumbHost(
+ _formViewer.BreadcrumbWebView,
+ new WebView2CoreInitializer()
+ );
+ var provider = new UtilitiesCS.OutlookObjects.Folder.OutlookFolderHierarchyProvider(
+ _globals.Ol.FolderTreeService,
+ () => _globals.Ol.ArchiveRootPath
+ );
+ _router = new BreadcrumbBridgeRouter(
+ provider,
+ _breadcrumbHost,
+ new UtilitiesCS.OutlookObjects.Folder.BreadcrumbMessageCodec(),
+ new UtilitiesCS.OutlookObjects.Folder.BreadcrumbHtmlRenderer(),
+ new BreadcrumbOutboundQueue(_breadcrumbHost)
+ );
+ _breadcrumbHost.CoreInitialized += (s, e) => _router.NotifyCoreInitialized();
+ _router.FocusSearchRequested += (s, e) => _formViewer?.SearchText.Select();
+ _router.ApplyTheme(DarkMode);
+ _ = InitializeBreadcrumbHostAsync();
+ }
+
+ // Fire-and-forget host initialization with an error boundary (#792 D3): a fixed number of
+ // attempts on this awaited path, no wall-clock delay, cancellation stops the loop without
+ // being a fault. On final failure the router discards its pending document and outbound
+ // queue explicitly through NotifyInitializationFailed, the folder-area label carries the
+ // visible error state (D4), and the fault is reported once through the boundary sink.
+ internal async Task InitializeBreadcrumbHostAsync()
+ {
+ System.Exception lastFailure = null;
+ for (int attempt = 1; attempt <= BreadcrumbInitializationAttemptLimit; attempt++)
+ {
+ try
+ {
+ await InitializeBreadcrumbHostOnceAsync();
+ return;
+ }
+ catch (OperationCanceledException)
+ {
+ logger.Debug("Breadcrumb initialization canceled.");
+ return;
+ }
+ catch (System.Exception ex)
+ {
+ lastFailure = ex;
+ logger.Warn(
+ $"Breadcrumb WebView2 initialization attempt {attempt} of "
+ + $"{BreadcrumbInitializationAttemptLimit} failed: {ex.Message}",
+ ex
+ );
+ }
+ }
+
+ _router?.NotifyInitializationFailed(lastFailure);
+ ShowFolderAreaError(FolderAreaInitializationFailedText);
+ TryReportBoundaryFault(
+ $"Breadcrumb WebView2 initialization failed after {BreadcrumbInitializationAttemptLimit} attempts: {lastFailure.Message}",
+ lastFailure
+ );
+ }
+
+ // One initialization attempt: the seam when a test installed one, else the production host.
+ private Task InitializeBreadcrumbHostOnceAsync()
+ {
+ Func initializer = BreadcrumbHostInitializer;
+ return initializer != null
+ ? initializer()
+ : _breadcrumbHost.InitializeAsync(_formViewer.UiSyncContext);
+ }
+
+ // D4: a document navigated into a WebView2 whose core never initialized is not visible, so
+ // the existing folder-area label is the visible carrier of the final failure.
+ private void ShowFolderAreaError(string message)
+ {
+ Label label = _formViewer?.label2;
+ if (label == null)
+ {
+ return;
+ }
+
+ if (!label.InvokeRequired)
+ {
+ label.Text = message;
+ return;
+ }
+
+ label.BeginInvoke(new MethodInvoker(() => label.Text = message));
+ }
+
+ // Presentation only. #465 C (RC9) removed the _folderRows write-back: neither assigns
+ // nor reads the field.
+ private void BindFolderRows(string[] rows)
+ {
+ var formViewer = _formViewer;
+ if (formViewer == null || _router == null)
+ {
+ return;
+ }
+
+ _ = BindBreadcrumbRowsAsync(rows ?? Array.Empty());
+ }
+
+ // Retention plus presentation for the three source paths; retaining here rather than in
+ // BindFolderRows is what stops the delete gesture accumulating.
+ private void BindSourceFolderRows(string[] rows)
+ {
+ var formViewer = _formViewer;
+ if (formViewer == null || _router == null)
+ {
+ return;
+ }
+
+ _folderRows = rows ?? Array.Empty();
+ BindFolderRows(_folderRows);
+ }
+
+ // Async bind boundary: joins the feature-324 score projection and delegates to the router.
+ internal async Task BindBreadcrumbRowsAsync(string[] rows)
+ {
+ try
+ {
+ var scores =
+ _dataModel?.FolderHelper?.Suggestions?.ToScoredArray()
+ ?? Array.Empty();
+ await _router.BindRowsAsync(rows, scores, _globals.Ol.ArchiveRootPath, Token);
+ }
+ catch (OperationCanceledException)
+ {
+ logger.Debug("Breadcrumb bind canceled.");
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault($"Breadcrumb bind failed: {ex.Message}", ex);
+ }
+ }
+ }
+}
diff --git a/QuickFiler/Controllers/EfcFormController.EventHandlers.cs b/QuickFiler/Controllers/EfcFormController.EventHandlers.cs
new file mode 100644
index 000000000..00e35978e
--- /dev/null
+++ b/QuickFiler/Controllers/EfcFormController.EventHandlers.cs
@@ -0,0 +1,383 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Microsoft.Office.Interop.Outlook;
+using QuickFiler.Helper_Classes;
+using QuickFiler.Interfaces;
+using QuickFiler.Properties;
+using QuickFiler.Viewers;
+using TaskVisualization;
+using ToDoModel;
+using UtilitiesCS;
+using UtilitiesCS.Interfaces.IWinForm;
+using UtilitiesCS.Threading;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcFormController
+ {
+ #region Event Handlers
+
+ internal void RegisterAlwaysOnAsyncKeyActions()
+ {
+ _formViewer.KeyboardHandler.AlwaysOnKeyActionsAsync = new KbdActions<
+ Keys,
+ KaKeyAsync,
+ Func
+ >(
+ new List
+ {
+ new KaKeyAsync("Collection", Keys.Return, (k) => ActionOkAsync()),
+ }
+ );
+ }
+
+ public void WireEventHandlers()
+ {
+ //_homeController.KeyboardHandler.CharActions = new KbdActions>();
+ //_homeController.KeyboardHandler.CharActionsAsync = new KbdActions>();
+
+ _formViewer.ForAllControls(
+ x =>
+ {
+ x.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(
+ _homeController.KeyboardHandler.KeyboardHandler_PreviewKeyDownAsync
+ );
+ x.KeyDown += new System.Windows.Forms.KeyEventHandler(
+ _homeController.KeyboardHandler.KeyboardHandler_KeyDownAsync
+ );
+ },
+ new List { }
+ );
+ _formViewer.SaveAttachmentsMenuItem.CheckedChanged += SaveAttachments_CheckedChanged;
+ _formViewer.SaveEmailMenuItem.CheckedChanged += SaveEmail_CheckedChanged;
+ _formViewer.SavePicturesMenuItem.CheckedChanged += SavePictures_CheckedChanged;
+ _formViewer.ConversationMenuItem.CheckedChanged += MoveConversation_CheckedChanged;
+ _formViewer.Ok.Click += ButtonOK_Click;
+ RegisterAlwaysOnAsyncKeyActions();
+ ConfigureBreadcrumbControl();
+ _formViewer.Cancel.Click += ButtonCancel_Click;
+ _formViewer.RefreshPredicted.Click += ButtonRefresh_Click;
+ _formViewer.NewFolder.Click += ButtonCreate_Click;
+ _formViewer.BtnDelItem.Click += ButtonDelete_Click;
+ _formViewer.SearchText.TextChanged += SearchText_TextChanged;
+ _formViewer.SearchText.KeyDown += SearchText_DownArrow;
+ _formViewer.EditFiltersMenuItem.Click += EditFiltersMenuItem_Click;
+ _globals.Ol.PropertyChanged += DarkMode_Changed;
+ }
+
+ public void SearchText_DownArrow(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Down)
+ {
+ // Enter the breadcrumb list and select its first row (parity with the prior
+ // TreeListView down-arrow behavior); further key handling happens in-document.
+ _formViewer.FolderListBox.Select();
+ _router?.SelectFirstRow();
+ }
+ }
+
+ public async void ButtonCancel_Click(object sender, EventArgs e) =>
+ await ButtonCancelClickAsync();
+
+ internal async Task ButtonCancelClickAsync()
+ {
+ try
+ {
+ if (SynchronizationContext.Current is null)
+ SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
+
+ await ActionCancelAsync();
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault(ex.Message, ex);
+ }
+ }
+
+ public async void ButtonOK_Click(object sender, EventArgs e) => await ButtonOkClickAsync();
+
+ internal async Task ButtonOkClickAsync()
+ {
+ try
+ {
+ if (SynchronizationContext.Current is null)
+ SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
+
+ await ActionOkAsync();
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault(ex.Message, ex);
+ }
+ }
+
+ public async void ButtonRefresh_Click(object sender, EventArgs e) =>
+ await ButtonRefreshClickAsync();
+
+ internal async Task ButtonRefreshClickAsync()
+ {
+ try
+ {
+ if (SynchronizationContext.Current is null)
+ SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
+
+ await RefreshSuggestionsAsync();
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault(ex.Message, ex);
+ }
+ }
+
+ public async void ButtonCreate_Click(object sender, EventArgs e) =>
+ await ButtonCreateClickAsync();
+
+ internal async Task ButtonCreateClickAsync()
+ {
+ try
+ {
+ if (SynchronizationContext.Current is null)
+ SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
+
+ if (!IsValidSelection)
+ {
+ MessageBox.Show(
+ "Please select a valid parent folder where you would like to place the new folder."
+ );
+ }
+ else if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
+ {
+ await _homeController.OpenFsFolderAsync(SelectedFolder);
+
+ _formViewer.Close();
+ Cleanup();
+ }
+ else
+ {
+ if (!_globals.FS.SpecialFolders.TryGetValue("OneDrive", out var folderRoot))
+ {
+ logger.Debug($"Cannot create folder without OneDrive location");
+ return;
+ }
+ var folder =
+ (
+ await _dataModel.FolderHelper.CreateFolderAsync(
+ SelectedFolder,
+ _globals.Ol.ArchiveRootPath,
+ folderRoot,
+ Token
+ )
+ ) as MAPIFolder;
+
+ if (folder is not null)
+ {
+ await _dataModel.MoveToFolderAsync(
+ folder,
+ _globals.Ol.ArchiveRootPath,
+ SaveAttachments,
+ SaveEmail,
+ SavePictures,
+ MoveConversation
+ );
+
+ _formViewer.Close();
+ Cleanup();
+ }
+ }
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault(ex.Message, ex);
+ }
+ }
+
+ public async void ButtonDelete_Click(object sender, EventArgs e) =>
+ await ButtonDeleteClickAsync();
+
+ internal async Task ButtonDeleteClickAsync()
+ {
+ try
+ {
+ await ActionDeleteAsync();
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault(ex.Message, ex);
+ }
+ }
+
+ private void SaveAttachments_CheckedChanged(object sender, EventArgs e)
+ {
+ SaveAttachments = _formViewer.SaveAttachmentsMenuItem.Checked;
+ }
+
+ private void SaveEmail_CheckedChanged(object sender, EventArgs e)
+ {
+ SaveEmail = _formViewer.SaveEmailMenuItem.Checked;
+ }
+
+ private void SavePictures_CheckedChanged(object sender, EventArgs e)
+ {
+ SavePictures = _formViewer.SavePicturesMenuItem.Checked;
+ }
+
+ private void MoveConversation_CheckedChanged(object sender, EventArgs e)
+ {
+ MoveConversation = _formViewer.ConversationMenuItem.Checked;
+ }
+
+ private void SearchText_TextChanged(object sender, EventArgs e)
+ {
+ BindSourceFolderRows(_dataModel.FindMatches(_formViewer.SearchText.Text));
+ }
+
+ public void EditFiltersMenuItem_Click(object sender, EventArgs e)
+ {
+ var filters = new ManageFilters();
+ filters.LoadFilters(_globals);
+ filters.Show();
+ }
+
+ private KbdActions> _characterAsyncActions;
+ internal KbdActions> CharacterAsyncActions =>
+ Initializer.GetOrLoad(ref _characterAsyncActions, GetAsyncCharacterActions);
+
+ internal KbdActions> GetAsyncCharacterActions()
+ {
+ return new KbdActions>(
+ new List
+ {
+ new KaCharAsync("Controller", 'S', (x) => JumpToAsync(_formViewer.SearchText)),
+ new KaCharAsync(
+ "Controller",
+ 'F',
+ (x) => JumpToAsync(_formViewer.FolderListBox)
+ ),
+ //new KaCharAsync("Controller", 'A', (x) => ToggleCheckboxAsync(_formViewer.SaveAttachments)),
+ //new KaCharAsync("Controller", 'M', (x) => ToggleCheckboxAsync(_formViewer.SaveEmail)),
+ //new KaCharAsync("Controller", 'P', (x) => ToggleCheckboxAsync(_formViewer.SavePictures)),
+ //new KaCharAsync("Controller", 'C', (x) => ToggleCheckboxAsync(_formViewer.MoveConversation)),
+ new KaCharAsync("Controller", 'K', (x) => KbdExecuteAsync(ActionOkAsync)),
+ new KaCharAsync("Controller", 'X', (x) => KbdExecuteAsync(ActionCancelAsync)),
+ new KaCharAsync(
+ "Controller",
+ 'R',
+ (x) => KbdExecuteAsync(RefreshSuggestionsAsync)
+ ),
+ new KaCharAsync("Controller", 'N', (x) => KbdExecuteAsync(CreateFolderAsync)),
+ new KaCharAsync("Controller", 'T', (x) => KbdExecuteAsync(ActionDeleteAsync)),
+ new KaCharAsync(
+ "Controller",
+ 'M',
+ (x) => KbdExecuteAsync(() => ShowMenu(_formViewer.MoveOptionsMenu))
+ ),
+ }
+ );
+ }
+
+ //private Dictionary> _kbdActions;
+ //public Dictionary> KbdActions => Initializer.GetOrLoad(ref _kbdActions, GetKbdActions);
+ //internal Dictionary> GetKbdActions()
+ //{
+ // return new()
+ // {
+ // { 'S', async (x) => await JumpToAsync(_formViewer.SearchText) },
+ // { 'F', async (x) => await JumpToAsync(_formViewer.FolderListBox) },
+ // { 'A', async (x) => await ToggleCheckboxAsync(_formViewer.SaveAttachments) },
+ // { 'M', async (x) => await ToggleCheckboxAsync(_formViewer.SaveEmail) },
+ // { 'P', async (x) => await ToggleCheckboxAsync(_formViewer.SavePictures) },
+ // { 'C', async (x) => await ToggleCheckboxAsync(_formViewer.MoveConversation) },
+ // { 'K', async (x) => await KbdExecuteAsync(ActionOkAsync) },
+ // { 'X', async (x) => await KbdExecuteAsync(ActionCancelAsync) },
+ // { 'R', async (x) => await KbdExecuteAsync(RefreshSuggestionsAsync) },
+ // { 'N', async (x) => await KbdExecuteAsync(CreateFolderAsync) },
+ // { 'T', async (x) => await KbdExecuteAsync(ActionDeleteAsync) }
+ // };
+ //}
+
+ private KbdActions> _characterActions;
+ public KbdActions> CharacterActions =>
+ Initializer.GetOrLoad(ref _characterActions, GetKbdActions);
+
+ internal KbdActions> GetKbdActions()
+ {
+ return new KbdActions>(
+ new List
+ {
+ new KaChar(
+ "Controller",
+ 'S',
+ async (x) => await JumpToAsync(_formViewer.SearchText)
+ ),
+ new KaChar(
+ "Controller",
+ 'F',
+ async (x) => await JumpToAsync(_formViewer.FolderListBox)
+ ),
+ new KaChar(
+ "Controller",
+ 'K',
+ async (x) => await KbdExecuteAsync(ActionOkAsync)
+ ),
+ new KaChar(
+ "Controller",
+ 'X',
+ async (x) => await KbdExecuteAsync(ActionCancelAsync)
+ ),
+ new KaChar(
+ "Controller",
+ 'R',
+ async (x) => await KbdExecuteAsync(RefreshSuggestionsAsync)
+ ),
+ new KaChar(
+ "Controller",
+ 'N',
+ async (x) => await KbdExecuteAsync(CreateFolderAsync)
+ ),
+ new KaChar(
+ "Controller",
+ 'T',
+ async (x) => await KbdExecuteAsync(ActionDeleteAsync)
+ ),
+ new KaChar(
+ "Controller",
+ 'M',
+ async (x) =>
+ await KbdExecuteAsync(() => ShowMenu(_formViewer.MoveOptionsMenu))
+ ),
+ }
+ );
+ }
+
+ internal void DarkMode_Changed(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == nameof(_globals.Ol.DarkMode))
+ {
+ _darkMode = _globals.Ol.DarkMode;
+ if (DarkMode)
+ {
+ ActiveTheme = "DarkNormal";
+ }
+ else
+ {
+ ActiveTheme = "LightNormal";
+ }
+
+ // Re-theme the breadcrumb document alongside the WinForms theme swap.
+ _router?.ApplyTheme(DarkMode);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/QuickFiler/Controllers/EfcFormController.Helpers.cs b/QuickFiler/Controllers/EfcFormController.Helpers.cs
new file mode 100644
index 000000000..0825734c9
--- /dev/null
+++ b/QuickFiler/Controllers/EfcFormController.Helpers.cs
@@ -0,0 +1,270 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Microsoft.Office.Interop.Outlook;
+using QuickFiler.Helper_Classes;
+using QuickFiler.Interfaces;
+using QuickFiler.Properties;
+using QuickFiler.Viewers;
+using TaskVisualization;
+using ToDoModel;
+using UtilitiesCS;
+using UtilitiesCS.Interfaces.IWinForm;
+using UtilitiesCS.Threading;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcFormController
+ {
+ #region Helper Methods
+
+ ///
+ /// Issue #736 finding 2: the single containment point for the keyboard-dispatch path. Both
+ /// KbdExecuteAsync overloads route their two statements through this member, so the
+ /// handling is written once rather than duplicated, and a fault raised by the
+ /// keyboard-dialog toggle is covered as well as one raised by the dispatched action.
+ ///
+ internal async Task RunKbdGuardedAsync(System.Func body)
+ {
+ try
+ {
+ await body();
+ }
+ catch (OperationCanceledException)
+ {
+ // Cancellation is not a fault, so it is recorded at debug level and deliberately
+ // not reported through the sink, matching the existing distinction in
+ // BindBreadcrumbRowsAsync.
+ logger.Debug("Keyboard dispatch canceled.");
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault($"Keyboard dispatch failed: {ex.Message}", ex);
+ }
+ }
+
+ public async Task KbdExecuteAsync(Func action)
+ {
+ await RunKbdGuardedAsync(async () =>
+ {
+ await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
+ await action();
+ });
+ }
+
+ public async Task KbdExecuteAsync(System.Action action)
+ {
+ await RunKbdGuardedAsync(async () =>
+ {
+ await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
+ action();
+ });
+ }
+
+ internal async Task JumpToAsync(Control control)
+ {
+ await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
+ //await _formViewer.UiSyncContext;
+ control.Focus();
+ }
+
+ public void MaximizeFormViewer()
+ {
+ _formViewer.WindowState = System.Windows.Forms.FormWindowState.Maximized;
+ }
+
+ public void MinimizeFormViewer()
+ {
+ _formViewer.WindowState = System.Windows.Forms.FormWindowState.Minimized;
+ }
+
+ internal void ShowMenu(ToolStripMenuItem menu) => menu.ShowDropDown();
+
+ public async Task ToggleCheckboxAsync(CheckBox checkBox)
+ {
+ await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
+ checkBox.Checked = !checkBox.Checked;
+ }
+
+ public void ToggleOffNavigation(bool async)
+ {
+ CharacterActions.Keys.ForEach(key =>
+ _homeController.KeyboardHandler.CharActions.Remove("Controller", key)
+ );
+ ToggleTips(async, Enums.ToggleState.Off);
+ _itemController.ToggleNavigation(async, Enums.ToggleState.Off);
+ }
+
+ public async Task ToggleOffNavigationAsync()
+ {
+ CharacterAsyncActions.Keys.ForEach(key =>
+ _homeController.KeyboardHandler.CharActionsAsync.Remove("Controller", key)
+ );
+ await ToggleTipsAsync(Enums.ToggleState.Off);
+ await _itemController.ToggleNavigationAsync(Enums.ToggleState.Off);
+ }
+
+ public void ToggleOnNavigation(bool async)
+ {
+ CharacterActions.ForEach(x => _homeController.KeyboardHandler.CharActions.Add(x));
+ ToggleTips(async, Enums.ToggleState.On);
+ _itemController.ToggleNavigation(async, Enums.ToggleState.On);
+ }
+
+ public async Task ToggleOnNavigationAsync()
+ {
+ CharacterAsyncActions.ForEach(x =>
+ _homeController.KeyboardHandler.CharActionsAsync.Add(x)
+ );
+ await ToggleTipsAsync(Enums.ToggleState.On);
+ await _itemController.ToggleNavigationAsync(Enums.ToggleState.On);
+ }
+
+ public void ToggleTips(bool async)
+ {
+ foreach (IQfcTipsDetails tipsDetails in _listTipsDetails)
+ {
+ if (async)
+ {
+ _formViewer.BeginInvoke(new System.Action(() => tipsDetails.Toggle(true)));
+ }
+ else
+ {
+ _formViewer.Invoke(new System.Action(() => tipsDetails.Toggle(true)));
+ }
+ }
+ }
+
+ public void ToggleTips(bool async, Enums.ToggleState desiredState)
+ {
+ foreach (IQfcTipsDetails tipsDetails in _listTipsDetails)
+ {
+ if (async)
+ {
+ _formViewer.BeginInvoke(
+ new System.Action(() => tipsDetails.Toggle(desiredState, true))
+ );
+ }
+ else
+ {
+ _formViewer.Invoke(
+ new System.Action(() => tipsDetails.Toggle(desiredState, true))
+ );
+ }
+ }
+ }
+
+ public async Task ToggleTipsAsync(Enums.ToggleState desiredState)
+ {
+ Token.ThrowIfCancellationRequested();
+
+ // Attempt to remove blocking await code and start all tasks simultaneously.
+ var tasks = _listTipsDetails
+ .Select(x => x.ToggleAsync(desiredState, shareColumn: true))
+ .ToList();
+ // TODO: Check if this creates a deadlock
+ await Task.WhenAll(tasks);
+
+ // Original async code
+ //foreach (var tip in _listTipsDetails)
+ //{
+ // await tip.ToggleAsync(desiredState, shareColumn: true);
+ //}
+ }
+
+ internal void LoadUserSettings()
+ {
+ _saveAttachments = Settings.Default.SaveAttachments;
+ _formViewer.SaveAttachmentsMenuItem.Checked = _saveAttachments;
+
+ _saveEmail = Settings.Default.SaveEmail;
+ _formViewer.SaveEmailMenuItem.Checked = _saveEmail;
+
+ _savePictures = Settings.Default.SavePictures;
+ _formViewer.SavePicturesMenuItem.Checked = _savePictures;
+
+ _moveConversation = Settings.Default.MoveConversation;
+ _formViewer.ConversationMenuItem.Checked = _moveConversation;
+ }
+
+ /// #464 C: both call sites discard the result, so the boundary is here.
+ public async Task PopulateFolderCombobox(object folderList = null)
+ {
+ try
+ {
+ // Capture _formViewer in a local variable before the first await. Cleanup() may set
+ // _formViewer to null while InitFolderHandlerAsync is executing (e.g. the user
+ // dismisses the form), so all post-await access must go through this local reference.
+ var formViewer = _formViewer;
+ if (formViewer == null)
+ return;
+
+ await _dataModel.InitFolderHandlerAsync(folderList);
+
+ await formViewer.UiSyncContext;
+
+ BindSourceFolderRows(_dataModel.FolderHelper.FolderArray);
+ }
+ catch (System.Exception ex)
+ {
+ TryReportBoundaryFault(ex.Message, ex);
+ }
+ }
+
+ // #465 D (RC7): single classification owner. StartsWith, never Substring, over the
+ internal static bool IsBannerRow(string row) =>
+ row is not null
+ && row.StartsWith(
+ UtilitiesCS.OutlookObjects.Folder.BreadcrumbRowBuilder.BannerPrefix,
+ StringComparison.Ordinal
+ );
+
+ // The rest of IsValidSelection's pure logic, routed through the owner above.
+ internal static bool IsSelectableFolder(string selectedFolder) =>
+ !IsBannerRow(selectedFolder)
+ && EfcSelectionGuard.IsValidCreationSelection(selectedFolder);
+
+ internal bool IsValidSelection => IsSelectableFolder(SelectedFolder);
+
+ #endregion
+
+ public void ToggleExpansionStyle(Enums.ToggleState desiredState)
+ {
+ if (desiredState == Enums.ToggleState.On)
+ {
+ _itemTlp.RowStyles[_itemViewerTlpRow].Height = _tlpHeightExpanded;
+ _formViewer.MinimumSize = new Size(
+ _formViewer.MinimumSize.Width,
+ _formViewer.MinimumSize.Height + _tlpHeightDiff
+ );
+ _formViewer.Size = new Size(
+ _formViewer.Size.Width,
+ _formViewer.Size.Height + _tlpHeightDiff
+ );
+ _formViewer.WindowState = FormWindowState.Maximized;
+ }
+ else
+ {
+ _formViewer.WindowState = FormWindowState.Normal;
+ _itemTlp.RowStyles[_itemViewerTlpRow].Height = _tlpHeightCollapsed;
+ _formViewer.MinimumSize = new Size(
+ _formViewer.MinimumSize.Width,
+ _formViewer.MinimumSize.Height - _tlpHeightDiff
+ );
+ _formViewer.Size = new Size(
+ _formViewer.Size.Width,
+ _formViewer.Size.Height - _tlpHeightDiff
+ );
+ }
+ }
+ }
+}
diff --git a/QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs b/QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs
new file mode 100644
index 000000000..e5094fd6c
--- /dev/null
+++ b/QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs
@@ -0,0 +1,243 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Microsoft.Office.Interop.Outlook;
+using QuickFiler.Helper_Classes;
+using QuickFiler.Interfaces;
+using QuickFiler.Properties;
+using QuickFiler.Viewers;
+using TaskVisualization;
+using ToDoModel;
+using UtilitiesCS;
+using UtilitiesCS.Interfaces.IWinForm;
+using UtilitiesCS.Threading;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcFormController
+ {
+ #region Setup and Cleanup Methods
+
+ internal void CaptureConfigureItemViewer()
+ {
+ var explorerSize = _globals.Ol.GetExplorerScreenSize();
+ _tlpHeightExpanded = (int)Math.Round(_itemTlp.RowStyles[1].Height, 0);
+ var heightDiff = _tlpHeightExpanded - _itemViewer.Height;
+ _tlpHeightCollapsed = _itemViewer.MinimumSize.Height + heightDiff;
+ _tlpHeightDiff = _tlpHeightExpanded - _tlpHeightCollapsed;
+ _itemViewerTlpRow = _itemTlp.GetPositionFromControl(_itemViewer).Row;
+ ToggleExpansionStyle(Enums.ToggleState.Off);
+ var itemTlpRows = _itemViewer.L0vh_Tlp.RowStyles.Cast().Take(5);
+ var bodyRow = itemTlpRows.ElementAt(4);
+ var bodyRowHeight =
+ _tlpHeightCollapsed
+ - itemTlpRows.Select(x => x.Height).Sum(x => x)
+ + bodyRow.Height;
+ bodyRow.Height = bodyRowHeight;
+ _formViewer.MinimumSize = new Size(
+ (int)(explorerSize.Width * 0.75),
+ (int)(explorerSize.Height * 0.75)
+ );
+ _formViewer.Size = _formViewer.MinimumSize;
+ }
+
+ /// Releases collaborators. Safe on a partial controller and idempotent.
+ public void Cleanup()
+ {
+ // Detach before nulling: release the subscription before dropping its owner.
+ var globals = _globals;
+ if (globals?.Ol is not null)
+ {
+ globals.Ol.PropertyChanged -= DarkMode_Changed;
+ }
+ _globals = null;
+ _formViewer = null;
+ _dataModel = null;
+
+ // Clearing before invoking is what makes the single invocation structural.
+ var parentCleanup = _parentCleanup;
+ _parentCleanup = null;
+ if (parentCleanup is not null)
+ {
+ parentCleanup.Invoke();
+ }
+ }
+
+ public void ConfigureFind()
+ {
+ if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
+ {
+ _formViewer.Text = "Quick Filer - Find Folder";
+ _formViewer.Ok.Text = "Open Outlook Folder";
+ _formViewer.NewFolder.Text = "Open File System Folder";
+ }
+ }
+
+ internal void ResolveControlGroups()
+ {
+ _listTipsDetails = _formViewer
+ .TipsLabels.Select(x => (IQfcTipsDetails)new QfcTipsDetails(x))
+ .ToList();
+ _listTipsDetails.ForEach(x => x.Toggle(Enums.ToggleState.Off, true));
+
+ var starter = _formViewer.GetAllChildren(except: new List { _itemViewer });
+
+ _listButtons = starter.Where(x => x is Button).Cast().ToList();
+
+ _listCheckBox = starter.Where(x => (x is CheckBox)).ToList();
+
+ _listHighlighted = new List
+ {
+ _formViewer.SearchText,
+ _formViewer.FolderListBox,
+ };
+
+ _listDefault = starter
+ .Where(x =>
+ !_formViewer.TipsLabels.Contains(x)
+ && !_listButtons.Contains(x)
+ && !_listHighlighted.Contains(x)
+ && !_listCheckBox.Contains(x)
+ )
+ .ToList();
+ }
+
+ internal void SetupThemes()
+ {
+ _themes = EfcThemeHelper.SetupFormThemes(
+ _formViewer.TipsLabels.Cast().ToList(),
+ _listHighlighted,
+ _listDefault,
+ _listButtons.Cast().ToList(),
+ _listCheckBox
+ );
+
+ _activeTheme = LoadTheme();
+ }
+
+ #endregion Setup and Cleanup Methods
+
+ #region Public Properties
+
+ private string _activeTheme;
+ public string ActiveTheme
+ {
+ // GetOrLoad throws under strict: true once _themes is null, so test at the call
+ // site and return the backing field on the torn-down path.
+ get =>
+ _themes is null
+ ? _activeTheme
+ : Initializer.GetOrLoad(ref _activeTheme, LoadTheme, strict: true, _themes);
+ set =>
+ Initializer.SetAndSave(
+ ref _activeTheme,
+ value,
+ (x) => _themes[x].SetTheme(async: true)
+ );
+ }
+
+ internal string LoadTheme()
+ {
+ var activeTheme = DarkMode ? "DarkNormal" : "LightNormal";
+ if (_themes is not null && _themes.ContainsKey(activeTheme))
+ {
+ _themes[activeTheme].SetTheme();
+ }
+ return activeTheme;
+ }
+
+ private bool _darkMode;
+ public bool DarkMode
+ {
+ // The params object[] dependency array is materialised before GetOrLoad is entered,
+ // so _globals.Ol must be tested at the call site or the null path still dereferences.
+ get =>
+ _globals?.Ol is null
+ ? _darkMode
+ : Initializer.GetOrLoad(
+ ref _darkMode,
+ () => _globals.Ol.DarkMode,
+ false,
+ _globals,
+ _globals.Ol
+ );
+ set => Initializer.SetAndSave(ref _darkMode, value, (x) => _globals.Ol.DarkMode = x);
+ }
+
+ public IntPtr FormHandle => _formViewer.Handle;
+
+ public string SelectedFolder
+ {
+ // Derived from the bridge router's selection tracking. IsValidSelection routes to
+ // IsSelectableFolder, which composes IsBannerRow, matching the producers' "===="
+ // prefix, with the guard's deliberately broader three-character rejection.
+ get => _router?.SelectedFolderPath;
+ }
+
+ private bool _saveAttachments;
+ public bool SaveAttachments
+ {
+ get => _saveAttachments;
+ set
+ {
+ _saveAttachments = value;
+ // Should be set elsewhere as a user default
+ //Settings.Default.SaveAttachments = value;
+ }
+ }
+
+ private bool _saveEmail;
+ public bool SaveEmail
+ {
+ get => _saveEmail;
+ set
+ {
+ _saveEmail = value;
+ // Should be set elsewhere as a user default
+ //Settings.Default.SaveEmail = value;
+ }
+ }
+
+ private bool _savePictures;
+ public bool SavePictures
+ {
+ get => _savePictures;
+ set
+ {
+ _savePictures = value;
+ // Should be set elsewhere as a user default
+ //Settings.Default.SavePictures = value;
+ }
+ }
+
+ private bool _moveConversation;
+ public bool MoveConversation
+ {
+ get => _moveConversation;
+ set
+ {
+ _moveConversation = value;
+ // Should be set elsewhere as a user default
+ //Settings.Default.MoveConversation = value;
+ }
+ }
+
+ private CancellationToken _token;
+ public CancellationToken Token
+ {
+ get => _token;
+ set => _token = value;
+ }
+
+ #endregion
+ }
+}
diff --git a/QuickFiler/Controllers/EfcFormController.cs b/QuickFiler/Controllers/EfcFormController.cs
index 9019b939d..a1de1c173 100644
--- a/QuickFiler/Controllers/EfcFormController.cs
+++ b/QuickFiler/Controllers/EfcFormController.cs
@@ -23,7 +23,7 @@
namespace QuickFiler.Controllers
{
- internal class EfcFormController : IFilerFormController
+ internal partial class EfcFormController : IFilerFormController
{
#region Constructors
@@ -262,1060 +262,5 @@ private static void ShowModelessFaultNotice(string message)
private List _listHighlighted;
#endregion Private Properties
-
- #region Setup and Cleanup Methods
-
- internal void CaptureConfigureItemViewer()
- {
- var explorerSize = _globals.Ol.GetExplorerScreenSize();
- _tlpHeightExpanded = (int)Math.Round(_itemTlp.RowStyles[1].Height, 0);
- var heightDiff = _tlpHeightExpanded - _itemViewer.Height;
- _tlpHeightCollapsed = _itemViewer.MinimumSize.Height + heightDiff;
- _tlpHeightDiff = _tlpHeightExpanded - _tlpHeightCollapsed;
- _itemViewerTlpRow = _itemTlp.GetPositionFromControl(_itemViewer).Row;
- ToggleExpansionStyle(Enums.ToggleState.Off);
- var itemTlpRows = _itemViewer.L0vh_Tlp.RowStyles.Cast().Take(5);
- var bodyRow = itemTlpRows.ElementAt(4);
- var bodyRowHeight =
- _tlpHeightCollapsed
- - itemTlpRows.Select(x => x.Height).Sum(x => x)
- + bodyRow.Height;
- bodyRow.Height = bodyRowHeight;
- _formViewer.MinimumSize = new Size(
- (int)(explorerSize.Width * 0.75),
- (int)(explorerSize.Height * 0.75)
- );
- _formViewer.Size = _formViewer.MinimumSize;
- }
-
- /// Releases collaborators. Safe on a partial controller and idempotent.
- public void Cleanup()
- {
- // Detach before nulling: release the subscription before dropping its owner.
- var globals = _globals;
- if (globals?.Ol is not null)
- {
- globals.Ol.PropertyChanged -= DarkMode_Changed;
- }
- _globals = null;
- _formViewer = null;
- _dataModel = null;
-
- // Clearing before invoking is what makes the single invocation structural.
- var parentCleanup = _parentCleanup;
- _parentCleanup = null;
- if (parentCleanup is not null)
- {
- parentCleanup.Invoke();
- }
- }
-
- public void ConfigureFind()
- {
- if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
- {
- _formViewer.Text = "Quick Filer - Find Folder";
- _formViewer.Ok.Text = "Open Outlook Folder";
- _formViewer.NewFolder.Text = "Open File System Folder";
- }
- }
-
- internal void ResolveControlGroups()
- {
- _listTipsDetails = _formViewer
- .TipsLabels.Select(x => (IQfcTipsDetails)new QfcTipsDetails(x))
- .ToList();
- _listTipsDetails.ForEach(x => x.Toggle(Enums.ToggleState.Off, true));
-
- var starter = _formViewer.GetAllChildren(except: new List { _itemViewer });
-
- _listButtons = starter.Where(x => x is Button).Cast().ToList();
-
- _listCheckBox = starter.Where(x => (x is CheckBox)).ToList();
-
- _listHighlighted = new List
- {
- _formViewer.SearchText,
- _formViewer.FolderListBox,
- };
-
- _listDefault = starter
- .Where(x =>
- !_formViewer.TipsLabels.Contains(x)
- && !_listButtons.Contains(x)
- && !_listHighlighted.Contains(x)
- && !_listCheckBox.Contains(x)
- )
- .ToList();
- }
-
- internal void SetupThemes()
- {
- _themes = EfcThemeHelper.SetupFormThemes(
- _formViewer.TipsLabels.Cast().ToList(),
- _listHighlighted,
- _listDefault,
- _listButtons.Cast().ToList(),
- _listCheckBox
- );
-
- _activeTheme = LoadTheme();
- }
-
- #endregion Setup and Cleanup Methods
-
- #region Public Properties
-
- private string _activeTheme;
- public string ActiveTheme
- {
- // GetOrLoad throws under strict: true once _themes is null, so test at the call
- // site and return the backing field on the torn-down path.
- get =>
- _themes is null
- ? _activeTheme
- : Initializer.GetOrLoad(ref _activeTheme, LoadTheme, strict: true, _themes);
- set =>
- Initializer.SetAndSave(
- ref _activeTheme,
- value,
- (x) => _themes[x].SetTheme(async: true)
- );
- }
-
- internal string LoadTheme()
- {
- var activeTheme = DarkMode ? "DarkNormal" : "LightNormal";
- if (_themes is not null && _themes.ContainsKey(activeTheme))
- {
- _themes[activeTheme].SetTheme();
- }
- return activeTheme;
- }
-
- private bool _darkMode;
- public bool DarkMode
- {
- // The params object[] dependency array is materialised before GetOrLoad is entered,
- // so _globals.Ol must be tested at the call site or the null path still dereferences.
- get =>
- _globals?.Ol is null
- ? _darkMode
- : Initializer.GetOrLoad(
- ref _darkMode,
- () => _globals.Ol.DarkMode,
- false,
- _globals,
- _globals.Ol
- );
- set => Initializer.SetAndSave(ref _darkMode, value, (x) => _globals.Ol.DarkMode = x);
- }
-
- public IntPtr FormHandle => _formViewer.Handle;
-
- public string SelectedFolder
- {
- // Derived from the bridge router's selection tracking. IsValidSelection routes to
- // IsSelectableFolder, which composes IsBannerRow, matching the producers' "===="
- // prefix, with the guard's deliberately broader three-character rejection.
- get => _router?.SelectedFolderPath;
- }
-
- private bool _saveAttachments;
- public bool SaveAttachments
- {
- get => _saveAttachments;
- set
- {
- _saveAttachments = value;
- // Should be set elsewhere as a user default
- //Settings.Default.SaveAttachments = value;
- }
- }
-
- private bool _saveEmail;
- public bool SaveEmail
- {
- get => _saveEmail;
- set
- {
- _saveEmail = value;
- // Should be set elsewhere as a user default
- //Settings.Default.SaveEmail = value;
- }
- }
-
- private bool _savePictures;
- public bool SavePictures
- {
- get => _savePictures;
- set
- {
- _savePictures = value;
- // Should be set elsewhere as a user default
- //Settings.Default.SavePictures = value;
- }
- }
-
- private bool _moveConversation;
- public bool MoveConversation
- {
- get => _moveConversation;
- set
- {
- _moveConversation = value;
- // Should be set elsewhere as a user default
- //Settings.Default.MoveConversation = value;
- }
- }
-
- private CancellationToken _token;
- public CancellationToken Token
- {
- get => _token;
- set => _token = value;
- }
-
- #endregion
-
- #region Event Handlers
-
- internal void RegisterAlwaysOnAsyncKeyActions()
- {
- _formViewer.KeyboardHandler.AlwaysOnKeyActionsAsync = new KbdActions<
- Keys,
- KaKeyAsync,
- Func
- >(
- new List
- {
- new KaKeyAsync("Collection", Keys.Return, (k) => ActionOkAsync()),
- }
- );
- }
-
- public void WireEventHandlers()
- {
- //_homeController.KeyboardHandler.CharActions = new KbdActions>();
- //_homeController.KeyboardHandler.CharActionsAsync = new KbdActions>();
-
- _formViewer.ForAllControls(
- x =>
- {
- x.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(
- _homeController.KeyboardHandler.KeyboardHandler_PreviewKeyDownAsync
- );
- x.KeyDown += new System.Windows.Forms.KeyEventHandler(
- _homeController.KeyboardHandler.KeyboardHandler_KeyDownAsync
- );
- },
- new List { }
- );
- _formViewer.SaveAttachmentsMenuItem.CheckedChanged += SaveAttachments_CheckedChanged;
- _formViewer.SaveEmailMenuItem.CheckedChanged += SaveEmail_CheckedChanged;
- _formViewer.SavePicturesMenuItem.CheckedChanged += SavePictures_CheckedChanged;
- _formViewer.ConversationMenuItem.CheckedChanged += MoveConversation_CheckedChanged;
- _formViewer.Ok.Click += ButtonOK_Click;
- RegisterAlwaysOnAsyncKeyActions();
- ConfigureBreadcrumbControl();
- _formViewer.Cancel.Click += ButtonCancel_Click;
- _formViewer.RefreshPredicted.Click += ButtonRefresh_Click;
- _formViewer.NewFolder.Click += ButtonCreate_Click;
- _formViewer.BtnDelItem.Click += ButtonDelete_Click;
- _formViewer.SearchText.TextChanged += SearchText_TextChanged;
- _formViewer.SearchText.KeyDown += SearchText_DownArrow;
- _formViewer.EditFiltersMenuItem.Click += EditFiltersMenuItem_Click;
- _globals.Ol.PropertyChanged += DarkMode_Changed;
- }
-
- public void SearchText_DownArrow(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Down)
- {
- // Enter the breadcrumb list and select its first row (parity with the prior
- // TreeListView down-arrow behavior); further key handling happens in-document.
- _formViewer.FolderListBox.Select();
- _router?.SelectFirstRow();
- }
- }
-
- public async void ButtonCancel_Click(object sender, EventArgs e) =>
- await ButtonCancelClickAsync();
-
- internal async Task ButtonCancelClickAsync()
- {
- try
- {
- if (SynchronizationContext.Current is null)
- SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
-
- await ActionCancelAsync();
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault(ex.Message, ex);
- }
- }
-
- public async void ButtonOK_Click(object sender, EventArgs e) => await ButtonOkClickAsync();
-
- internal async Task ButtonOkClickAsync()
- {
- try
- {
- if (SynchronizationContext.Current is null)
- SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
-
- await ActionOkAsync();
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault(ex.Message, ex);
- }
- }
-
- public async void ButtonRefresh_Click(object sender, EventArgs e) =>
- await ButtonRefreshClickAsync();
-
- internal async Task ButtonRefreshClickAsync()
- {
- try
- {
- if (SynchronizationContext.Current is null)
- SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
-
- await RefreshSuggestionsAsync();
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault(ex.Message, ex);
- }
- }
-
- public async void ButtonCreate_Click(object sender, EventArgs e) =>
- await ButtonCreateClickAsync();
-
- internal async Task ButtonCreateClickAsync()
- {
- try
- {
- if (SynchronizationContext.Current is null)
- SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
-
- if (!IsValidSelection)
- {
- MessageBox.Show(
- "Please select a valid parent folder where you would like to place the new folder."
- );
- }
- else if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
- {
- await _homeController.OpenFsFolderAsync(SelectedFolder);
-
- _formViewer.Close();
- Cleanup();
- }
- else
- {
- if (!_globals.FS.SpecialFolders.TryGetValue("OneDrive", out var folderRoot))
- {
- logger.Debug($"Cannot create folder without OneDrive location");
- return;
- }
- var folder =
- (
- await _dataModel.FolderHelper.CreateFolderAsync(
- SelectedFolder,
- _globals.Ol.ArchiveRootPath,
- folderRoot,
- Token
- )
- ) as MAPIFolder;
-
- if (folder is not null)
- {
- await _dataModel.MoveToFolderAsync(
- folder,
- _globals.Ol.ArchiveRootPath,
- SaveAttachments,
- SaveEmail,
- SavePictures,
- MoveConversation
- );
-
- _formViewer.Close();
- Cleanup();
- }
- }
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault(ex.Message, ex);
- }
- }
-
- public async void ButtonDelete_Click(object sender, EventArgs e) =>
- await ButtonDeleteClickAsync();
-
- internal async Task ButtonDeleteClickAsync()
- {
- try
- {
- await ActionDeleteAsync();
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault(ex.Message, ex);
- }
- }
-
- private void SaveAttachments_CheckedChanged(object sender, EventArgs e)
- {
- SaveAttachments = _formViewer.SaveAttachmentsMenuItem.Checked;
- }
-
- private void SaveEmail_CheckedChanged(object sender, EventArgs e)
- {
- SaveEmail = _formViewer.SaveEmailMenuItem.Checked;
- }
-
- private void SavePictures_CheckedChanged(object sender, EventArgs e)
- {
- SavePictures = _formViewer.SavePicturesMenuItem.Checked;
- }
-
- private void MoveConversation_CheckedChanged(object sender, EventArgs e)
- {
- MoveConversation = _formViewer.ConversationMenuItem.Checked;
- }
-
- private void SearchText_TextChanged(object sender, EventArgs e)
- {
- BindSourceFolderRows(_dataModel.FindMatches(_formViewer.SearchText.Text));
- }
-
- public void EditFiltersMenuItem_Click(object sender, EventArgs e)
- {
- var filters = new ManageFilters();
- filters.LoadFilters(_globals);
- filters.Show();
- }
-
- private KbdActions> _characterAsyncActions;
- internal KbdActions> CharacterAsyncActions =>
- Initializer.GetOrLoad(ref _characterAsyncActions, GetAsyncCharacterActions);
-
- internal KbdActions> GetAsyncCharacterActions()
- {
- return new KbdActions>(
- new List
- {
- new KaCharAsync("Controller", 'S', (x) => JumpToAsync(_formViewer.SearchText)),
- new KaCharAsync(
- "Controller",
- 'F',
- (x) => JumpToAsync(_formViewer.FolderListBox)
- ),
- //new KaCharAsync("Controller", 'A', (x) => ToggleCheckboxAsync(_formViewer.SaveAttachments)),
- //new KaCharAsync("Controller", 'M', (x) => ToggleCheckboxAsync(_formViewer.SaveEmail)),
- //new KaCharAsync("Controller", 'P', (x) => ToggleCheckboxAsync(_formViewer.SavePictures)),
- //new KaCharAsync("Controller", 'C', (x) => ToggleCheckboxAsync(_formViewer.MoveConversation)),
- new KaCharAsync("Controller", 'K', (x) => KbdExecuteAsync(ActionOkAsync)),
- new KaCharAsync("Controller", 'X', (x) => KbdExecuteAsync(ActionCancelAsync)),
- new KaCharAsync(
- "Controller",
- 'R',
- (x) => KbdExecuteAsync(RefreshSuggestionsAsync)
- ),
- new KaCharAsync("Controller", 'N', (x) => KbdExecuteAsync(CreateFolderAsync)),
- new KaCharAsync("Controller", 'T', (x) => KbdExecuteAsync(ActionDeleteAsync)),
- new KaCharAsync(
- "Controller",
- 'M',
- (x) => KbdExecuteAsync(() => ShowMenu(_formViewer.MoveOptionsMenu))
- ),
- }
- );
- }
-
- //private Dictionary> _kbdActions;
- //public Dictionary> KbdActions => Initializer.GetOrLoad(ref _kbdActions, GetKbdActions);
- //internal Dictionary> GetKbdActions()
- //{
- // return new()
- // {
- // { 'S', async (x) => await JumpToAsync(_formViewer.SearchText) },
- // { 'F', async (x) => await JumpToAsync(_formViewer.FolderListBox) },
- // { 'A', async (x) => await ToggleCheckboxAsync(_formViewer.SaveAttachments) },
- // { 'M', async (x) => await ToggleCheckboxAsync(_formViewer.SaveEmail) },
- // { 'P', async (x) => await ToggleCheckboxAsync(_formViewer.SavePictures) },
- // { 'C', async (x) => await ToggleCheckboxAsync(_formViewer.MoveConversation) },
- // { 'K', async (x) => await KbdExecuteAsync(ActionOkAsync) },
- // { 'X', async (x) => await KbdExecuteAsync(ActionCancelAsync) },
- // { 'R', async (x) => await KbdExecuteAsync(RefreshSuggestionsAsync) },
- // { 'N', async (x) => await KbdExecuteAsync(CreateFolderAsync) },
- // { 'T', async (x) => await KbdExecuteAsync(ActionDeleteAsync) }
- // };
- //}
-
- private KbdActions> _characterActions;
- public KbdActions> CharacterActions =>
- Initializer.GetOrLoad(ref _characterActions, GetKbdActions);
-
- internal KbdActions> GetKbdActions()
- {
- return new KbdActions>(
- new List
- {
- new KaChar(
- "Controller",
- 'S',
- async (x) => await JumpToAsync(_formViewer.SearchText)
- ),
- new KaChar(
- "Controller",
- 'F',
- async (x) => await JumpToAsync(_formViewer.FolderListBox)
- ),
- new KaChar(
- "Controller",
- 'K',
- async (x) => await KbdExecuteAsync(ActionOkAsync)
- ),
- new KaChar(
- "Controller",
- 'X',
- async (x) => await KbdExecuteAsync(ActionCancelAsync)
- ),
- new KaChar(
- "Controller",
- 'R',
- async (x) => await KbdExecuteAsync(RefreshSuggestionsAsync)
- ),
- new KaChar(
- "Controller",
- 'N',
- async (x) => await KbdExecuteAsync(CreateFolderAsync)
- ),
- new KaChar(
- "Controller",
- 'T',
- async (x) => await KbdExecuteAsync(ActionDeleteAsync)
- ),
- new KaChar(
- "Controller",
- 'M',
- async (x) =>
- await KbdExecuteAsync(() => ShowMenu(_formViewer.MoveOptionsMenu))
- ),
- }
- );
- }
-
- internal void DarkMode_Changed(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == nameof(_globals.Ol.DarkMode))
- {
- _darkMode = _globals.Ol.DarkMode;
- if (DarkMode)
- {
- ActiveTheme = "DarkNormal";
- }
- else
- {
- ActiveTheme = "LightNormal";
- }
-
- // Re-theme the breadcrumb document alongside the WinForms theme swap.
- _router?.ApplyTheme(DarkMode);
- }
- }
-
- #endregion
-
- #region Major Actions
-
- async public Task ActionOkAsync()
- {
- if (SynchronizationContext.Current is null)
- SynchronizationContext.SetSynchronizationContext(_formViewer.UiSyncContext);
-
- var selectedFolder = SelectedFolder;
- // Classifies through the single owner and retains #614's rooted-path rejection.
- if (
- selectedFolder is null
- || IsBannerRow(selectedFolder)
- || !EfcSelectionGuard.IsValidFilingSelection(selectedFolder)
- )
- {
- MessageBox.Show("Please select a valid folder.");
- return;
- }
- else
- {
- _formViewer.Hide();
- if (_initType.HasFlag(QfEnums.InitTypeEnum.Sort))
- {
- await _homeController.ExecuteMovesAsync();
- }
- else if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
- {
- await _homeController.OpenOlFolderAsync(SelectedFolder);
- }
- else
- {
- throw new NotImplementedException();
- }
- _formViewer.Dispose();
- Cleanup();
- }
- }
-
- public async Task ActionCancelAsync()
- {
- //Debug.WriteLine($"Thread Id before await: {Thread.CurrentThread.ManagedThreadId}");
- await _formViewer.UiSyncContext;
- //Debug.WriteLine($"Thread Id after await: {Thread.CurrentThread.ManagedThreadId}");
- _formViewer.Close();
- Cleanup();
- }
-
- /// The pseudo-row that marks the delete target.
- internal const string TrashRowText = "Trash to Delete";
-
- /// Prepends the trash pseudo-row, idempotently.
- internal static string[] WithTrashRow(string[] rows)
- {
- if (rows is null)
- {
- return new[] { TrashRowText };
- }
- if (rows.Length > 0 && rows[0] == TrashRowText)
- {
- return rows;
- }
- var itemList = rows.ToList();
- itemList.Insert(0, TrashRowText);
- return itemList.ToArray();
- }
-
- /// Retains the delete-gesture rows, then binds them.
- internal void ApplyDeleteGesture()
- {
- _folderRows = WithTrashRow(_folderRows);
- BindFolderRows(_folderRows);
- }
-
- public async Task ActionDeleteAsync()
- {
- await _formViewer.UiSyncContext;
- ApplyDeleteGesture();
- }
-
- public async Task CreateFolderAsync()
- {
- if (!IsValidSelection)
- {
- MessageBox.Show("Please select a valid folder");
- }
- else if (_initType.HasFlag(QfEnums.InitTypeEnum.Find))
- {
- await _homeController.OpenFsFolderAsync(SelectedFolder);
- }
- else
- {
- await _formViewer.UiSyncContext;
- _formViewer.Hide();
- if (!_globals.FS.SpecialFolders.TryGetValue("OneDrive", out var oneDrive))
- {
- return;
- }
- var folder = await Task.FromResult(
- _dataModel.FolderHelper.CreateFolder(
- SelectedFolder,
- _globals.Ol.ArchiveRootPath,
- oneDrive
- )
- )
- .ConfigureAwait(false);
- if (folder is not null)
- {
- await _dataModel
- .MoveToFolderAsync(
- folder,
- _globals.Ol.ArchiveRootPath,
- SaveAttachments,
- SaveEmail,
- SavePictures,
- MoveConversation
- )
- .ConfigureAwait(false);
- await _formViewer.UiSyncContext;
- _formViewer.Dispose();
- Cleanup();
- }
- }
- }
-
- /// Applies a match delegate to a search string; never returns null.
- internal static string[] MatchesForSearchText(
- System.Func findMatches,
- string searchText
- )
- {
- if (findMatches is null)
- {
- return Array.Empty();
- }
- return findMatches(searchText ?? string.Empty) ?? Array.Empty();
- }
-
- ///
- /// #465 B (RC8): the control read happens here, on the UI thread, before any
- /// Task.Run , carrying an unchanged value into the worker.
- ///
- public async Task RefreshSuggestionsAsync()
- {
- var searchText = _formViewer.SearchText.Text;
-
- await Task.Run(() => _dataModel.RefreshSuggestions(), Token);
- var matches = await Task.Run(
- () => MatchesForSearchText(_dataModel.FindMatches, searchText),
- Token
- );
-
- BindSourceFolderRows(matches);
- }
-
- #endregion
-
- #region Helper Methods
-
- ///
- /// Issue #736 finding 2: the single containment point for the keyboard-dispatch path. Both
- /// KbdExecuteAsync overloads route their two statements through this member, so the
- /// handling is written once rather than duplicated, and a fault raised by the
- /// keyboard-dialog toggle is covered as well as one raised by the dispatched action.
- ///
- internal async Task RunKbdGuardedAsync(System.Func body)
- {
- try
- {
- await body();
- }
- catch (OperationCanceledException)
- {
- // Cancellation is not a fault, so it is recorded at debug level and deliberately
- // not reported through the sink, matching the existing distinction in
- // BindBreadcrumbRowsAsync.
- logger.Debug("Keyboard dispatch canceled.");
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault($"Keyboard dispatch failed: {ex.Message}", ex);
- }
- }
-
- public async Task KbdExecuteAsync(Func action)
- {
- await RunKbdGuardedAsync(async () =>
- {
- await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
- await action();
- });
- }
-
- public async Task KbdExecuteAsync(System.Action action)
- {
- await RunKbdGuardedAsync(async () =>
- {
- await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
- action();
- });
- }
-
- internal async Task JumpToAsync(Control control)
- {
- await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
- //await _formViewer.UiSyncContext;
- control.Focus();
- }
-
- // Wiring-only breadcrumb setup (#349): constructs the exempt WebView2 host adapter and the
- // non-exempt router where ConfigureFolderTreeView previously wired the TreeListView, then
- // connects the router's events back to the form. All breadcrumb logic lives in the router.
- private void ConfigureBreadcrumbControl()
- {
- _breadcrumbHost = new WebView2BreadcrumbHost(
- _formViewer.BreadcrumbWebView,
- new WebView2CoreInitializer()
- );
- var provider = new UtilitiesCS.OutlookObjects.Folder.OutlookFolderHierarchyProvider(
- _globals.Ol.FolderTreeService,
- () => _globals.Ol.ArchiveRootPath
- );
- _router = new BreadcrumbBridgeRouter(
- provider,
- _breadcrumbHost,
- new UtilitiesCS.OutlookObjects.Folder.BreadcrumbMessageCodec(),
- new UtilitiesCS.OutlookObjects.Folder.BreadcrumbHtmlRenderer(),
- new BreadcrumbOutboundQueue(_breadcrumbHost)
- );
- _breadcrumbHost.CoreInitialized += (s, e) => _router.NotifyCoreInitialized();
- _router.FocusSearchRequested += (s, e) => _formViewer?.SearchText.Select();
- _router.ApplyTheme(DarkMode);
- _ = InitializeBreadcrumbHostAsync();
- }
-
- // Fire-and-forget host initialization with an error boundary (the router queues every
- // outbound payload until CoreWebView2InitializationCompleted fires).
- private async Task InitializeBreadcrumbHostAsync()
- {
- try
- {
- await _breadcrumbHost.InitializeAsync(_formViewer.UiSyncContext);
- }
- catch (System.Exception ex)
- {
- logger.Error($"Breadcrumb WebView2 initialization failed: {ex.Message}", ex);
- }
- }
-
- // Presentation only. #465 C (RC9) removed the _folderRows write-back: neither assigns
- // nor reads the field.
- private void BindFolderRows(string[] rows)
- {
- var formViewer = _formViewer;
- if (formViewer == null || _router == null)
- {
- return;
- }
-
- _ = BindBreadcrumbRowsAsync(rows ?? Array.Empty());
- }
-
- // Retention plus presentation for the three source paths; retaining here rather than in
- // BindFolderRows is what stops the delete gesture accumulating.
- private void BindSourceFolderRows(string[] rows)
- {
- var formViewer = _formViewer;
- if (formViewer == null || _router == null)
- {
- return;
- }
-
- _folderRows = rows ?? Array.Empty();
- BindFolderRows(_folderRows);
- }
-
- // Async bind boundary: joins the feature-324 score projection and delegates to the router.
- internal async Task BindBreadcrumbRowsAsync(string[] rows)
- {
- try
- {
- var scores =
- _dataModel?.FolderHelper?.Suggestions?.ToScoredArray()
- ?? Array.Empty();
- await _router.BindRowsAsync(rows, scores, _globals.Ol.ArchiveRootPath, Token);
- }
- catch (OperationCanceledException)
- {
- logger.Debug("Breadcrumb bind canceled.");
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault($"Breadcrumb bind failed: {ex.Message}", ex);
- }
- }
-
- public void MaximizeFormViewer()
- {
- _formViewer.WindowState = System.Windows.Forms.FormWindowState.Maximized;
- }
-
- public void MinimizeFormViewer()
- {
- _formViewer.WindowState = System.Windows.Forms.FormWindowState.Minimized;
- }
-
- internal void ShowMenu(ToolStripMenuItem menu) => menu.ShowDropDown();
-
- public async Task ToggleCheckboxAsync(CheckBox checkBox)
- {
- await _homeController.KeyboardHandler.ToggleKeyboardDialogAsync();
- checkBox.Checked = !checkBox.Checked;
- }
-
- public void ToggleOffNavigation(bool async)
- {
- CharacterActions.Keys.ForEach(key =>
- _homeController.KeyboardHandler.CharActions.Remove("Controller", key)
- );
- ToggleTips(async, Enums.ToggleState.Off);
- _itemController.ToggleNavigation(async, Enums.ToggleState.Off);
- }
-
- public async Task ToggleOffNavigationAsync()
- {
- CharacterAsyncActions.Keys.ForEach(key =>
- _homeController.KeyboardHandler.CharActionsAsync.Remove("Controller", key)
- );
- await ToggleTipsAsync(Enums.ToggleState.Off);
- await _itemController.ToggleNavigationAsync(Enums.ToggleState.Off);
- }
-
- public void ToggleOnNavigation(bool async)
- {
- CharacterActions.ForEach(x => _homeController.KeyboardHandler.CharActions.Add(x));
- ToggleTips(async, Enums.ToggleState.On);
- _itemController.ToggleNavigation(async, Enums.ToggleState.On);
- }
-
- public async Task ToggleOnNavigationAsync()
- {
- CharacterAsyncActions.ForEach(x =>
- _homeController.KeyboardHandler.CharActionsAsync.Add(x)
- );
- await ToggleTipsAsync(Enums.ToggleState.On);
- await _itemController.ToggleNavigationAsync(Enums.ToggleState.On);
- }
-
- public void ToggleTips(bool async)
- {
- foreach (IQfcTipsDetails tipsDetails in _listTipsDetails)
- {
- if (async)
- {
- _formViewer.BeginInvoke(new System.Action(() => tipsDetails.Toggle(true)));
- }
- else
- {
- _formViewer.Invoke(new System.Action(() => tipsDetails.Toggle(true)));
- }
- }
- }
-
- public void ToggleTips(bool async, Enums.ToggleState desiredState)
- {
- foreach (IQfcTipsDetails tipsDetails in _listTipsDetails)
- {
- if (async)
- {
- _formViewer.BeginInvoke(
- new System.Action(() => tipsDetails.Toggle(desiredState, true))
- );
- }
- else
- {
- _formViewer.Invoke(
- new System.Action(() => tipsDetails.Toggle(desiredState, true))
- );
- }
- }
- }
-
- public async Task ToggleTipsAsync(Enums.ToggleState desiredState)
- {
- Token.ThrowIfCancellationRequested();
-
- // Attempt to remove blocking await code and start all tasks simultaneously.
- var tasks = _listTipsDetails
- .Select(x => x.ToggleAsync(desiredState, shareColumn: true))
- .ToList();
- // TODO: Check if this creates a deadlock
- await Task.WhenAll(tasks);
-
- // Original async code
- //foreach (var tip in _listTipsDetails)
- //{
- // await tip.ToggleAsync(desiredState, shareColumn: true);
- //}
- }
-
- internal void LoadUserSettings()
- {
- _saveAttachments = Settings.Default.SaveAttachments;
- _formViewer.SaveAttachmentsMenuItem.Checked = _saveAttachments;
-
- _saveEmail = Settings.Default.SaveEmail;
- _formViewer.SaveEmailMenuItem.Checked = _saveEmail;
-
- _savePictures = Settings.Default.SavePictures;
- _formViewer.SavePicturesMenuItem.Checked = _savePictures;
-
- _moveConversation = Settings.Default.MoveConversation;
- _formViewer.ConversationMenuItem.Checked = _moveConversation;
- }
-
- /// #464 C: both call sites discard the result, so the boundary is here.
- public async Task PopulateFolderCombobox(object folderList = null)
- {
- try
- {
- // Capture _formViewer in a local variable before the first await. Cleanup() may set
- // _formViewer to null while InitFolderHandlerAsync is executing (e.g. the user
- // dismisses the form), so all post-await access must go through this local reference.
- var formViewer = _formViewer;
- if (formViewer == null)
- return;
-
- await _dataModel.InitFolderHandlerAsync(folderList);
-
- await formViewer.UiSyncContext;
-
- BindSourceFolderRows(_dataModel.FolderHelper.FolderArray);
- }
- catch (System.Exception ex)
- {
- TryReportBoundaryFault(ex.Message, ex);
- }
- }
-
- // #465 D (RC7): single classification owner. StartsWith, never Substring, over the
- internal static bool IsBannerRow(string row) =>
- row is not null
- && row.StartsWith(
- UtilitiesCS.OutlookObjects.Folder.BreadcrumbRowBuilder.BannerPrefix,
- StringComparison.Ordinal
- );
-
- // The rest of IsValidSelection's pure logic, routed through the owner above.
- internal static bool IsSelectableFolder(string selectedFolder) =>
- !IsBannerRow(selectedFolder)
- && EfcSelectionGuard.IsValidCreationSelection(selectedFolder);
-
- internal bool IsValidSelection => IsSelectableFolder(SelectedFolder);
-
- #endregion
-
- public void ToggleExpansionStyle(Enums.ToggleState desiredState)
- {
- if (desiredState == Enums.ToggleState.On)
- {
- _itemTlp.RowStyles[_itemViewerTlpRow].Height = _tlpHeightExpanded;
- _formViewer.MinimumSize = new Size(
- _formViewer.MinimumSize.Width,
- _formViewer.MinimumSize.Height + _tlpHeightDiff
- );
- _formViewer.Size = new Size(
- _formViewer.Size.Width,
- _formViewer.Size.Height + _tlpHeightDiff
- );
- _formViewer.WindowState = FormWindowState.Maximized;
- }
- else
- {
- _formViewer.WindowState = FormWindowState.Normal;
- _itemTlp.RowStyles[_itemViewerTlpRow].Height = _tlpHeightCollapsed;
- _formViewer.MinimumSize = new Size(
- _formViewer.MinimumSize.Width,
- _formViewer.MinimumSize.Height - _tlpHeightDiff
- );
- _formViewer.Size = new Size(
- _formViewer.Size.Width,
- _formViewer.Size.Height - _tlpHeightDiff
- );
- }
- }
}
}
diff --git a/QuickFiler/Controllers/EfcHomeController.cs b/QuickFiler/Controllers/EfcHomeController.cs
index d2e9ef7fd..93e59d2c2 100644
--- a/QuickFiler/Controllers/EfcHomeController.cs
+++ b/QuickFiler/Controllers/EfcHomeController.cs
@@ -47,15 +47,26 @@ private static EfcHomeControllerDependencies CreateDefaultDependencies()
public EfcHomeController(
IApplicationGlobals globals,
System.Action parentCleanup,
- MailItem mail = null
+ MailItem mail = null,
+ IFolderSearchHandler carriedFolderHandler = null,
+ MailItemHelper carriedMailHelper = null
)
- : this(globals, parentCleanup, CreateDefaultDependencies(), mail) { }
+ : this(
+ globals,
+ parentCleanup,
+ CreateDefaultDependencies(),
+ mail,
+ carriedFolderHandler,
+ carriedMailHelper
+ ) { }
internal EfcHomeController(
IApplicationGlobals globals,
System.Action parentCleanup,
EfcHomeControllerDependencies dependencies,
- MailItem mail = null
+ MailItem mail = null,
+ IFolderSearchHandler carriedFolderHandler = null,
+ MailItemHelper carriedMailHelper = null
)
{
dependencies.ThrowIfNull();
@@ -70,6 +81,12 @@ internal EfcHomeController(
this.Token
);
+ // #792 AC-U3: deposit the pop-out carry before the form controller is built, because
+ // FormControllerWithDataFactory calls Initialize(), which fires PopulateFolderCombobox
+ // and therefore InitFolderHandlerAsync, the consumer of the carry.
+ DataModel.CarriedFolderHandler = carriedFolderHandler;
+ DataModel.CarriedMailHelper = carriedMailHelper;
+
if (DataModel.Mail is not null)
{
InitType = QfEnums.InitTypeEnum.Sort | QfEnums.InitTypeEnum.SortConv;
diff --git a/QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs b/QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs
new file mode 100644
index 000000000..41fcfd51a
--- /dev/null
+++ b/QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Web.WebView2.Core;
+using QuickFiler.Viewers;
+using UtilitiesCS;
+
+namespace QuickFiler.Controllers
+{
+ internal partial class EfcItemController
+ {
+ private IWebViewCoreInitializer _webViewInitializer;
+
+ ///
+ /// Seam over WebView2 environment creation for the EFC item viewer (#792).
+ /// is routed through it so a test can observe the
+ /// values handed to the SDK without starting a browser process.
+ ///
+ internal IWebViewCoreInitializer WebViewInitializer
+ {
+ get => _webViewInitializer ??= new WebView2CoreInitializer();
+ set => _webViewInitializer = value;
+ }
+
+ ///
+ /// The additional browser argument handed to
+ /// so that the item preview keeps no browsing data.
+ ///
+ ///
+ /// The owner of this value is (#792); this alias
+ /// exists so the #463 pin
+ /// EfcItemControllerTests.IncognitoArgument_IsAsciiDoubleHyphenIncognitoWithTrailingSpace
+ /// keeps asserting the value the preview actually passes.
+ ///
+ internal const string IncognitoArgument =
+ WebView2EnvironmentContract.AdditionalBrowserArguments;
+
+ internal async Task InitializeWebViewAsync()
+ {
+ string cacheFolder = WebView2EnvironmentContract.ResolveUserDataFolder();
+ CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();
+
+ await _itemViewer.UiSyncContext;
+
+ // Both seam calls are awaited (no detached continuation) so a failure reaches
+ // InitializeWebViewGuardedAsync instead of being lost off the awaited path (#792).
+ _webViewEnvironment = await WebViewInitializer.CreateEnvironmentAsync(
+ cacheFolder,
+ options
+ );
+ await WebViewInitializer.EnsureCoreWebView2Async(
+ _itemViewer.L0v2h2_WebView2,
+ _webViewEnvironment
+ );
+ }
+ }
+}
diff --git a/QuickFiler/Controllers/EfcItemController.cs b/QuickFiler/Controllers/EfcItemController.cs
index 020bfdf93..069c72d49 100644
--- a/QuickFiler/Controllers/EfcItemController.cs
+++ b/QuickFiler/Controllers/EfcItemController.cs
@@ -165,52 +165,6 @@ private void Initialize(bool async)
#region Item Setup and Disposal Methods
- ///
- /// The additional browser argument handed to
- /// so that the item preview keeps no browsing data.
- ///
- ///
- /// Hoisted to a constant so the value has exactly one owner and can be asserted directly.
- /// A direct assertion is the only instrument available for it: the enclosing member needs
- /// the real WebView2 runtime, so it cannot be executed under the unit-test policy.
- ///
- internal const string IncognitoArgument = "--incognito ";
-
- internal async Task InitializeWebViewAsync()
- {
- // Create the cache directory
- string localAppData = Environment.GetFolderPath(
- Environment.SpecialFolder.LocalApplicationData
- );
- string cacheFolder = Path.Combine(localAppData, "WindowsFormsWebView2");
-
- // CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions("--disk-cache-size=1 ");
- CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions(
- IncognitoArgument
- );
-
- await _itemViewer.UiSyncContext;
- //logger.Debug($"Ui Thread Id: {Thread.CurrentThread.ManagedThreadId}");
- // Create the environment manually
- Task task = CoreWebView2Environment.CreateAsync(
- null,
- cacheFolder,
- options
- );
-
- // Do this so the task is continued on the UI Thread
- TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();
-
- await task.ContinueWith(
- t =>
- {
- _webViewEnvironment = task.Result;
- _itemViewer.L0v2h2_WebView2.EnsureCoreWebView2Async(_webViewEnvironment);
- },
- ui
- );
- }
-
internal void AdjustViewerForEfc()
{
// Collapse the right side of the navigation, disable all right side controls, and make them invisible
diff --git a/QuickFiler/Controllers/QfcCollectionController.PopOut.cs b/QuickFiler/Controllers/QfcCollectionController.PopOut.cs
new file mode 100644
index 000000000..ebb7cc511
--- /dev/null
+++ b/QuickFiler/Controllers/QfcCollectionController.PopOut.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.Office.Interop.Outlook;
+using QuickFiler.Interfaces;
+using UtilitiesCS;
+
+namespace QuickFiler.Controllers
+{
+ public partial class QfcCollectionController
+ {
+ private Func<
+ IApplicationGlobals,
+ System.Action,
+ MailItem,
+ IFolderSearchHandler,
+ MailItemHelper,
+ EfcHomeController
+ > _popOutHomeControllerFactory;
+
+ ///
+ /// Factory seam for the pop-out home controller; null selects the production factory
+ /// (#792 AC-U3).
+ ///
+ internal Func<
+ IApplicationGlobals,
+ System.Action,
+ MailItem,
+ IFolderSearchHandler,
+ MailItemHelper,
+ EfcHomeController
+ > PopOutHomeControllerFactory
+ {
+ get => _popOutHomeControllerFactory ?? CreatePopOutHomeController;
+ set => _popOutHomeControllerFactory = value;
+ }
+
+ private static EfcHomeController CreatePopOutHomeController(
+ IApplicationGlobals globals,
+ System.Action parentCleanup,
+ MailItem mailItem,
+ IFolderSearchHandler carriedFolderHandler,
+ MailItemHelper carriedMailHelper
+ )
+ {
+ return new EfcHomeController(
+ globals,
+ parentCleanup,
+ mailItem,
+ carriedFolderHandler,
+ carriedMailHelper
+ );
+ }
+
+ ///
+ /// Reads the folder handler and mail helper carried by a group's item controller (#792 D6).
+ /// Pure: the handler is read through the concrete
+ /// accessor by pattern match, the helper through ;
+ /// a null group or controller yields a null pair.
+ ///
+ internal static (
+ IFolderSearchHandler FolderHandler,
+ MailItemHelper MailHelper
+ ) ReadPopOutCarry(QfcItemGroup group)
+ {
+ IQfcItemController controller = group?.ItemController;
+ return (
+ controller is QfcItemController concrete ? concrete.FolderHandler : null,
+ controller?.ItemHelper
+ );
+ }
+
+ ///
+ /// Pops the selected group out into its own EFC home controller. The carry is read BEFORE
+ /// the removal call because QfcItemController.Cleanup nulls _folderHandler and
+ /// ItemHelper ; the home controller is built through the factory seam (#792 D6).
+ ///
+ public void PopOutControlGroup(int selection)
+ {
+ QfcItemGroup group = _itemGroups[selection - 1];
+ MailItem mailItem = group.MailItem;
+ (IFolderSearchHandler handler, MailItemHelper helper) = ReadPopOutCarry(group);
+
+ // Remove the group from the form
+ RemoveSpecificControlGroup(selection);
+
+ var form = PopOutHomeControllerFactory(_globals, () => { }, mailItem, handler, helper);
+ form.Run();
+ }
+
+ ///
+ /// Async form of . The carry is read BEFORE the removal call
+ /// because QfcItemController.Cleanup nulls _folderHandler and
+ /// ItemHelper ; the home controller is built through the factory seam (#792 D6).
+ ///
+ public async Task PopOutControlGroupAsync(int selection)
+ {
+ Token.ThrowIfCancellationRequested();
+
+ QfcItemGroup group = _itemGroups[selection - 1];
+ MailItem mailItem = group.MailItem;
+ (IFolderSearchHandler handler, MailItemHelper helper) = ReadPopOutCarry(group);
+
+ // Remove the group from the form
+ await RemoveSpecificControlGroupAsync(selection);
+
+ var form = PopOutHomeControllerFactory(_globals, () => { }, mailItem, handler, helper);
+
+ await form.RunAsync();
+ }
+ }
+}
diff --git a/QuickFiler/Controllers/QfcCollectionController.cs b/QuickFiler/Controllers/QfcCollectionController.cs
index 4d6f7e35e..54cf7470c 100644
--- a/QuickFiler/Controllers/QfcCollectionController.cs
+++ b/QuickFiler/Controllers/QfcCollectionController.cs
@@ -711,33 +711,6 @@ public ItemViewer LoadItemViewer_03(
return itemViewer;
}
- public void PopOutControlGroup(int selection)
- {
- // Get mail item from the group
- MailItem mailItem = _itemGroups[selection - 1].MailItem;
-
- // Remove the group from the form
- RemoveSpecificControlGroup(selection);
-
- var popOutForm = new EfcHomeController(_globals, () => { }, mailItem);
- popOutForm.Run();
- }
-
- public async Task PopOutControlGroupAsync(int selection)
- {
- Token.ThrowIfCancellationRequested();
-
- // Get mail item from the group
- MailItem mailItem = _itemGroups[selection - 1].MailItem;
-
- // Remove the group from the form
- await RemoveSpecificControlGroupAsync(selection);
-
- var popOutForm = new EfcHomeController(_globals, () => { }, mailItem);
-
- await popOutForm.RunAsync();
- }
-
public void RemoveControls()
{
if (_itemGroups is not null)
diff --git a/QuickFiler/Controllers/QfcItemController.ViewerSetup.cs b/QuickFiler/Controllers/QfcItemController.ViewerSetup.cs
index 742aab12f..f08c85b21 100644
--- a/QuickFiler/Controllers/QfcItemController.ViewerSetup.cs
+++ b/QuickFiler/Controllers/QfcItemController.ViewerSetup.cs
@@ -52,14 +52,9 @@ internal async Task InitializeWebViewAsync()
Token.ThrowIfCancellationRequested();
- // Create the cache directory
- string localAppData = Environment.GetFolderPath(
- Environment.SpecialFolder.LocalApplicationData
- );
- string cacheFolder = Path.Combine(localAppData, "WindowsFormsWebView2");
-
- // CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions("--disk-cache-size=1 ");
- CoreWebView2EnvironmentOptions options = new("--incognito ");
+ // #792: shared user-data folder and browser arguments come from the single contract.
+ string cacheFolder = WebView2EnvironmentContract.ResolveUserDataFolder();
+ CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();
// Switch to UI Thread
await _itemViewer.UiSyncContext;
diff --git a/QuickFiler/Controllers/QfcItemController.cs b/QuickFiler/Controllers/QfcItemController.cs
index b67db7c6a..70c87961a 100644
--- a/QuickFiler/Controllers/QfcItemController.cs
+++ b/QuickFiler/Controllers/QfcItemController.cs
@@ -264,6 +264,12 @@ public string SelectedFolder
///
public long TopFolderScore => _folderHandler?.Suggestions?.TopScore() ?? 0;
+ ///
+ /// Read-only accessor over the folder handler for the pop-out carry (#792 AC-U3). Null
+ /// after Cleanup, so callers must read it before the group is removed.
+ ///
+ internal IFolderSearchHandler FolderHandler => _folderHandler;
+
public bool SuppressEvents
{
get => _suppressEvents;
diff --git a/QuickFiler/Helper Classes/EfcViewerQueue.cs b/QuickFiler/Helper Classes/EfcViewerQueue.cs
index d1930cf73..80c552c89 100644
--- a/QuickFiler/Helper Classes/EfcViewerQueue.cs
+++ b/QuickFiler/Helper Classes/EfcViewerQueue.cs
@@ -22,7 +22,7 @@ internal static Action<
internal static Action<
Action,
DispatcherPriority
- > ProductionBlockingPriorityScheduler { get; set; } = (action, priority) => action();
+ > ProductionBlockingPriorityScheduler { get; set; } = InvokeOnUiDispatcher;
private static ViewerQueueCore _core = CreateProductionCore();
@@ -65,9 +65,16 @@ internal static void ResetProductionCoreDefaultsForTesting()
ProductionSynchronousScheduler = action => action();
ProductionPriorityScheduler = (action, priority) =>
_ = UiThread.Dispatcher.InvokeAsync(action, priority);
- ProductionBlockingPriorityScheduler = (action, priority) => action();
+ ProductionBlockingPriorityScheduler = InvokeOnUiDispatcher;
}
+ ///
+ /// Named UI-dispatcher invoke that is the blocking priority scheduler default, mirroring
+ /// ItemViewerQueue so the delegate identity is assertable (#792 AC-U3).
+ ///
+ internal static void InvokeOnUiDispatcher(Action action, DispatcherPriority priority) =>
+ UiThread.Dispatcher.Invoke(action, priority);
+
private static ViewerQueueCore CreateProductionCore()
{
return CreateProductionCore(
diff --git a/QuickFiler/QuickFiler.csproj b/QuickFiler/QuickFiler.csproj
index e9bbea7f5..6612eaf61 100644
--- a/QuickFiler/QuickFiler.csproj
+++ b/QuickFiler/QuickFiler.csproj
@@ -288,12 +288,18 @@
+
+
+
+
+
+
@@ -302,6 +308,7 @@
+
@@ -313,6 +320,7 @@
+
@@ -424,6 +432,7 @@
+
diff --git a/QuickFiler/Viewers/WebView2BreadcrumbHost.cs b/QuickFiler/Viewers/WebView2BreadcrumbHost.cs
index 0c129783f..63a1e2600 100644
--- a/QuickFiler/Viewers/WebView2BreadcrumbHost.cs
+++ b/QuickFiler/Viewers/WebView2BreadcrumbHost.cs
@@ -1,7 +1,6 @@
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
-using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
@@ -14,10 +13,10 @@ namespace QuickFiler.Viewers
///
/// Adapter implementing over the Designer-owned
/// control (#349). Initialization awaits the form's UI
- /// SynchronizationContext BEFORE EnsureCoreWebView2Async, and uses the shared
- /// %LocalAppData%\WindowsFormsWebView2 cache folder through the existing
- /// seam. Waiting is event-driven
- /// (CoreWebView2InitializationCompleted) — no polling, no delays. Every SDK touch outside the
+ /// SynchronizationContext BEFORE EnsureCoreWebView2Async, and resolves the shared user-data
+ /// folder and browser arguments from (#792) before
+ /// handing them to the existing seam. Waiting is
+ /// event-driven (CoreWebView2InitializationCompleted) — no polling, no delays. Every SDK touch outside the
/// SDK's own event callbacks is marshalled through one
/// callback, and exactly one host owns a given control at a time.
///
@@ -152,18 +151,36 @@ internal WebView2BreadcrumbHost(
/// fire-and-forget, so this member returns before the forward executes; order between
/// successive calls is preserved by the single post queue. Before InitializeAsync has
/// installed a dispatcher there is none to marshal through, and the callback executes inline
- /// on the calling thread exactly as it did before this change.
+ /// on the calling thread exactly as it did before this change. The CoreWebView2 read,
+ /// the null guard and the log-and-drop run inside the same callback as the forward (#792):
+ /// a document handed over before the core exists is dropped rather than forwarded to a
+ /// control that would throw.
///
public void NavigateToString(string html)
{
+ // One unit of work, so the read and the forward cannot be split across two dispatch hops.
+ void NavigateCore()
+ {
+ CoreWebView2? core = _control.CoreWebView2;
+ if (core == null)
+ {
+ log.Error(
+ "NavigateToString called before CoreWebView2 initialization; document dropped."
+ );
+ return;
+ }
+
+ ForwardNavigateToString(html);
+ }
+
BreadcrumbUiDispatcher? dispatcher = _dispatcher;
if (dispatcher == null)
{
- ForwardNavigateToString(html);
+ NavigateCore();
return;
}
- _ = dispatcher.Dispatch(() => ForwardNavigateToString(html));
+ _ = dispatcher.Dispatch(NavigateCore);
}
/// The unavoidable SDK call behind .
@@ -243,11 +260,8 @@ public async Task InitializeAsync(SynchronizationContext uiSyncContext)
throw new ArgumentNullException(nameof(uiSyncContext));
}
- string cacheFolder = Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
- "WindowsFormsWebView2"
- );
- var options = new CoreWebView2EnvironmentOptions();
+ string cacheFolder = WebView2EnvironmentContract.ResolveUserDataFolder();
+ CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();
// Capture variant V1: build the UI marshalling boundary from the context the caller
// already supplies, so the constructor gains no new throwing precondition. Assign only
diff --git a/QuickFiler/Viewers/WebView2EnvironmentContract.cs b/QuickFiler/Viewers/WebView2EnvironmentContract.cs
new file mode 100644
index 000000000..ecb2dbe51
--- /dev/null
+++ b/QuickFiler/Viewers/WebView2EnvironmentContract.cs
@@ -0,0 +1,53 @@
+#nullable enable
+using System;
+using System.IO;
+using Microsoft.Web.WebView2.Core;
+
+namespace QuickFiler.Viewers
+{
+ ///
+ /// Single owner of the WebView2 environment values shared by every WebView2 host in QuickFiler
+ /// (#792). The breadcrumb host, the QFC item viewer and the EFC item viewer must all resolve
+ /// the same user-data folder and the same additional browser arguments, because WebView2
+ /// shares one browser process per user-data folder: a second environment created for the
+ /// same folder with different options fails CoreWebView2Environment.CreateAsync with
+ /// HRESULT 0x8007139F (ERROR_INVALID_STATE, "The group or resource is not in the correct
+ /// state to perform the requested operation"). Reading every value from here keeps the
+ /// creation sites from diverging.
+ ///
+ internal static class WebView2EnvironmentContract
+ {
+ ///
+ /// The additional browser argument every host passes, so no viewer keeps browsing data.
+ /// The trailing space is part of the shared value.
+ ///
+ internal const string AdditionalBrowserArguments = "--incognito ";
+
+ ///
+ /// Leaf folder name under LocalApplicationData that every host uses as its user-data
+ /// folder.
+ ///
+ internal const string UserDataFolderName = "WindowsFormsWebView2";
+
+ ///
+ /// Resolves the shared user-data folder path. Pure: combines paths and creates nothing on
+ /// disk.
+ ///
+ internal static string ResolveUserDataFolder()
+ {
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ UserDataFolderName
+ );
+ }
+
+ ///
+ /// Creates a fresh options instance carrying . A
+ /// new instance is returned on every call because the SDK options type is mutable.
+ ///
+ internal static CoreWebView2EnvironmentOptions CreateOptions()
+ {
+ return new CoreWebView2EnvironmentOptions(AdditionalBrowserArguments);
+ }
+ }
+}
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t10-analyzers.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t10-analyzers.md
new file mode 100644
index 000000000..8dc9b42d4
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t10-analyzers.md
@@ -0,0 +1,24 @@
+# [P0-T10] Analyzer baseline
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-40
+- Command: CMD-OUTLOOK, then `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; console output captured to the gitignored `coverage/p0-t10-analyze.log`)
+- EXIT_CODE: 0
+- Output Summary:
+ - `OUTLOOK-CLOSED: true` (printed first; no `HALT:` line)
+ - `Build succeeded.`
+ - ` 0 Warning(s)` (verbatim msbuild summary line)
+ - ` 0 Error(s)` (verbatim msbuild summary line; exact-line match `^\s+0 Error\(s\)$` = true)
+ - Elapsed 16 seconds; 4994 log lines; 0 lines matching `: error `; 0 lines matching `: warning `.
+
+## Non-vacuity check of the Rebuild
+
+The 16-second duration was short enough to warrant confirming that the Rebuild compiled rather than skipped. From `coverage/p0-t10-analyze.log`:
+
+- CSC-INVOCATIONS: 36 (lines naming `csc.exe`/`csc.dll`)
+- CORECOMPILE-SKIPPED: 0 (no `Skipping target "CoreCompile"` line)
+- PROJECTS-DONE-REBUILD: 19 (`Done Building Project ".csproj" (Rebuild target(s))` lines)
+- ANALYZER-ARG-LINES: 34; the provisioned `Meziantou.Analyzer.3.0.203` path appears on 31 lines and produced no `CS0006`.
+- Assemblies rewritten during the run (local time): `QuickFiler/bin/Debug/QuickFiler.dll` 18:40:38, `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` 18:40:40, `TaskMaster.Test/bin/Debug/TaskMaster.Test.dll` 18:40:43, `UtilitiesCS/bin/Debug/UtilitiesCS.dll` 18:40:34.
+
+msbuild was resolved from `PATH` (`MSBUILD-ON-PATH: true`).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t11-nullable.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t11-nullable.md
new file mode 100644
index 000000000..f315039e8
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t11-nullable.md
@@ -0,0 +1,24 @@
+# [P0-T11] Nullable baseline
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-42
+- Command: CMD-OUTLOOK, then `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true` (no `/p:Nullable=enable`; run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; console output captured to the gitignored `coverage/p0-t11-nullable.log`)
+- EXIT_CODE: 0
+- Output Summary:
+ - `OUTLOOK-CLOSED: true` (printed first; no `HALT:` line)
+ - `Build succeeded.`
+ - ` 0 Warning(s)` (verbatim msbuild summary line)
+ - ` 0 Error(s)` (verbatim msbuild summary line; exact-line match `^\s+0 Error\(s\)$` = true)
+ - Elapsed 14 seconds; 11638 log lines; 0 lines matching `: error `; 0 lines matching `: warning `.
+
+## Non-vacuity check of the Rebuild
+
+From `coverage/p0-t11-nullable.log`:
+
+- CSC-INVOCATIONS: 36
+- CORECOMPILE-SKIPPED: 0
+- PROJECTS-DONE-REBUILD: 19
+- ANALYZER-ARG-LINES: 34; `Meziantou.Analyzer.3.0.203` on 31 lines, no `CS0006`.
+- Assemblies rewritten during the run (local time): `QuickFiler/bin/Debug/QuickFiler.dll` 18:42:44, `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` 18:42:46, `TaskMaster.Test/bin/Debug/TaskMaster.Test.dll` 18:42:49, `UtilitiesCS/bin/Debug/UtilitiesCS.dll` 18:42:41.
+
+msbuild was resolved from `PATH` (`MSBUILD-ON-PATH: true`).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t12-coverage-baseline.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t12-coverage-baseline.md
new file mode 100644
index 000000000..403d351bd
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t12-coverage-baseline.md
@@ -0,0 +1,115 @@
+# [P0-T12] Coverage baseline (QuickFiler.Test scope)
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-46
+- Command: `pwsh -NoProfile -WorkingDirectory -File scripts/vscode/Invoke-MSTestWithCoverage.ps1 -SearchRoot QuickFiler.Test -Configuration Debug -CoverageOutput coverage/p0-baseline.cobertura.xml` (CMD-COVERAGE, stage `p0-baseline`; `` is the item worktree root; console captured to the gitignored `coverage/p0-t12-coverage-run.log`)
+- EXIT_CODE: 1
+- ExpectedExitCode: 1
+- Output Summary: runner exit 1; console carried `is below the required 80% threshold`; `Test Run Successful.`; `Total tests: 1436`; `Passed: 1436`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; root line-rate 0.242471
+
+## Processed document
+
+- PROCESSED-DOCUMENT-EXISTS: true (coverage/p0-baseline.cobertura.xml, gitignored, not copied under the feature folder)
+- CONTAINS-SOURCES-ELEMENT: true
+
+## Root (document-level) figures
+
+- ROOT line-rate: 0.242471
+- ROOT branch-rate: 0.230546
+- ROOT lines-covered: 15048
+- ROOT lines-valid: 62061
+- ROOT branches-covered: 3733
+- ROOT branches-valid: 16192
+- QUICKFILER-SCOPED-DOCUMENT-LINE-RATE: 0.242471
+- REPO-WIDE-FLOOR: NOT MEASURED (single test assembly; see D10)
+
+## Package `QuickFiler` figures
+
+- PACKAGE-ELEMENTS-TOTAL: 6
+- PACKAGE-NAMES: QuickFiler, UtilitiesCS, TaskVisualization, SVGControl, ToDoModel, Tags
+- PACKAGE QuickFiler line-rate (attribute): 0.817304
+- PACKAGE QuickFiler branch-rate (attribute): 0.780358
+- PACKAGE QuickFiler line-rate (Get-CoberturaPackageLineSummary): 0.817304
+- PACKAGE QuickFiler branch-rate (Get-CoberturaPackageLineSummary): 0.780358
+- PACKAGE QuickFiler lines-covered: 10325
+- PACKAGE QuickFiler lines-valid: 12633
+- PACKAGE QuickFiler branches-covered: 2487
+- PACKAGE QuickFiler branches-valid: 3187
+- Note: a Cobertura `package` element carries only `line-rate`/`branch-rate` attributes; the four counts are rolled up with the repository helper `Get-CoberturaPackageLineSummary` (`scripts/vscode/Invoke-MSTestWithCoverage.PackageRate.ps1`), the same reducer that produces the root attributes.
+
+## Console transcription
+
+- Total tests: 1436
+- Passed: 1436
+- Failed: 0 (omitted category)
+- Skipped: 0 (omitted category)
+
+## Per-file rows (max-hits merge over `./lines/line` and `./methods/method/lines/line` of every matching `class`)
+
+- CLASS-ELEMENTS-TOTAL: 537
+### Viewers/WebView2BreadcrumbHost.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 91/103
+- LINE-MAP: 37:1 38:1 39:1 46:1 47:1 51:1 71:1 88:1 89:1 90:1 91:1 92:1 93:1 94:1 95:1 96:1 101:1 102:1 103:1 104:1 105:1 106:1 107:1 109:1 110:1 112:1 113:1 114:1 115:1 121:1 127:1 137:1 158:1 159:1 160:1 161:0 162:0 163:0 166:1 167:1 194:1 197:1 198:1 199:1 200:1 201:1 202:1 203:1 204:1 207:0 208:1 210:1 211:1 212:1 213:1 214:1 217:1 218:1 240:1 241:1 242:0 243:0 246:1 247:1 248:1 249:1 250:1 257:1 258:1 259:1 260:1 263:1 265:1 266:1 267:1 268:1 269:1 270:1 278:0 279:0 280:0 288:1 289:1 291:1 292:1 293:1 294:1 295:1 296:1 297:1 298:1 299:1 300:1 301:1 309:1 310:1 314:1 315:1 316:0 317:0 318:0 320:1 321:1
+
+### Controllers/BreadcrumbBridgeRouter.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 211/213
+- LINE-MAP: 21:1 22:1 23:1 36:1 38:1 41:1 47:1 48:1 49:1 50:1 51:1 52:1 53:1 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 87:1 88:1 89:1 105:1 106:1 107:1 108:1 111:1 112:1 113:1 114:1 115:1 116:1 117:1 118:1 119:1 120:1 121:1 122:1 123:1 124:1 125:1 126:1 129:1 130:1 131:1 132:1 133:1 134:1 135:1 136:1 137:1 143:1 144:1 145:1 146:1 147:1 148:1 149:1 150:1 151:1 152:1 154:1 155:1 156:1 157:1 158:1 159:1 164:1 165:1 170:1 171:1 172:1 173:1 174:1 176:1 177:1 187:1 192:1 193:1 194:1 197:1 198:1 199:1 200:1 201:1 202:0 203:0 208:1 209:1 210:1 211:1 212:1 213:1 214:1 215:1 216:1 218:1 219:1 230:1 231:1 232:1 233:1 236:1 237:1 238:1 239:1 240:1 241:1 246:1 247:1 249:1 250:1 251:1 252:1 253:1 256:1 260:1 261:1 262:1 263:1 264:1 267:1 268:1 269:1 270:1 276:1 277:1 278:1 279:1 280:1 281:1 282:1 283:1 284:1 285:1 286:1 287:1 290:1 291:1 292:1 293:1 294:1 295:1 296:1 300:1 301:1 302:1 303:1 304:1 305:1 306:1 311:1 312:1 313:1 314:1 321:1 322:1 323:1 324:1 325:1 326:1 328:1 329:1 337:1 338:1 339:1 340:1 341:1 342:1 343:1 346:1 349:1 354:1 355:1 356:1 357:1 358:1 359:1 360:1 361:1 362:1 363:1 364:1 365:1 366:1 369:1 370:1 371:1 372:1 374:1 377:1 378:1 380:1 381:1 383:1 384:1 386:1 387:1 389:1 390:1 392:1 395:1 397:1 398:1 399:1 400:1 401:1 404:1 405:1
+
+### Controllers/BreadcrumbBridgeRouter.Selection.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 140/143
+- LINE-MAP: 18:1 19:1 20:1 21:1 22:1 23:1 24:1 27:1 28:1 29:0 30:0 33:1 34:1 37:1 38:1 39:1 40:1 41:1 42:1 43:1 44:1 47:1 48:1 54:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 66:1 68:1 69:1 70:1 71:1 72:1 73:1 75:1 76:1 78:1 79:1 81:1 84:1 85:1 86:1 87:1 90:1 91:1 92:1 93:1 95:1 96:1 97:1 98:1 99:1 100:1 101:1 102:1 103:1 104:1 105:1 106:1 109:1 110:1 111:1 112:1 115:1 116:1 118:1 119:1 122:1 123:1 124:1 125:1 126:1 131:1 132:1 133:1 134:1 135:1 136:1 137:1 140:1 141:1 144:1 145:1 146:1 147:1 148:1 149:1 150:1 151:1 154:1 155:1 156:1 157:1 158:1 159:1 160:1 161:1 164:1 165:1 166:1 169:1 170:1 171:1 172:1 173:1 174:1 175:1 177:1 178:1 179:1 180:1 183:1 184:1 185:1 186:1 187:1 188:1 190:1 192:1 193:1 196:1 197:1 198:1 199:1 200:1 201:1 203:1 205:0 206:1 209:1 210:1 211:1 212:1 213:1 214:1 216:1 218:1 219:1
+
+### Controllers/BreadcrumbOutboundQueue.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 23/24
+- LINE-MAP: 18:1 23:1 24:1 25:1 26:1 29:0 38:1 39:1 40:1 41:1 44:1 45:1 46:1 47:1 49:1 50:1 51:1 52:1 60:1 61:1 62:1 63:1 64:1 65:1
+
+### Controllers/EfcFormController.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 251/822
+- LINE-MAP: 30:1 31:1 32:1 33:1 34:1 35:1 36:1 37:1 38:1 39:1 40:1 41:1 42:1 43:1 44:1 45:1 46:1 47:1 48:1 49:1 51:1 52:1 53:1 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 64:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 72:1 73:1 74:1 75:1 77:1 80:0 81:0 82:0 83:0 84:0 85:0 86:0 87:0 88:0 89:0 90:0 91:0 92:0 93:0 94:0 95:0 96:0 97:0 100:0 101:0 102:0 103:0 104:0 105:0 106:0 107:0 108:0 109:0 112:0 113:0 114:0 115:0 116:0 117:0 123:1 124:1 125:1 129:1 138:1 139:1 140:1 141:1 151:1 152:1 153:1 154:1 155:1 156:1 160:1 161:1 162:1 163:1 164:1 165:1 166:1 167:1 168:1 173:1 174:1 183:1 184:1 238:1 269:0 270:0 271:0 272:0 273:0 274:0 275:0 276:0 277:0 278:0 279:0 280:0 281:0 282:0 283:0 284:0 285:0 286:0 287:0 288:0 289:0 293:1 295:1 296:1 297:0 298:0 299:0 300:1 301:1 302:1 305:1 306:1 307:1 308:1 309:1 310:1 311:1 314:0 315:0 316:0 317:0 318:0 319:0 320:0 321:0 324:0 325:0 326:0 327:0 328:0 330:0 332:0 334:0 336:0 337:0 338:0 339:0 340:0 342:0 343:0 344:0 345:0 346:0 347:0 348:0 349:0 350:0 353:0 354:0 355:0 356:0 357:0 358:0 359:0 360:0 362:0 363:0 375:1 376:1 377:1 379:0 380:0 381:0 382:0 383:0 387:1 388:1 389:1 390:0 391:0 392:0 393:1 394:1 402:1 403:1 404:1 405:1 406:0 407:1 408:1 409:1 410:1 411:0 414:0 421:1 427:1 429:1 430:1 433:1 439:1 441:1 442:1 445:1 451:1 453:1 454:1 457:1 463:1 465:1 466:1 469:1 475:1 476:0 484:0 485:0 486:0 487:0 488:0 489:0 490:0 491:0 492:0 493:0 494:0 495:0 498:0 502:0 503:0 504:0 505:0 506:0 507:0 508:0 509:0 510:0 511:0 512:0 513:0 514:0 515:0 516:0 517:0 518:0 519:0 520:0 521:0 522:0 523:0 524:0 525:0 526:0 527:0 528:0 529:0 532:0 533:0 534:0 537:0 538:0 539:0 540:0 543:0 546:1 548:1 549:1 550:1 552:0 553:0 554:1 555:1 556:1 557:1 558:1 560:0 563:1 565:1 566:1 567:1 569:0 570:0 571:1 572:1 573:1 574:1 575:1 578:0 581:1 583:1 584:1 585:1 587:0 588:0 589:1 590:1 591:1 592:1 593:1 596:0 599:1 601:1 602:1 603:1 605:0 606:0 607:0 608:0 609:0 610:0 611:0 612:0 613:0 615:0 616:0 617:0 619:0 620:0 621:0 622:0 623:0 625:0 626:0 627:0 628:0 629:0 630:0 631:0 632:0 633:0 635:0 636:0 637:0 638:0 639:0 640:0 641:0 642:0 643:0 644:0 646:0 647:0 648:0 649:0 650:0 651:1 652:1 653:1 654:1 655:1 658:0 661:1 663:1 664:1 665:0 666:1 667:1 668:1 669:1 670:1 673:0 674:0 675:0 678:0 679:0 680:0 683:0 684:0 685:0 688:0 689:0 690:0 693:0 694:0 695:0 698:0 699:0 700:0 701:0 702:0 706:0 709:0 710:0 711:0 712:0 713:0 714:0 715:0 716:0 717:0 718:0 719:0 720:0 721:0 722:0 723:0 724:0 725:0 726:0 727:0 728:0 729:0 730:0 731:0 732:0 733:0 734:0 735:0 736:0 737:0 738:0 739:0 763:0 766:0 767:0 768:0 769:0 770:0 771:0 772:0 773:0 774:0 775:0 776:0 777:0 778:0 779:0 780:0 781:0 782:0 783:0 784:0 785:0 786:0 787:0 788:0 789:0 790:0 791:0 792:0 793:0 794:0 795:0 796:0 797:0 798:0 799:0 800:0 801:0 802:0 803:0 804:0 805:0 806:0 807:0 808:0 809:0 810:0 811:0 812:0 813:0 816:0 817:0 818:0 819:0 820:0 821:0 822:0 823:0 825:0 826:0 827:0 830:0 831:0 832:0 839:0 840:0 841:0 843:0 845:0 846:0 847:0 848:0 849:0 850:0 851:0 852:0 855:0 856:0 857:0 858:0 859:0 860:0 861:0 862:0 863:0 864:0 866:0 867:0 869:0 870:0 871:0 872:0 875:0 877:0 879:0 880:0 881:0 888:1 889:1 890:0 891:0 893:1 894:1 895:1 897:1 898:1 899:1 900:1 904:1 905:1 906:1 907:1 910:1 911:1 912:1 913:1 916:0 917:0 918:0 919:0 920:0 921:0 922:0 923:0 924:0 926:0 927:0 928:0 929:0 930:0 931:0 933:0 934:0 935:0 936:0 937:0 938:0 939:0 940:0 941:0 942:0 943:0 944:0 945:0 946:0 947:0 948:0 949:0 950:0 951:0 952:0 953:0 954:0 955:0 956:0 957:0 958:0 965:1 966:1 967:1 968:1 970:1 971:1 978:0 979:0 981:0 982:0 983:0 984:0 985:0 987:0 988:0 1001:1 1003:1 1004:1 1005:1 1006:1 1007:1 1011:1 1012:1 1013:1 1014:1 1015:1 1016:1 1017:1 1020:1 1021:1 1022:1 1023:1 1024:1 1025:1 1026:1 1029:1 1030:1 1031:1 1032:1 1033:1 1034:1 1035:1 1038:0 1039:0 1041:0 1042:0 1048:0 1049:0 1050:0 1051:0 1052:0 1053:0 1054:0 1055:0 1056:0 1057:0 1058:0 1059:0 1060:0 1061:0 1062:0 1063:0 1064:0 1065:0 1066:0 1067:0 1068:0 1073:0 1075:0 1076:0 1077:0 1078:0 1079:0 1080:0 1081:0 1082:0 1087:1 1088:1 1089:1 1090:1 1091:1 1094:0 1095:1 1100:0 1101:0 1102:0 1103:0 1104:0 1107:0 1108:0 1109:0 1113:1 1115:1 1116:1 1117:1 1118:1 1119:1 1120:1 1121:0 1122:0 1123:0 1124:0 1125:1 1126:1 1127:1 1128:1 1129:1 1132:0 1133:0 1134:0 1137:0 1138:0 1139:0 1141:0 1144:0 1145:0 1146:0 1147:0 1150:0 1151:0 1152:0 1153:0 1154:0 1155:0 1156:0 1159:0 1160:0 1161:0 1162:0 1163:0 1164:0 1165:0 1168:0 1169:0 1170:0 1171:0 1172:0 1175:0 1176:0 1177:0 1178:0 1179:0 1180:0 1181:0 1184:0 1185:0 1186:0 1187:0 1188:0 1189:0 1190:0 1192:0 1193:0 1194:0 1195:0 1196:0 1199:0 1200:0 1201:0 1202:0 1203:0 1204:0 1205:0 1206:0 1207:0 1209:0 1210:0 1211:0 1212:0 1213:0 1214:0 1215:0 1218:0 1219:0 1222:0 1223:0 1224:0 1226:0 1233:0 1236:0 1237:0 1238:0 1240:0 1241:0 1243:0 1244:0 1246:0 1247:0 1248:0 1252:1 1254:1 1258:1 1259:1 1260:1 1262:1 1264:0 1266:0 1267:0 1268:1 1269:1 1270:1 1271:1 1272:1 1276:1 1277:1 1278:1 1279:1 1280:1 1284:1 1285:1 1287:0 1292:0 1293:0 1294:0 1295:0 1296:0 1297:0 1298:0 1299:0 1300:0 1301:0 1302:0 1303:0 1304:0 1305:0 1307:0 1308:0 1309:0 1310:0 1311:0 1312:0 1313:0 1314:0 1315:0 1316:0 1317:0 1318:0 1319:0
+
+### Controllers/EfcHomeController.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 226/230
+- LINE-MAP: 20:1 21:1 22:1 24:1 25:1 30:1 31:1 32:1 33:1 36:1 37:1 38:1 41:1 42:1 43:1 52:0 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 64:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 73:1 74:1 75:1 76:1 77:1 78:1 79:1 80:1 81:1 82:1 83:1 84:1 85:1 86:1 87:1 88:1 89:1 90:1 91:1 92:1 93:1 94:1 95:1 97:1 98:1 99:1 100:1 101:1 102:1 109:1 110:1 111:1 119:1 120:1 121:1 122:1 124:1 125:1 126:1 127:1 129:1 130:1 131:1 132:1 133:1 134:1 135:1 136:1 137:1 138:1 145:1 146:1 147:1 155:1 156:1 157:1 158:1 160:1 161:1 162:1 163:1 165:1 167:1 168:1 175:1 176:1 177:1 178:1 179:1 180:1 181:1 182:1 183:1 184:1 186:1 188:1 189:1 190:1 191:1 192:1 193:1 194:1 197:1 200:1 201:1 208:1 211:1 212:1 213:1 214:1 215:1 216:1 217:1 218:1 219:1 220:1 221:1 224:1 225:1 226:1 227:1 228:1 229:1 230:1 231:1 232:1 233:1 234:1 235:1 236:1 237:1 239:1 240:1 242:1 245:1 246:1 248:1 250:1 251:1 252:1 253:1 260:1 261:1 262:1 267:1 268:1 274:1 275:1 281:1 282:1 288:0 289:0 294:1 297:1 305:1 309:1 310:1 311:1 312:1 313:1 315:1 316:1 317:1 318:1 319:1 320:1 321:1 322:1 323:1 326:1 327:1 328:1 329:1 330:1 332:1 333:1 334:1 335:1 336:1 337:1 338:1 339:1 340:1 343:1 344:1 345:1 346:1 347:1 348:1 349:1 350:1 351:1 352:1 361:1 362:1 368:1 374:1 375:1 381:1 382:1 388:1 397:1 400:1 401:1 402:1 403:1 408:1 414:1 420:0 423:1 430:1 431:1 432:1 435:1 436:1 437:1
+
+### Controllers/EfcDataModel.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 189/286
+- LINE-MAP: 23:1 24:1 25:1 28:1 29:1 30:1 33:1 34:1 35:1 38:1 39:1 40:1 41:1 42:1 43:1 44:1 48:1 49:1 50:1 51:1 52:1 53:1 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 64:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 72:1 73:1 74:1 75:1 77:1 78:1 79:1 80:1 81:1 83:1 84:1 85:1 86:1 87:1 96:1 97:1 98:1 99:1 101:1 102:1 103:1 104:1 105:1 107:1 108:1 109:1 110:1 111:1 114:1 115:1 116:1 117:1 118:1 119:1 120:1 121:1 122:1 123:1 125:1 126:1 127:1 128:1 129:1 130:1 131:1 132:1 133:1 134:1 136:1 137:1 138:1 139:1 141:1 142:1 154:1 159:1 160:1 166:1 167:1 173:1 174:1 181:0 183:0 184:0 185:0 189:0 190:0 191:0 192:0 193:0 194:0 195:0 197:0 198:0 199:0 200:0 201:0 202:0 203:0 204:0 205:0 206:0 207:0 208:0 210:0 211:0 212:0 213:0 214:0 215:0 216:0 217:0 218:0 219:0 220:0 221:0 226:1 227:1 234:1 235:1 236:1 237:1 238:1 241:1 244:1 246:1 247:1 248:0 249:0 250:0 253:0 254:0 257:1 258:1 259:1 261:1 281:1 283:1 284:1 285:1 287:1 288:1 289:1 290:1 291:1 292:1 293:1 294:1 295:1 297:1 310:1 311:1 312:1 313:1 316:1 317:1 318:1 319:1 321:1 322:1 323:1 324:1 327:1 328:1 329:1 332:1 333:1 334:1 335:1 336:1 337:1 338:1 339:1 340:1 341:1 343:1 344:1 345:1 346:1 359:0 360:0 361:0 364:1 365:1 366:1 367:1 370:1 371:1 372:1 373:1 376:0 377:0 378:0 379:0 380:0 381:0 382:0 384:0 385:0 386:1 389:1 390:1 391:1 392:1 394:1 395:1 396:1 397:1 400:0 401:0 402:0 403:0 404:0 405:0 406:0 408:0 409:0 410:1 420:0 421:0 422:0 423:0 424:0 425:0 426:0 427:0 428:0 429:0 430:0 431:0 432:0 433:0 449:1 450:1 451:1 452:1 453:1 454:1 455:1 456:1 457:1 460:1 461:1 462:1 465:0 466:0 467:0 468:0 471:0 472:0 474:0 477:0 478:0 479:0 480:0 481:0 483:0 484:0 485:0 486:0 487:0 488:0 489:0 492:0 494:0 495:0
+
+### Controllers/QfcItemController.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 73/73
+- LINE-MAP: 30:1 31:1 32:1 37:1 38:1 98:1 99:1 102:1 105:1 106:1 112:1 113:1 116:1 119:1 120:1 123:1 126:1 127:1 132:1 137:1 138:1 144:1 146:1 150:1 151:1 157:1 158:1 160:1 165:1 174:1 183:1 184:1 189:1 195:1 197:1 198:1 199:1 200:1 201:1 202:1 203:1 204:1 205:1 207:1 208:1 209:1 210:1 211:1 215:1 216:1 219:1 222:1 224:1 225:1 226:1 227:1 228:1 229:1 231:1 232:1 233:1 234:1 240:1 265:1 269:1 270:1 275:1 287:1 288:1 289:1 290:1 291:1 292:1
+
+### Controllers/QfcItemController.ViewerSetup.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 194/213
+- LINE-MAP: 94:0 95:0 96:0 97:0 98:0 101:0 102:0 103:0 104:0 105:0 106:0 107:0 138:1 139:1 140:1 141:1 149:1 150:1 151:0 152:1 153:1 154:1 157:1 158:1 159:1 160:1 161:1 162:1 168:1 169:1 170:0 171:1 172:0 173:0 174:1 175:1 189:1 190:1 191:1 196:1 197:1 198:1 199:1 202:1 203:1 204:1 205:1 208:1 209:1 210:1 215:1 216:1 217:1 218:1 221:1 222:1 223:1 224:1 228:1 235:1 237:1 238:1 239:1 241:1 242:1 243:1 245:1 247:1 249:1 250:1 251:1 252:1 253:1 254:1 255:1 257:1 258:1 259:1 260:1 261:1 262:1 263:1 265:1 266:1 267:1 268:1 270:1 271:1 282:1 283:1 285:1 286:1 287:1 288:1 289:1 290:1 292:1 293:1 301:1 302:1 303:1 304:1 306:1 307:1 308:1 309:1 312:1 313:1 314:1 315:1 316:1 317:1 318:1 320:1 321:1 322:1 323:1 324:1 325:1 326:1 328:1 329:1 330:1 331:1 333:1 334:1 337:1 338:1 340:1 341:1 344:1 345:1 346:1 347:1 354:1 357:1 359:1 362:1 363:1 366:1 378:1 379:1 380:1 381:1 382:1 385:1 386:1 389:1 391:1 392:1 393:1 394:1 397:1 398:1 399:1 400:1 401:1 402:1 403:1 404:1 405:1 406:1 408:1 409:1 410:1 411:1 413:1 414:1 416:1 417:1 419:1 420:1 422:1 423:1 424:1 427:1 430:1 431:1 432:1 433:1 434:1 435:1 437:1 438:1 439:1 440:1 441:1 442:1 444:1 445:1 446:1 447:1 448:1 449:1 450:1 452:1 453:1 454:1 455:1 456:1 458:1 459:1 461:1 462:1 467:1 468:1 469:0 470:0 471:0 472:1 473:1 474:1 477:1
+
+### Helper Classes/EfcViewerQueue.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 46/50
+- LINE-MAP: 11:1 14:1 20:1 25:1 27:1 30:1 31:1 32:1 35:1 36:1 37:1 38:1 39:1 40:1 41:1 42:1 43:1 49:1 50:1 51:1 57:1 58:1 59:1 60:1 63:1 64:1 65:1 66:1 67:0 68:1 69:1 72:1 73:1 74:1 75:1 76:1 77:1 78:1 79:1 82:0 83:0 84:0 92:1 93:1 94:1 95:1 96:1 97:1 98:1 99:1
+
+## Uninstrumented files
+
+- Controllers/EfcItemController.cs: CLASS-ELEMENTS: 0 (class-level `[ExcludeFromCodeCoverage]` at `QuickFiler/Controllers/EfcItemController.cs:26`)
+- Controllers/QfcCollectionController.cs: CLASS-ELEMENTS: 0 (class-level `[ExcludeFromCodeCoverage]` at `QuickFiler/Controllers/QfcCollectionController.cs:22`)
+
+INSTRUMENTED-FILES-WITH-ZERO-CLASS-ELEMENTS: 0
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t13-taskmaster-sweep.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t13-taskmaster-sweep.md
new file mode 100644
index 000000000..9bf45f72a
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t13-taskmaster-sweep.md
@@ -0,0 +1,21 @@
+# [P0-T13] Regression-sweep baseline (TaskMaster.Test, no coverage)
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-47
+- Command: CMD-VSTEST (`vstest.console.exe` resolved through `vswhere -latest -products * -find 'Common7/IDE/Extensions/TestPlatform/vstest.console.exe'`), then `& $vstest TaskMaster.Test/bin/Debug/TaskMaster.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:TestCategory!=LiveOutlook" "/Blame:CollectHangDump;TestTimeout=4min;HangDumpType=None" "/ResultsDirectory:coverage/test-results/p0-t13" "/Logger:trx;LogFileName=p0-t13.trx"` (CMD-SWEEP with `` = `p0-t13`; run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; console captured to the gitignored `coverage/p0-t13-sweep.log`; the TRX stays under the gitignored `coverage/test-results/p0-t13/`)
+- EXIT_CODE: 0
+- Output Summary: `Test Run Successful.`; `Total tests: 452`; `Passed: 452`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; `Total time: 2.6932 Seconds`; 0 lines beginning `Failed `; no Blame hang output (the run completed with a summary well inside the 4-minute per-test timeout).
+
+## Console transcription
+
+- Total tests: 452
+- Passed: 452
+- Failed: 0 (omitted category)
+- Skipped: 0 (omitted category)
+
+BASELINE_FAILURE_SET: none
+
+## Notes
+
+- The assembly under test was produced by the [P0-T11] nullable Rebuild (`TaskMaster.Test/bin/Debug/TaskMaster.Test.dll`, written 18:42:49 local time); no build ran in this task.
+- `scripts/vscode/TaskMaster.cli.runsettings` was passed unchanged (Workers=0, ClassLevel).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t16-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t16-commit.md
new file mode 100644
index 000000000..ce202aa39
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t16-commit.md
@@ -0,0 +1,21 @@
+# [P0-T16] Phase 0 commit
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-50
+- Command: `git add -- docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "chore(792): phase 0 baselines and plan"` (run with `git -C ` against the item worktree on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`)
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 0d0275e9] chore(792): phase 0 baselines and plan`; `16 files changed, 503 insertions(+), 15 deletions(-)`; 15 files created under `evidence/` and the plan file modified (fifteen `[ ]` to `[x]` check-offs for [P0-T1] through [P0-T15]).
+
+## Acceptance observations
+
+- `git show --name-only --format= HEAD` listed 16 paths, every one under `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/` (13 under `evidence/baseline/`, 1 under `evidence/other/`, 2 under `evidence/regression-testing/`, plus `plan.2026-09-17T07-30.md`).
+- `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` printed nothing.
+- `git status --porcelain --untracked-files=all` printed nothing immediately after the commit.
+
+COMMIT-SHA-OBSERVED: 0d0275e999efee6f643fef9f6e8206e0303c8c8b
+
+## Residual (recorded, not an acceptance clause)
+
+This artifact and the [P0-T16] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 0 (the plan's convention 9 treats docs and evidence as expected-dirty). No source path is dirty. They are left for the next feature-folder commit in the plan rather than committed here, because the plan authorizes exactly one commit in Phase 0.
+
+Git printed sixteen `LF will be replaced by CRLF` warnings for the newly added Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t3-sdk.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t3-sdk.md
new file mode 100644
index 000000000..41967dec3
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t3-sdk.md
@@ -0,0 +1,20 @@
+# [P0-T3] Repo-local .NET SDK bootstrap
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-35
+- Command: `pwsh -NoProfile -File scripts/vscode/Install-RepoDotNetSdk.ps1` (run with the item worktree as the working directory), then `dotnet --version` and `dotnet --list-sdks` from the same directory.
+- EXIT_CODE: 0
+- Output Summary: The install script exited 0. `dotnet --version` printed `8.0.205`, which begins `8.0.` and is a version string, not the `global.json` `errorMessage`. `dotnet --list-sdks` returned 2 rows (versions `8.0.205` and `10.0.401`); at least one row's path segment ends `.dotnet-sdk/sdk` after `.Replace('\', '/')`. The `--list-sdks` output is not transcribed because its path column carries the account name.
+
+## Observations
+
+- DOTNET-VERSION: 8.0.205
+- SDK-UNDER-REPO-LOCAL-DIR: true
+- SDK-LINE-COUNT: 2
+- SDK-VERSIONS-ONLY: 8.0.205, 10.0.401
+- DOTNET-SDK-DIR-GITIGNORED: true (`git check-ignore -q .dotnet-sdk` exit 0; `.gitignore` line 350), so the tree stays clean.
+
+## Execution notes
+
+- The initial attempt to compute `SDK-UNDER-REPO-LOCAL-DIR` inline through the Bash tool produced `false` because the doubled backslash in a regex was collapsed by the tool layer into an invalid pattern. The value above was re-derived through the plan's gitignored helper path `coverage/plan792-helper.ps1` (convention 8) using the string method `.Replace('\', '/')`, which needs no regex escape.
+- `pwsh -File` resolves a relative script path against the launching shell's directory rather than `-WorkingDirectory`, so the helper was invoked by absolute path; the helper's opening branch assertion is the worktree proof.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t4-tool-restore.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t4-tool-restore.md
new file mode 100644
index 000000000..0c9958fec
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t4-tool-restore.md
@@ -0,0 +1,9 @@
+# [P0-T4] Manifest tool restore
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-35
+- Command: `dotnet tool restore` then `dotnet tool list` (manifest: repository-root `dotnet-tools.json`; run with the item worktree as the working directory)
+- EXIT_CODE: 0
+- Output Summary:
+ - `dotnet tool restore` printed `Tool 'csharpier' (version '1.2.6') was restored. Available commands: csharpier` and `Restore was successful.`; exit 0.
+ - `dotnet tool list` printed one row whose first column is `csharpier` and second column is `1.2.6` (third column `csharpier`); exit 0. The Manifest column is not transcribed because it carries the account name.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t5-nuget-restore.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t5-nuget-restore.md
new file mode 100644
index 000000000..79d6022bf
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t5-nuget-restore.md
@@ -0,0 +1,25 @@
+# [P0-T5] NuGet package restore
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-37
+- Command: `pwsh -NoProfile -File scripts/vscode/Invoke-Restore.ps1` (msbuild `/t:Restore /p:RestorePackagesConfig=true`, run with the item worktree as the working directory)
+- EXIT_CODE: 0
+- Output Summary: Restore target succeeded; `Installed: 172 package(s) to packages.config projects`; `0 Warning(s)`, `0 Error(s)`; `Time Elapsed 00:00:02.47`.
+
+## Acceptance observations
+
+- MOQ-EXACT-FOLDER-PRESENT: true — `Test-Path packages/Moq.4.20.72` held, so the exact-folder form was used (the wildcard fallback was not needed).
+- PROJECTS-SCANNED: 2 (`QuickFiler/QuickFiler.csproj`, `QuickFiler.Test/QuickFiler.Test.csproj`)
+- ANALYZER-PATHS-RESOLVED: 20 of 20 (final state, after the restore supplement below)
+- PORCELAIN-SOURCE-LINES: 0 (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` printed nothing)
+
+## Restore supplement (recorded, not hidden)
+
+The first pass of the analyzer-path check after the restore reported `ANALYZER-PATHS-RESOLVED: 18 of 20`. The two unresolved items were the ` ` items at `QuickFiler/QuickFiler.csproj:598` and `QuickFiler.Test/QuickFiler.Test.csproj:525`; the other 18 (Roslynator 5.0.0, AsyncFixer 2.1.0, BannedApiAnalyzers 5.6.0, SonarAnalyzer.CSharp 10.34.0.3385, MSTest.Analyzers 4.4.0) resolved on the first pass, which is the positive control that the probe reached the intended files.
+
+Cause, verified before acting:
+
+- Every first-party `packages.config` and every csproj ``/`` line names `Meziantou.Analyzer.3.0.235`, so the restore installed only `packages/Meziantou.Analyzer.3.0.235`; the hand-written `` items in 15 of 16 first-party projects still name `3.0.203` (only `TaskMaster/TaskMaster.csproj:575` was updated to `3.0.235`).
+- The skew is inherited: `git show origin/main:QuickFiler/QuickFiler.csproj` carries the identical `3.0.203` item under the `3.0.235` import, and `git diff --stat origin/main HEAD -- '*.csproj' 'packages.config'` is empty, so this branch never touched those files. It surfaces only on a cold worktree, where the superseded package folder is absent.
+
+Action taken (environment only; no tracked file changed): `nuget install Meziantou.Analyzer -Version 3.0.203 -OutputDirectory packages -DependencyVersion Ignore` (exit 0). `git check-ignore -v` reports the provisioned DLL is ignored by `.gitignore:191` (`**/[Pp]ackages/*`). The check was then re-run and reported `ANALYZER-PATHS-RESOLVED: 20 of 20`. The plan text labels a mismatch as an environment defect; the remedy repairs the environment and leaves the source tree byte-identical, which is why it is recorded here as a restore supplement rather than a halt. The durable fix (aligning the 15 stale `` version strings with `packages.config`) is outside this item's write set and is reported to the maintainer in the Phase 0 summary as a pre-existing repository defect.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t6-dotnet-coverage.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t6-dotnet-coverage.md
new file mode 100644
index 000000000..6f149de52
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t6-dotnet-coverage.md
@@ -0,0 +1,13 @@
+# [P0-T6] dotnet-coverage global tool presence
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-38
+- Command: `if (-not (Get-Command dotnet-coverage -ErrorAction SilentlyContinue)) { dotnet tool install --global dotnet-coverage }` then `Get-Command dotnet-coverage` and `dotnet-coverage --version` (run under `pwsh -NoProfile` with the item worktree as the working directory)
+- EXIT_CODE: 0
+- Output Summary: `Get-Command dotnet-coverage` succeeded (the tool was already installed; no install ran). `dotnet-coverage --version` printed `18.10.0+f4cc39224845ffa74bf246c9da2399d50e5d6342`.
+
+## Observations
+
+- DOTNET-COVERAGE-PRESENT: true
+- DOTNET-COVERAGE-VERSION: 18.10.0+f4cc39224845ffa74bf246c9da2399d50e5d6342
+- The resolved tool path is not recorded because it carries the account name.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t7-git-base.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t7-git-base.md
new file mode 100644
index 000000000..bc7535e88
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t7-git-base.md
@@ -0,0 +1,49 @@
+# [P0-T7] Git base capture
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-38
+- Command: `git fetch origin`; `git rev-parse HEAD`; `git rev-parse origin/main`; `git merge-base HEAD origin/main`; `git merge-base --is-ancestor origin/main HEAD; $LASTEXITCODE`; `git status --porcelain --untracked-files=all`; `git diff --name-status (git merge-base HEAD origin/main) HEAD` (all run against the item worktree on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`)
+- EXIT_CODE: 0
+- Output Summary: fetch exit 0; HEAD `11b107a55fc32078f97e0cd48f893c175be5b6f4`; `origin/main` `e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3`; merge base equals `origin/main`; `origin/main` is an ancestor of HEAD (exit 0); porcelain lists 7 lines, all under the feature folder, 0 source paths; base-to-HEAD name-status lists 7 added files, all under the feature folder.
+
+## Base
+
+BASE-SHA: e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3
+
+ORIGIN-MAIN-IS-ANCESTOR: true
+
+Note (DIFF BASES block, both forms compared): `git merge-base --is-ancestor origin/main HEAD` exited 0, so `origin/main` is an ancestor of HEAD and the merge base IS the `origin/main` SHA: `git merge-base HEAD origin/main` printed `e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3`, identical to `git rev-parse origin/main`. Two-dot and three-dot forms anchored to `origin/main` therefore resolve to the same base. Bare local `main` was not used.
+
+HEAD-OBSERVED: 11b107a55fc32078f97e0cd48f893c175be5b6f4
+
+SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4
+
+Note: `SPEC-REF-SHA` equals the `git rev-parse HEAD` output at capture time. The feature folder does not exist at `BASE-SHA` (every feature-folder path is `A` in the name-status list below), so criterion-text immutability of `spec.md` is checked against `SPEC-REF-SHA`, not `BASE-SHA`.
+
+## Porcelain (verbatim, `git status --porcelain --untracked-files=all`)
+
+```
+ M docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t3-sdk.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t4-tool-restore.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t5-nuget-restore.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t6-dotnet-coverage.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/phase0-instructions-read.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p0-t2-outlook-closed.md
+```
+
+PORCELAIN-SOURCE-PATHS: 0
+
+(Computed as the count of porcelain lines whose path ends `.cs`, `.csproj`, `.sln` or `packages.config`. The gitignored `coverage/plan792-helper.ps1` and `packages/Meziantou.Analyzer.3.0.203/` do not appear, as expected.)
+
+## BASE-TO-HEAD-NAME-STATUS
+
+```
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/issue.md
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-12T13-21.md
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/research/2026-09-12T10-30-breadcrumb-webview2-init-research.md
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/research/2026-09-17T11-20-breadcrumb-webview2-init-research.md
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md
+A docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/user-story.md
+```
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t8-line-counts.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t8-line-counts.md
new file mode 100644
index 000000000..c86ceda9b
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t8-line-counts.md
@@ -0,0 +1,58 @@
+# [P0-T8] Baseline line counts and new-file absence
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-39
+- Command: `(Get-Content -LiteralPath ).Count` per existing write-set `.cs` path and `Test-Path -LiteralPath ` per new path, run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (the helper's opening branch assertion is the worktree proof)
+- EXIT_CODE: 0
+- Output Summary: 12 existing rows measured, `MISMATCH-COUNT: 0` against the plan's expected values; 17 new paths checked, `NEW-PATHS-PRESENT: 0`; `OVER-CEILING-BEFORE: 3`; positive control `Test-Path` on an existing path returned true.
+
+## Existing write-set `.cs` files (total line count)
+
+| Path | Lines | Expected | Match |
+|---|---|---|---|
+| `QuickFiler/Controllers/EfcFormController.cs` | 1321 | 1321 | true |
+| `QuickFiler/Controllers/EfcItemController.cs` | 1122 | 1122 | true |
+| `QuickFiler/Controllers/QfcCollectionController.cs` | 2333 | 2333 | true |
+| `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` | 479 | 479 | true |
+| `QuickFiler/Controllers/EfcDataModel.cs` | 499 | 499 | true |
+| `QuickFiler/Controllers/EfcHomeController.cs` | 447 | 447 | true |
+| `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` | 407 | 407 | true |
+| `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` | 368 | 368 | true |
+| `QuickFiler/Controllers/QfcItemController.cs` | 334 | 334 | true |
+| `QuickFiler/Helper Classes/EfcViewerQueue.cs` | 101 | 101 | true |
+| `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` | 67 | 67 | true |
+| `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` | 485 | 485 | true |
+
+EXISTING-ROWS: 12 (eleven production, one test)
+MISMATCH-COUNT: 0
+
+OVER-CEILING-BEFORE: 3 — `QuickFiler/Controllers/QfcCollectionController.cs` (2333), `QuickFiler/Controllers/EfcFormController.cs` (1321), `QuickFiler/Controllers/EfcItemController.cs` (1122).
+
+## Seventeen new write-set paths (must be absent on the unfixed tree)
+
+| Path | ABSENT |
+|---|---|
+| `QuickFiler/Viewers/WebView2EnvironmentContract.cs` | true |
+| `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` | true |
+| `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` | true |
+| `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs` | true |
+| `QuickFiler/Controllers/EfcFormController.EventHandlers.cs` | true |
+| `QuickFiler/Controllers/EfcFormController.Actions.cs` | true |
+| `QuickFiler/Controllers/EfcFormController.Helpers.cs` | true |
+| `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` | true |
+| `QuickFiler/Controllers/EfcDataModel.Carry.cs` | true |
+| `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs` | true |
+| `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` | true |
+| `QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs` | true |
+| `QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs` | true |
+| `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs` | true |
+| `QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs` | true |
+| `QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs` | true |
+| `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs` | true |
+
+NEW-PATHS-CHECKED: 17
+NEW-PATHS-PRESENT: 0
+
+Positive control for the absence claim: the same `Test-Path -LiteralPath` form against `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` returned true (`CONTROL-EXISTING-PATH-TEST: true`), so a false `Test-Path` on the seventeen paths is a genuine absence rather than a mis-scoped probe.
+
+This artifact records the AC-U8 gate in its FAIL state (the seventeen paths absent and the pre-change counts) per the plan's observed-failing map.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t9-csharpier-check.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t9-csharpier-check.md
new file mode 100644
index 000000000..35374d9e0
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t9-csharpier-check.md
@@ -0,0 +1,15 @@
+# [P0-T9] Formatter baseline (read-only)
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-39
+- Command: `dotnet tool run csharpier check .` (run with the item worktree as the working directory; manifest-pinned CSharpier 1.2.6 restored in [P0-T4])
+- EXIT_CODE: 0
+- Output Summary: `Checked 1641 files in 4263ms.` — the command printed exactly one line and reported no unformatted file.
+
+## Observations
+
+Verbatim check line: `Checked 1641 files in 4263ms.`
+
+BASELINE-DRIFT-SET: (empty; exit 0, no file reported)
+
+DRIFT-IN-WRITE-SET: 0
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/phase0-instructions-read.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/phase0-instructions-read.md
new file mode 100644
index 000000000..fb4dc6769
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/phase0-instructions-read.md
@@ -0,0 +1,46 @@
+# Phase 0 — Policy and Requirements Read Evidence ([P0-T1])
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-33
+- Work Mode: full-bug
+- Work Mode source: `issue.md` line 12 (`- Work Mode: full-bug`), re-derived by `Select-String -Pattern '^- Work Mode:'` returning line 12.
+- AC source (full-bug): `spec.md` only.
+
+## Policy Order
+
+Files read in the `policy-compliance-order` sequence, each from the item worktree:
+
+1. `CLAUDE.md`
+2. `.claude/rules/general-code-change.md`
+3. `.claude/rules/general-unit-test.md`
+4. `.claude/rules/csharp.md`
+5. `.claude/rules/quality-tiers.md`
+6. `.claude/rules/tonality.md`
+7. `.claude/rules/plan-acceptance-gates.md`
+
+## Files Read
+
+All ten files were read in full with the Read tool from the item worktree on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`:
+
+1. `CLAUDE.md`
+2. `.claude/rules/general-code-change.md`
+3. `.claude/rules/general-unit-test.md`
+4. `.claude/rules/csharp.md`
+5. `.claude/rules/quality-tiers.md`
+6. `.claude/rules/tonality.md`
+7. `.claude/rules/plan-acceptance-gates.md`
+8. `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md`
+9. `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/user-story.md`
+10. `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/research/2026-09-17T11-20-breadcrumb-webview2-init-research.md`
+
+## Acceptance Criteria Count (mechanical)
+
+- Command: `Select-String -LiteralPath docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md -Pattern '^- \[ \] AC-U[1-9]:'`
+- EXIT_CODE: 0
+- Output Summary: 9 matches at `spec.md` lines 306, 307, 308, 309, 310, 311, 312, 313, 314 (AC-U1 through AC-U9 in order). All nine are unchecked `- [ ]` lines. `spec.md` lines 306-314 hold exactly nine `- [ ] AC-U` checkbox lines.
+
+## Notes
+
+- The plan's `## Acceptance Criteria` heading in `spec.md` is at line 304; the nine criteria immediately follow it.
+- `user-story.md` states that it carries no acceptance criteria of its own; it holds the AC-U5 manual runbook (lines 52-86).
+- The superseded research record `research/2026-09-12T10-30-breadcrumb-webview2-init-research.md` was not read and is not relied on, per the plan's Inputs section.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t10-ac-u1.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t10-ac-u1.md
new file mode 100644
index 000000000..ac464815f
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t10-ac-u1.md
@@ -0,0 +1,25 @@
+# [P7-T10] AC-U1 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 306 from `- [ ] AC-U1:` to `- [x] AC-U1:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U1:'` and `'^- \[ \] AC-U1:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U1: line 306 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`; the reference and current `spec.md` both have 401 lines.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:306`)
+
+```
+- [x] AC-U1: A failed `CoreWebView2` initialization is retried, and on final failure the Efc view shows a visible error state in the folder area instead of a blank list.
+```
+
+## Evidence the check-off rests on
+
+- [P3-T7] `evidence/regression-testing/p3-t7-fail-before.md` — observed failing on the unfixed tree: 18 of 31 tests failed on their pre-predicted assertions, including the retry tests (`InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce`, `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing`), the label test (`InitializeBreadcrumbHostAsync_OnFinalFailure_ShowsTheErrorTextInTheFolderAreaLabel`) and the router notification test (`InitializeBreadcrumbHostAsync_OnFinalFailure_NotifiesTheRouter`).
+- [P4-T11] `evidence/regression-testing/p4-t11-pass-after.md` — pass-after: `Total tests: 234`, `Passed: 234`; all 32 Issue792/contract tests pass.
+- [P5-T5] `evidence/regression-testing/p5-t5-ac-u1-mutation.md` — non-vacuity: mutation A (attempt limit 3 to 1) and mutation B (per-attempt report) each failed on the pre-predicted assertions (`Failed: 2` each), and each restoration returned `Passed: 2`.
+- D4 label carrier — `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs:114-129` `ShowFolderAreaError` writes `FolderAreaInitializationFailedText` to the existing folder-area label `EfcViewer.label2`; the final-pass coverage ([P7-T8] gate 2) records every new executable line of that file covered except the pre-declared `BeginInvoke` branch at line 128.
+
+## Positive control on the verification
+
+The comparator is `-ceq` on the substring after the checkbox: the current line with a single character appended compares false against the reference (see the control run recorded in [P7-T17]), and the whole line including the checkbox compares false (`- [x]` versus `- [ ]`), so `text-byte-identical-to-ref=True` is a discriminating result.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t11-ac-u2.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t11-ac-u2.md
new file mode 100644
index 000000000..38d551434
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t11-ac-u2.md
@@ -0,0 +1,21 @@
+# [P7-T11] AC-U2 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 307 from `- [ ] AC-U2:` to `- [x] AC-U2:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U2:'` and `'^- \[ \] AC-U2:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U2: line 307 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:307`)
+
+```
+- [x] AC-U2: `_pendingDocument` is never silently dropped: it is delivered when initialization later succeeds or an error is surfaced.
+```
+
+## Evidence the check-off rests on
+
+- [P3-T7] `evidence/regression-testing/p3-t7-fail-before.md` — observed failing: the pending-cleared tests (`NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner`, `NotifyInitializationFailed_LeavesNoStashForALaterInitialization`) failed on their pre-predicted assertions on the unfixed tree; the control `NotifyCoreInitialized_AfterAnEarlierStash_StillNavigatesIt` passed.
+- [P4-T11] `evidence/regression-testing/p4-t11-pass-after.md` — pass-after: `Total tests: 234`, `Passed: 234`.
+- [P5-T7] `evidence/regression-testing/p5-t7-ac-u2-mutation.md` — non-vacuity: with the pending-document clear removed, the pre-predicted `_navigated` count assertion failed (expected 1, found 2: banner then the replayed stale stash); restoration returned `Passed: 1`.
+- Final pass: [P7-T8] gate 3 records every added executable line of `BreadcrumbBridgeRouter.NotifyInitializationFailed` (including `_pendingDocument = null;` at line 354) covered.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t12-ac-u3.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t12-ac-u3.md
new file mode 100644
index 000000000..393252771
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t12-ac-u3.md
@@ -0,0 +1,24 @@
+# [P7-T12] AC-U3 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 308 from `- [ ] AC-U3:` to `- [x] AC-U3:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U3:'` and `'^- \[ \] AC-U3:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U3: line 308 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:308`)
+
+```
+- [x] AC-U3: The pop-out path carries the already-initialized folder predictor and loaded `MailItemHelper` from the QfcItem, following the #678 carry pattern, and constructs the `EfcViewer` on the UI thread.
+```
+
+## Evidence the check-off rests on
+
+- [P1-T4] `evidence/regression-testing/p1-t4-fail-before.md` — the UI-thread half observed failing: `ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke` (scheduler delegate identity) was among the 4 of 5 tests failing on the unfixed tree on its pre-predicted assertion.
+- [P3-T7] `evidence/regression-testing/p3-t7-fail-before.md` — the carry half observed failing: the adoption tests (`TryAdoptCarriedFolderHandler_*`, `InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry`), the carry-read tests (`ReadPopOutCarry_*`) and `EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController` failed on their pre-predicted assertions.
+- [P4-T11] `evidence/regression-testing/p4-t11-pass-after.md` — pass-after: `Total tests: 234`, `Passed: 234`.
+- [P5-T6] `evidence/regression-testing/p5-t6-ac-u3-deposit-mutation.md` — non-vacuity: deposit removed, the pre-predicted captured-handler reference assertion failed (`but found `); restoration returned `Passed: 1`.
+- [P5-T8] `evidence/regression-testing/p5-t8-ac-u3-adoption-mutation.md` — non-vacuity: adoption disabled, the pure adoption test failed on the pre-predicted boolean and the `InitFolderHandlerAsync` test on the pre-predicted unguarded construction path; restoration returned `Passed: 2`.
+- [P6-T4] `evidence/qa-gates/p6-t4-popout-ordering.md` — `ORDERING: PASS`: in both `PopOutControlGroup` and `PopOutControlGroupAsync` the `ReadPopOutCarry(group)` read precedes `RemoveSpecificControlGroup(Async)(selection)`, so the carry is read before `Cleanup` nulls the handler and helper.
+- Final pass: [P7-T8] gate 3 records the two deposit statements in `EfcHomeController.cs` (lines 87, 88), the `QfcItemController.FolderHandler` accessor (line 271) and the `EfcViewerQueue` initializer and reset (lines 25, 68) covered; the single body line of `InvokeOnUiDispatcher` (line 76) is `n/a` by D8, as the spec anticipates ("verifiable only as a scheduler-delegate assertion").
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t13-ac-u4.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t13-ac-u4.md
new file mode 100644
index 000000000..abc3d3632
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t13-ac-u4.md
@@ -0,0 +1,21 @@
+# [P7-T13] AC-U4 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 309 from `- [ ] AC-U4:` to `- [x] AC-U4:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U4:'` and `'^- \[ \] AC-U4:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U4: line 309 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:309`)
+
+```
+- [x] AC-U4: `PopulateFolderCombobox` and `InitializeBreadcrumbHostAsync` report failures through `TryReportBoundaryFault` to the user, not log-only.
+```
+
+## Evidence the check-off rests on
+
+- [P0-T15] `evidence/regression-testing/fail-before-exception.p0-t15.md` — the `PopulateFolderCombobox` half was already satisfied at baseline (`EfcFormController.cs:1270` called `TryReportBoundaryFault`), so a failing run was structurally impossible; the dossier records `Passed PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault`, `Total tests: 1`, `Passed: 1` on the unfixed tree as the absence-of-defect proof for that half.
+- [P1-T4] `evidence/regression-testing/p1-t4-fail-before.md` — the `InitializeBreadcrumbHostAsync` half observed failing: `InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser` and the strengthened `PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink` were among the 4 of 5 failing on their pre-predicted assertions.
+- [P4-T11] `evidence/regression-testing/p4-t11-pass-after.md` — pass-after: `Total tests: 234`, `Passed: 234`.
+- [P5-T1] `evidence/regression-testing/p5-t1-ac-u4-mutation.md` — non-vacuity: with the notifier call dropped inside `DefaultBoundaryErrorSink`, the new default-sink test failed on the pre-predicted `ContainSingle` assertion while the pre-existing sink-substituting test still passed (showing the strengthened test is the discriminating one); restoration returned `Passed: 2`.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t14-ac-u6.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t14-ac-u6.md
new file mode 100644
index 000000000..bc191b69f
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t14-ac-u6.md
@@ -0,0 +1,25 @@
+# [P7-T14] AC-U6 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 311 from `- [ ] AC-U6:` to `- [x] AC-U6:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U6:'` and `'^- \[ \] AC-U6:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U6: line 311 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:311`)
+
+```
+- [x] AC-U6: All three production WebView2 environment creations resolve their user-data folder and their additional browser arguments from one shared owner, and a test asserts the three agree.
+```
+
+## Evidence the check-off rests on
+
+- [P0-T14] `evidence/regression-testing/p0-t14-ac-u6-structural-fail-before.md` — the structural gate observed FAIL on the unfixed tree: `PRIMARY-CONSTRUCTION-COUNT: 3`, `CREATEASYNC-OUTSIDE-ADAPTER: 1`, `SEAM-CALLER-COUNT: 2`, `CONTRACT-READER-COUNT: 0`, `AC-U6-STRUCTURAL: FAIL`.
+- [P6-T1] `evidence/qa-gates/p6-t1-ac-u6-structural-pass.md` — the same gate, unchanged, on the fixed tree: 1 (the contract file) / 0 / 3 / 3, `AC-U6-STRUCTURAL: PASS`.
+- [P1-T4] `evidence/regression-testing/p1-t4-fail-before.md` — the site-1 seam test `InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` observed failing on the unfixed tree.
+- [P4-T4] `evidence/regression-testing/p4-t4-site3-mutation.md` — site 3 (`EfcItemController.InitializeWebViewAsync`, uninstrumented) proven through the seam: `EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam` passes unmutated and fails on the pre-predicted assertion when mutated; file restored byte-identical.
+- [P4-T11] `evidence/regression-testing/p4-t11-pass-after.md` — pass-after: `Total tests: 234`, `Passed: 234`, including the `WebView2EnvironmentContractTests` class that asserts the shared values.
+- [P5-T2] `evidence/regression-testing/p5-t2-ac-u6-site1-mutation.md` — non-vacuity: site 1 regressed to an inline construction fails the pre-predicted `AdditionalBrowserArguments` assertion and the structural gate (`PRIMARY-CONSTRUCTION-COUNT: 2`, FAIL); in its second half, site 2 (`QfcItemController.ViewerSetup.cs`, method-level exempt) regressed is caught structurally (`PRIMARY-CONSTRUCTION-COUNT: 2`, `CONTRACT-READER-COUNT: 2`, FAIL); both restored to 1/0/3/3 PASS.
+- [P5-T3] `evidence/regression-testing/p5-t3-ac-u6-constant-mutation.md` — non-vacuity: mutating the shared constant fails the three pre-predicted string-equality tests while the three contract-relative tests still pass; restoration returned `Passed: 6`.
+- Final pass: [P7-T8] gate 1 records `WebView2EnvironmentContract.cs` at 9/9 lines covered.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t15-ac-u7.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t15-ac-u7.md
new file mode 100644
index 000000000..fdc621283
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t15-ac-u7.md
@@ -0,0 +1,21 @@
+# [P7-T15] AC-U7 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 312 from `- [ ] AC-U7:` to `- [x] AC-U7:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U7:'` and `'^- \[ \] AC-U7:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U7: line 312 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:312`)
+
+```
+- [x] AC-U7: The breadcrumb outbound queue is not left to grow without bound after a failed initialization: a failure notification drains or discards it explicitly, and a test asserts its pending count is zero afterwards.
+```
+
+## Evidence the check-off rests on
+
+- [P3-T7] `evidence/regression-testing/p3-t7-fail-before.md` — observed failing: the queue tests (`DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending`, `DiscardPending_OnAnEmptyQueue_ReturnsZero`, `NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting`) failed on their pre-predicted assertions on the unfixed tree.
+- [P4-T11] `evidence/regression-testing/p4-t11-pass-after.md` — pass-after: `Total tests: 234`, `Passed: 234`.
+- [P5-T4] `evidence/regression-testing/p5-t4-ac-u7-mutation.md` — non-vacuity: with the discard skipped, the pre-predicted `PendingCount` assertion failed (expected 0, found 2); restoration returned `Passed: 1`.
+- Final pass: [P7-T8] gate 3 records the three `DiscardPending` statements (`BreadcrumbOutboundQueue.cs:75-77`) and the router's `_outboundQueue.DiscardPending()` call (`BreadcrumbBridgeRouter.cs:355`) covered.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t16-ac-u8.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t16-ac-u8.md
new file mode 100644
index 000000000..283f195b1
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t16-ac-u8.md
@@ -0,0 +1,20 @@
+# [P7-T16] AC-U8 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 313 from `- [ ] AC-U8:` to `- [x] AC-U8:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U8:'` and `'^- \[ \] AC-U8:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U8: line 313 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:313`)
+
+```
+- [x] AC-U8: No file created or modified by this change exceeds 500 lines, and every added or removed .cs file has a matching Compile item edit in its owning project file.
+```
+
+## Evidence the check-off rests on
+
+- [P7-T3] `evidence/qa-gates/p7-t3-file-size-audit.md` — authoritative post-format sizes: all 29 write-set `.cs` files measured after the final-pass format step; every file created by this change is at most 500 lines (largest new file `EfcFormController.EventHandlers.cs` at 383; largest new test file `EfcFormControllerIssue792Tests.cs` at 348); `UNEXPECTED-OVER-CEILING: 0`. The two modified files still over the ceiling (`EfcItemController.cs` 1076, `QfcCollectionController.cs` 2306) were over it before this change (1122 and 2333 at [P0-T8]) and are the pre-existing debt AC-U9 records; both shrank.
+- [P6-T3] `evidence/qa-gates/p6-t3-compile-item-parity.md` — Compile-item parity: `git diff --name-status $BaseSha HEAD -- '*.cs'` lists `A-ROWS: 17`, `D-ROWS: 0`; the two csproj diffs add exactly 17 bare ` ` elements and remove 0; `INCLUDE-SET-EQUALS-A-SET: True`; `UNTRACKED-SOURCE: none`.
+- [P0-T8] `evidence/baseline/p0-t8-line-counts.md` — the gate's FAIL state: the seventeen new paths recorded absent and `OVER-CEILING-BEFORE: 3`.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t17-ac-u9.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t17-ac-u9.md
new file mode 100644
index 000000000..f87cac3c5
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t17-ac-u9.md
@@ -0,0 +1,44 @@
+# [P7-T17] AC-U9 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-18
+- Command: edit `spec.md` line 314 from `- [ ] AC-U9:` to `- [x] AC-U9:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U9:'` and `'^- \[ \] AC-U9:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE; then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U[1-9]:'` and `'^- \[ \] AC-U[1-9]:'` (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, console encoding UTF-8; the helper's opening branch assertion passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U9: line 314 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `CHECKED-TOTAL: 8`; `OPEN-TOTAL: 1` (AC-U5, line 310, remains `- [ ]`); `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`; `git diff --numstat -- spec.md` prints `8 8`, that is exactly the eight checkbox lines changed and nothing else.
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:314`)
+
+```
+- [x] AC-U9: The pre-existing over-ceiling size of the two files that are not fully split is recorded explicitly in the change description as pre-existing debt, with the line counts before and after.
+```
+
+## Evidence the check-off rests on
+
+- [P7-T3] `evidence/qa-gates/p7-t3-file-size-audit.md`, the `PRE-EXISTING-DEBT:` line, verbatim:
+
+```
+PRE-EXISTING-DEBT: EfcItemController.cs before 1122 after 1076; QfcCollectionController.cs before 2333 after 2306
+```
+
+ with the accompanying statement that both files were over the ceiling at the [P0-T8] baseline, both shrank because members moved to new partials, neither is brought under the ceiling, and no new file exceeds it. ([P6-T2] carries the same figures as the advisory measurement.)
+
+## Whole-set verification (the [P7-T17] acceptance)
+
+| AC | line | state | text identical to reference |
+|---|---|---|---|
+| AC-U1 | 306 | `[x]` | true |
+| AC-U2 | 307 | `[x]` | true |
+| AC-U3 | 308 | `[x]` | true |
+| AC-U4 | 309 | `[x]` | true |
+| AC-U5 | 310 | `[ ]` (open; Phase 8, human-executed) | true |
+| AC-U6 | 311 | `[x]` | true |
+| AC-U7 | 312 | `[x]` | true |
+| AC-U8 | 313 | `[x]` | true |
+| AC-U9 | 314 | `[x]` | true |
+
+`'^- \[x\] AC-U[1-9]:'` returns 8; `'^- \[ \] AC-U[1-9]:'` returns 1. The reference (`SPEC-REF-SHA`) and the current `spec.md` both have 401 lines, and the `git diff -U0` shows 16 changed lines: the 8 removed `- [ ]` forms and the 8 added `- [x]` forms of AC-U1 through AC-U4 and AC-U6 through AC-U9.
+
+## Positive control on the comparator
+
+Run separately after the verification (same worktree, UTF-8 console): for AC-U1, `CONTROL-SAME-TEXT: True` (current text after the checkbox `-ceq` reference text after the checkbox), `CONTROL-MUTATED-TEXT: False` (the same with one character appended), `CONTROL-WHOLE-LINE-WITH-CHECKBOX: False` (the whole line compares unequal because only the checkbox differs). The comparator therefore discriminates a one-character change, and a `True` for the criterion text is a real byte-identity.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t3-ac-u5.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t3-ac-u5.md
new file mode 100644
index 000000000..8c6f44d4b
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t3-ac-u5.md
@@ -0,0 +1,36 @@
+# [P8-T3] AC-U5 check-off
+
+- Issue: #792
+- Timestamp: 2026-09-18T06-31
+- Command: edit `spec.md` line 310 from `- [ ] AC-U5:` to `- [x] AC-U5:` (checkbox only); then `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U5:'` and `'^- \[ \] AC-U5:'`; byte comparison of the text after the checkbox against the same line of `git show "${SpecRefSha}:$FEATURE/spec.md"` with `$SpecRefSha` bound by CMD-BASE (run from the gitignored `coverage/plan792-helper.ps1` under `pwsh -NoProfile -WorkingDirectory - -File`, console encoding UTF-8; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` passed; HEAD `986ce5aafb5cae63fb9a01ce1d904491ea2b3b95`); then a separate `pwsh -NoProfile -WorkingDirectory
- -Command` control run for the AC-U5 line specifically
+- EXIT_CODE: 0
+- Output Summary: `AC-U5: line 310 | checked=1 open=0 | ref-state '- [ ]' | text-byte-identical-to-ref=True`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`; `REF-SPEC-LINES: 401`, `CUR-SPEC-LINES: 401`; `SPEC-NUMSTAT-VS-HEAD: 1 1` (the AC-U5 line is the only change to `spec.md` since the [P7-T18] commit); `SPEC-CHANGED-CHECKBOX-LINES: 2` (`-- [ ] AC-U5:` removed, `+- [x] AC-U5:` added).
+- PostedAs: none (local `spec.md` check-off only; nothing was posted to GitHub)
+
+## Check-off line (verbatim, `spec.md:310`)
+
+```
+- [x] AC-U5: Manual verification on both entry points: pop-out from QuickFiler and ribbon Sort Email each show suggestion rows and respond to typed search.
+```
+
+Reference line at `SPEC-REF-SHA` (verbatim, line 310 of `git show 11b107a55fc32078f97e0cd48f893c175be5b6f4:$FEATURE/spec.md`):
+
+```
+- [ ] AC-U5: Manual verification on both entry points: pop-out from QuickFiler and ribbon Sort Email each show suggestion rows and respond to typed search.
+```
+
+## Evidence the check-off rests on
+
+- [P8-T2] `evidence/other/p8-t2-ac-u5-manual-verification.md` — the runbook's four observations all `PASS` and the artifact states `AC-U5: PASS`: pop-out from QuickFiler showed suggestion rows (maintainer-confirmed), typed search in the popped-out view changed the rows (maintainer-confirmed), ribbon Sort Email showed suggestion rows under "Matched Folders:" (maintainer-confirmed), and the session log (21:43:22 to 23:48:15) contains zero occurrences of `Breadcrumb CoreWebView2 initialization failed`, `0x8007139F` and `resource not in correct state` with the positive controls recorded there (instrument-verified).
+- [P8-T1] `evidence/other/p8-t1-addin-rebuild.md` — the session under test ran the add-in rebuilt from HEAD `986ce5aaf` (assembly mtime 21:27:02, manifests generated 21:43:18, add-in startup 21:43:22).
+
+## Positive control on the comparator (separate run, AC-U5 line)
+
+- `CONTROL-SAME-TEXT: True` — current text after the checkbox `-ceq` reference text after the checkbox.
+- `CONTROL-MUTATED-TEXT: False` — the same with one character appended.
+- `CONTROL-CASE-FLIP: False` — the same with the current text upper-cased (`-ceq` is case-sensitive).
+- `CONTROL-WHOLE-LINE-WITH-CHECKBOX: False` — the whole line compares unequal because only the checkbox differs (`- [x]` versus `- [ ]`).
+
+The comparator discriminates a one-character change and a case change, so `text-byte-identical-to-ref=True` is a real byte-identity.
+
+Note on the helper: the helper script's own final control line (`CONTROL-MUTATED-TEXT-DETECTED`) raised a non-terminating `InvalidOperation` (`[System.Char] does not contain a method named 'Substring'`) and printed an empty value; this is a defect in that gitignored helper line, not in the verification above, which is why the control was run separately (as [P7-T17] also did). The helper's exit code was 0 and every verification line before the control printed as recorded.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t4-ac-status.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t4-ac-status.md
new file mode 100644
index 000000000..a489926cc
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t4-ac-status.md
@@ -0,0 +1,61 @@
+# [P8-T4] Acceptance reconciliation over spec.md
+
+- Issue: #792
+- Timestamp: 2026-09-18T06-32
+- Command: `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[x\] AC-U[1-9]:'` and `'^- \[ \] AC-U[1-9]:'`; CMD-BASE (binds `$BaseSha` and `$SpecRefSha` from `evidence/baseline/p0-t7-git-base.md`); `git diff --numstat $SpecRefSha -- $FEATURE/spec.md`; `git diff --stat $SpecRefSha -- $FEATURE/spec.md`; `git diff -U0 $SpecRefSha -- $FEATURE/spec.md` with every `-`/`+` line paired in order and compared: prefix `- [ ] ` on the removed line, prefix `- [x] ` on the added line, and the text after the checkbox `-ceq` (run under `pwsh -NoProfile -WorkingDirectory
- -Command`, console encoding UTF-8, on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`, HEAD `986ce5aafb5cae63fb9a01ce1d904491ea2b3b95`)
+- EXIT_CODE: 0
+- Output Summary: `CHECKED: 9`; `OPEN: 0`; `SPEC-REF-SHA: 11b107a55fc32078f97e0cd48f893c175be5b6f4`; `BASE-SHA: e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3`; `git diff --numstat` prints `9 9` for `spec.md` (`1 file changed, 9 insertions(+), 9 deletions(-)`), that is exactly nine changed lines; the `-U0` diff has 9 removed and 9 added lines, and each of the nine pairs (AC-U1 through AC-U9) reports `only-checkbox-differs=True`; `NON-AC-CHANGED-LINES: 0`; `EVERY-CHANGED-LINE-IS-A-CHECKBOX-FLIP: True`.
+
+### Acceptance Criteria Status
+- Source: docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md
+- Total AC items: 9
+- Checked off (delivered): 9
+- Remaining (unchecked): 0
+- Items remaining: none
+
+## Per-criterion state (spec.md lines 306-314)
+
+| AC | line | state | text byte-identical to `SPEC-REF-SHA` | check-off artifact |
+|---|---|---|---|---|
+| AC-U1 | 306 | `[x]` | true | `evidence/issue-updates/p7-t10-ac-u1.md` |
+| AC-U2 | 307 | `[x]` | true | `evidence/issue-updates/p7-t11-ac-u2.md` |
+| AC-U3 | 308 | `[x]` | true | `evidence/issue-updates/p7-t12-ac-u3.md` |
+| AC-U4 | 309 | `[x]` | true | `evidence/issue-updates/p7-t13-ac-u4.md` |
+| AC-U5 | 310 | `[x]` | true | `evidence/issue-updates/p8-t3-ac-u5.md` (human-executed runbook, [P8-T2]) |
+| AC-U6 | 311 | `[x]` | true | `evidence/issue-updates/p7-t14-ac-u6.md` |
+| AC-U7 | 312 | `[x]` | true | `evidence/issue-updates/p7-t15-ac-u7.md` |
+| AC-U8 | 313 | `[x]` | true | `evidence/issue-updates/p7-t16-ac-u8.md` |
+| AC-U9 | 314 | `[x]` | true | `evidence/issue-updates/p7-t17-ac-u9.md` |
+
+The per-line byte-identity column is the `text-byte-identical-to-ref=True` result of the [P8-T3] helper run over all nine criteria (reference and current `spec.md` both 401 lines).
+
+## Positive controls on the counting patterns
+
+- `'^- \[[ x]\] AC-U[1-9]:'` (either checkbox state) returns 9, equal to checked + open, so the two counting patterns partition the nine criterion lines with none unaccounted for.
+- `'^- \[x\] AC-U0:'` returns 0: a pattern for a criterion that does not exist returns zero from the same cmdlet, so the 9 is not an artefact of a permissive pattern.
+- The pairwise comparison uses `-ceq` (case-sensitive ordinal); the [P8-T3] control run showed it returns `False` for a one-character append and for a case change of the same text.
+
+## Diff shape (`git diff -U0 $SpecRefSha -- spec.md`, changed lines truncated to 22 characters)
+
+```
+-- [ ] AC-U1: A failed
+-- [ ] AC-U2: `_pendin
+-- [ ] AC-U3: The pop-
+-- [ ] AC-U4: `Populat
+-- [ ] AC-U5: Manual v
+-- [ ] AC-U6: All thre
+-- [ ] AC-U7: The brea
+-- [ ] AC-U8: No file
+-- [ ] AC-U9: The pre-
++- [x] AC-U1: A failed
++- [x] AC-U2: `_pendin
++- [x] AC-U3: The pop-
++- [x] AC-U4: `Populat
++- [x] AC-U5: Manual v
++- [x] AC-U6: All thre
++- [x] AC-U7: The brea
++- [x] AC-U8: No file
++- [x] AC-U9: The pre-
+```
+
+No task in this plan edited any criterion text; every change to `spec.md` since `SPEC-REF-SHA` is a checkbox flip.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p0-t2-outlook-closed.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p0-t2-outlook-closed.md
new file mode 100644
index 000000000..52719561e
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p0-t2-outlook-closed.md
@@ -0,0 +1,11 @@
+# [P0-T2] Human checkpoint — Outlook closed before any build
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-34
+- Command: `$outlook = Get-Process -Name OUTLOOK -ErrorAction SilentlyContinue; if ($outlook) { Write-Output 'HALT: Outlook is running. Close Outlook through File > Exit (never end the process), then re-run this task.'; exit 2 }; Write-Output 'OUTLOOK-CLOSED: true'` (CMD-OUTLOOK, run under `pwsh -NoProfile` with the item worktree as the working directory)
+- EXIT_CODE: 0
+- Output Summary: `OUTLOOK-CLOSED: true`. No `HALT:` line was printed. No process named `OUTLOOK` was found.
+
+## Human confirmation
+
+Outlook was closed by a person through its normal exit path before this check ran; the maintainer confirmed in the Phase 0 delegation that Outlook was verified not running immediately before execution began. No process was ended by this task or by any other task in this plan; `Stop-Process` was not called.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p2-t14-independent-confirmation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p2-t14-independent-confirmation.md
new file mode 100644
index 000000000..99816cf91
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p2-t14-independent-confirmation.md
@@ -0,0 +1,34 @@
+# Phase 2 independent confirmation: [P2-T14] re-run and em-dash conservation re-check
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-29
+- Command: the [P2-T14] command sequence exactly as recorded in `evidence/regression-testing/p2-t14-pure-move-proof.md` (CMD-OUTLOOK, CMD-VSTEST, CMD-BUILD-PLAIN, CMD-SCOPED-RUN with `
` = `p2-t14`), run synchronously a second time from `coverage/plan792-helper.ps1` with the item worktree as the working directory, plus a byte-level non-ASCII scan over the six `QuickFiler/Controllers/EfcFormController*.cs` parts against `git show 0d0275e99:QuickFiler/Controllers/EfcFormController.cs`
+- EXIT_CODE: 0
+- Output Summary: second run reproduced the recorded result exactly: `Test Run Successful.`; `Total tests: 187`; `Passed: 187`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; `Total time: 2.3218 Seconds`; CMD-BUILD-PLAIN `EXIT_CODE: 0`, `Build succeeded.`, ` 0 Warning(s)`, ` 0 Error(s)` (exact-line match true). Em-dash re-check: the six parts contain 2 non-ASCII lines, the original contains 2, and no mojibake was found; no edit was needed.
+
+## Why this artifact exists
+
+This executor was relaunched with the instruction to execute [P2-T13] through [P2-T15] on the belief that the earlier executor had stopped. The earlier executor was still live in this worktree: it wrote its [P2-T14] artifact at 19:26, committed [P2-T15] as `11f5aa598` at 19:28:54 and checked off [P2-T14] and [P2-T15] in the plan at 19:29:36, while this executor's own [P2-T14] run was in progress. This executor's write of `p2-t14-pure-move-proof.md` briefly overwrote the committed artifact in the working copy; it was restored from `HEAD` (`git checkout HEAD -- `) and this executor's observations are recorded here instead, in `evidence/other/`, so the committed [P2-T14] evidence is unchanged. No source file was written by this executor. Detection signals: plan-file check-off count advanced during a read-only interval, and HEAD advanced from `0d0275e99` to `11f5aa598` between two status samples.
+
+## [P2-T14] second-run observations (TRX and console)
+
+- `COUNTERS: total=187 executed=187 passed=187 failed=0`; `OUTCOME: 187 Passed`; 187 `Passed ` console lines; zero `Failed ` and zero `Skipped ` lines; `TRX-PRESENT: true` under the gitignored `coverage/test-results/p2-t14/`.
+- Positive controls on the filter: each of the eight `FullyQualifiedName~` alternatives matched discovered tests (`EfcFormControllerTests` 32, `EfcItemControllerTests` 10, `EfcDataModel` 33, `QfcCollectionControllerTests` 13, `ViewerQueueStaticWrapperTests` 8, `BreadcrumbBridgeRouterQueueTests` 26, `WebView2BreadcrumbHostTests` 8, `EfcHomeController` 57; 17 classes, 187 total). `ISSUE792-CLASSES-IN-RUN: 0`, so the three Phase 1 `*Issue792Tests` classes with their four `[expect-fail]` tests were not selected, as intended. `Select-String -SimpleMatch 'LiveOutlook'` over `QuickFiler.Test/` returns 0 files, so the absence of a `TestCategory` clause selects no live-Outlook test.
+- Build non-vacuity: `BUILD-CSC-INVOCATIONS: 0`, `BUILD-CORECOMPILE-SKIPPED: 18` (incremental). `QuickFiler/bin/Debug/QuickFiler.dll` 19:24:31 and `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` 19:24:34 were produced by the [P2-T13] `/t:Rebuild`; the newest source under `QuickFiler/` and `QuickFiler.Test/` (`*.cs`, `*.csproj`, excluding `bin/` and `obj/`) is 19:23:59, so the assemblies under test embody the committed Phase 2 tree.
+
+## Em-dash conservation re-check (`QuickFiler/Controllers/EfcFormController.cs:195`)
+
+The relaunch instruction reported one non-ASCII line across the six parts against two in the original, attributing the loss to a hyphen substituted for the em dash in the doc comment now at line 195. Re-derived byte-level (`[System.IO.File]::ReadAllBytes`, UTF-8 decode, per-line scan for any code point above U+007F, plus a scan for the mojibake sequences `Ã` and `â€`):
+
+| File | Lines | BOM | Non-ASCII lines |
+|---|---|---|---|
+| `QuickFiler/Controllers/EfcFormController.cs` | 266 | yes | 2: line 1 (U+FEFF, BOM) and line 195 (U+2014, em dash) |
+| `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs` | 243 | no | 0 |
+| `QuickFiler/Controllers/EfcFormController.EventHandlers.cs` | 383 | no | 0 |
+| `QuickFiler/Controllers/EfcFormController.Actions.cs` | 184 | no | 0 |
+| `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` | 125 | no | 0 |
+| `QuickFiler/Controllers/EfcFormController.Helpers.cs` | 270 | no | 0 |
+
+- `NON-ASCII-LINE-COUNT: 2`; `MOJIBAKE-LINE-COUNT: 0`; every part is CRLF-only (LF count equals CRLF count in each).
+- Original at `0d0275e99`: `ORIGINAL-NON-ASCII-LINE-COUNT: 2`, the same two lines (the BOM-prefixed `using System;` and the `load-bearing rather than defensive —` doc-comment line).
+- Conclusion: line 195 already holds U+2014 on disk; the parts are byte-faithful to the original for this line. No file was edited. The reported count of one is consistent with the instrument effect recorded in `evidence/qa-gates/p2-t13-compile-gate.md` (a `git show` stream decoded as code page 437 turns U+2014 into three characters and the BOM line into a differently filtered line), not with any loss in the working tree.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p7-t1-outlook-closed.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p7-t1-outlook-closed.md
new file mode 100644
index 000000000..1afada1c9
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p7-t1-outlook-closed.md
@@ -0,0 +1,15 @@
+# [P7-T1] Human checkpoint — Outlook closed before the final rebuilds
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-02
+- Command: `$outlook = Get-Process -Name OUTLOOK -ErrorAction SilentlyContinue; if ($outlook) { Write-Output 'HALT: Outlook is running. Close Outlook through File > Exit (never end the process), then re-run this task.'; exit 2 }; Write-Output 'OUTLOOK-CLOSED: true'` (CMD-OUTLOOK, run from `coverage/plan792-helper.ps1 -Step outlook` under `pwsh -NoProfile` with the item worktree as the working directory; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: `OUTLOOK-CLOSED: true`. No `HALT:` line was printed. No process named `OUTLOOK` was found.
+
+## Positive control
+
+The same `Get-Process -Name -ErrorAction SilentlyContinue` form applied to `pwsh` returned 9 processes in the same invocation, so a null result for `OUTLOOK` is a true absence rather than a cmdlet that reports nothing.
+
+## Human confirmation
+
+The maintainer confirmed in the Phase 7 delegation that Outlook was verified not running immediately before this phase began. No process was ended by this task or by any other task in this plan; `Stop-Process` was not called. Because the loop in this phase can restart and every build task ([P7-T4], [P7-T5]) re-runs CMD-OUTLOOK, a running Outlook at any later check HALTS that task for a human rather than being closed by the executor.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t1-addin-rebuild.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t1-addin-rebuild.md
new file mode 100644
index 000000000..4ad0ec05d
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t1-addin-rebuild.md
@@ -0,0 +1,71 @@
+# [P8-T1] Human checkpoint and add-in rebuild
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-26
+- Command: CMD-OUTLOOK, then `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU"` (plain Rebuild, no analyzer or nullable switch, as the task text specifies; run from the gitignored `coverage/p8-t1-rebuild.ps1` under `pwsh -NoProfile -WorkingDirectory - -File`; the script's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; `CWD-LEAF: item-792`; HEAD `986ce5aafb5cae63fb9a01ce1d904491ea2b3b95`; console output captured to the gitignored `coverage/p8-t1-rebuild.log`; the exit code was read from `$LASTEXITCODE` at script scope immediately after the native call, not from captured output)
+- EXIT_CODE: 0
+- Output Summary:
+ - `OUTLOOK-CLOSED: true` (printed first; no `HALT:` line; no process named `OUTLOOK` was found; no process was ended and `Stop-Process` was not called)
+ - `Build succeeded.` (1 line; `Build FAILED.` 0 lines)
+ - ` 0 Warning(s)` (verbatim msbuild summary line)
+ - ` 0 Error(s)` (verbatim msbuild summary line; exact-line match `^\s+0 Error\(s\)$` = 1)
+ - `Time Elapsed 00:00:16.11`; 11698 log lines; 0 lines matching `: error `; 0 lines matching `: warning `; 0 lines matching `MSB3021`.
+ - Build timestamp: started 2026-09-17T21:26:52, ended 2026-09-17T21:27:08 (local time).
+
+## CMD-OUTLOOK gate
+
+- Result: `OUTLOOK-CLOSED: true`.
+- Positive control: the same `Get-Process -Name
-ErrorAction SilentlyContinue` form applied to `pwsh` returned 10 processes in the same invocation, so the null result for `OUTLOOK` is a true absence.
+- Resident processes at gate time: `MSBuild` 0, `vstest.console` 2 (two-day-old orphans from a dead session, per the delegation), `testhost` 0. Issue #906 describes the resident-worker contention condition; no contention symptom (lock error, `MSB3021`, nondeterministic failure) was observed in this run.
+
+## Non-vacuity check of the Rebuild
+
+From `coverage/p8-t1-rebuild.log`:
+
+- CSC-INVOCATIONS: 36 (lines naming `csc.exe`/`csc.dll`; equal to the [P7-T4] and [P0-T10] counts), of which 1 names `/out:...TaskMaster.dll`
+- CORECOMPILE lines: 80 counted unanchored (`CoreCompile:`); an anchored `^CoreCompile:` count is not used because `/m` prefixes secondary-node lines with `N>`
+- CORECOMPILE-SKIPPED: 0 (no `Skipping target "CoreCompile"` line)
+- PROJECTS-DONE-REBUILD: 18 lines matching `Done Building Project .*\.csproj" \(Rebuild target\(s\)\)`; 0 lines carry `(default targets)`, so every project was driven by the Rebuild target
+- `MSBUILD-ON-PATH: True`
+
+## Add-in output assembly (proof the add-in was rewritten)
+
+LastWriteTime (local time) before and after the run:
+
+| Assembly | Before | After |
+|---|---|---|
+| `TaskMaster/bin/Debug/TaskMaster.dll` (the add-in) | 2026-09-17 21:08:08 | 2026-09-17 21:27:02 |
+| `TaskMaster/bin/Debug/QuickFiler.dll` (copied dependency, source of the fix) | not sampled before the run | 2026-09-17 21:26:59 |
+| `QuickFiler/bin/Debug/QuickFiler.dll` | 2026-09-17 21:08:05 | 2026-09-17 21:26:59 |
+| `UtilitiesCS/bin/Debug/UtilitiesCS.dll` | 2026-09-17 21:08:02 | 2026-09-17 21:26:56 |
+
+The add-in assembly's LastWriteTime advanced into the build window (21:26:52 to 21:27:08), the csc invocation count matches the earlier full rebuilds, and no `CoreCompile` target was skipped; the three signals agree that `TaskMaster/bin/Debug` now holds the add-in compiled from HEAD `986ce5aaf`.
+
+Observation as recorded at 21:27 (SUPERSEDED — see "Correction: the manifest gap was real" below): no `TaskMaster.vsto` or `TaskMaster.dll.manifest` exists in `TaskMaster/bin/Debug` after the run and the log never invokes a manifest-generation target. `TaskMaster/TaskMaster.csproj` (line 550) imports `Microsoft.VisualStudio.Tools.Office.targets` only when `BuildingInsideVisualStudio` is `true`, and its comment (lines 546-549) states that command-line builds "only need the compiled add-in assembly". Every earlier build in this plan produced the same output shape. The 21:27 record described this as "not a defect" and "by design"; that framing was wrong for the purpose of this task, because a registered `|vstolocal` add-in cannot load without the `.vsto` deployment manifest.
+
+## Correction: the manifest gap was real
+
+The 21:27 check found `TaskMaster.vsto` and `TaskMaster.dll.manifest` BOTH ABSENT. That was a real gap, not a moot caveat: with the registered manifest pointing at `TaskMaster/bin/Debug/TaskMaster.vsto`, Outlook had nothing to load. A manifest-generating build (one with `BuildingInsideVisualStudio` true, that is a build driven from Visual Studio) closed the gap between the command-line rebuild and the verification session. Observed on 2026-09-18 (`Get-Item` over the item worktree's `TaskMaster/bin/Debug`):
+
+| File | Length | LastWriteTime (local) |
+|---|---|---|
+| `TaskMaster/bin/Debug/TaskMaster.vsto` | 6615 | 2026-09-17 21:43:18 |
+| `TaskMaster/bin/Debug/TaskMaster.dll.manifest` | 86173 | 2026-09-17 21:43:18 |
+| `TaskMaster/bin/Debug/TaskMaster.dll` | 294400 | 2026-09-17 21:27:02 (unchanged from the table above) |
+
+The two manifests were written sixteen minutes after the command-line rebuild ended (21:27:08) and four seconds before the add-in's `ThisAddIn_Startup()` fired (21:43:22). `TaskMaster.dll` kept its 21:27:02 timestamp, so the manifests were generated over the assembly this task rebuilt, not over a newer one; the add-in that Outlook loaded is the one compiled from HEAD `986ce5aaf`.
+
+Instruction for the next reader: after a command-line `msbuild` rebuild of this solution, the manifest-generation step is a separate, required action before Outlook can load the `|vstolocal` add-in. Do not skip it as a non-issue.
+
+## Maintainer confirmation (recorded 2026-09-18T06-28)
+
+The task's second half, "the person reopens Outlook and confirms the add-in loaded", is recorded here from the maintainer's direct verification, with the registry and log facts re-derived by the executor on 2026-09-18.
+
+- Registered add-in: `HKCU\Software\Microsoft\Office\Outlook\Addins\TaskMaster` has `LoadBehavior` = 3 and `Manifest` resolving to the item worktree's `TaskMaster/bin/Debug/TaskMaster.vsto` with the `|vstolocal` suffix (re-derived: `Get-ItemProperty` on that key; the manifest string contains `/item-792/TaskMaster/bin/Debug/TaskMaster.vsto` and ends `|vstolocal`; the absolute prefix is deliberately not transcribed).
+- Outlook reopened at: process start 2026-09-17 21:43:18 (`Get-Process -Name OUTLOOK`, `StartTime`, still running on 2026-09-18); add-in session start 2026-09-17 21:43:22 (`ThisAddIn_Startup() fired`, first line of the worktree's own `TaskMaster/bin/Debug/logs/debug_2026-09-17.log`).
+- Add-in loaded: YES. Observed by the maintainer through the add-in's ribbon and QuickFiler/Efc views being usable in that session ([P8-T2] records the runbook observations), and instrument-verified by the session log in this worktree's own `TaskMaster/bin/Debug/logs/` directory, which the add-in writes only when it is running from this output directory. The log's first line is the add-in startup event at 21:43:22,837 and its `QuickFiler.*` loggers wrote lines during the session.
+- Recorded by / at: atomic-executor on behalf of the maintainer's stated observation, 2026-09-18T06-28 (local).
+
+No process was ended at any point; Outlook was still running when this confirmation was recorded and was not closed or killed by the executor.
+
+With this confirmation the task's acceptance is fully satisfied: `OUTLOOK-CLOSED: true` before the build, `EXIT_CODE: 0` with the exact `0 Error(s)` line, the build timestamp, and the person's confirmation that Outlook was reopened with the add-in loaded, with no `Stop-Process` anywhere. Nothing in this artifact is evidence about AC-U5 itself; that is [P8-T2].
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t2-ac-u5-manual-verification.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t2-ac-u5-manual-verification.md
new file mode 100644
index 000000000..8284763c5
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t2-ac-u5-manual-verification.md
@@ -0,0 +1,103 @@
+# [P8-T2] AC-U5 manual verification (runbook, user-story.md lines 52-86)
+
+- Issue: #792
+- Timestamp: 2026-09-18T06-30
+- Command: human execution of the AC-U5 runbook (steps 1-9, both entry points, QuickFiler opened first so an item-body WebView was already running) against the Outlook session that loaded the add-in rebuilt in [P8-T1]; step 9 instrumented by the executor with `Get-Content -LiteralPath TaskMaster/bin/Debug/logs/debug_2026-09-17.log` piped to `Select-String -SimpleMatch -CaseSensitive` for each literal below, plus a header-regex parse of every line into `(level, logger)` (run under `pwsh -NoProfile -WorkingDirectory - `; the log path is relative to the item worktree and the log file is not committed)
+- EXIT_CODE: 0
+- Output Summary: Outlook session start 2026-09-17 21:43:22 (add-in `ThisAddIn_Startup() fired`; process start 21:43:18). Observations 1-3 maintainer-confirmed PASS; observation 4 instrument-verified PASS: 0 occurrences of `Breadcrumb CoreWebView2 initialization failed`, 0 of `0x8007139F`, 0 of `resource not in correct state` in a 284,409-byte log spanning 21:43:22 to 23:48:15, with 103 lines written by `QuickFiler.*` loggers and 40 `ERROR`-level lines (all unrelated) as positive controls. `AC-U5: PASS`.
+
+## Session
+
+- Outlook process start: 2026-09-17 21:43:18 (`Get-Process -Name OUTLOOK`, `StartTime`; pid observed once, still running on 2026-09-18 and not closed or killed by the executor).
+- Add-in session start: 2026-09-17 21:43:22,837, the first line of the log: `ThisAddIn_Startup() fired` (transcribed under "Log lines inspected").
+- Add-in loaded from this worktree's `TaskMaster/bin/Debug` (registry `Manifest` resolves to that directory's `TaskMaster.vsto|vstolocal`, `LoadBehavior` 3; see [P8-T1]).
+- Ordering precondition of the runbook honoured: QuickFiler was opened first (step 4), so an item-body WebView was running before the first Efc pop-out (step 5). The log shows `QuickFiler.Controllers.QfcFormController` and `QuickFiler.Controllers.QfcItemController` lines before the first `QuickFiler.Controllers.EfcDataModel` constructor line at 21:45:13.
+
+## The four observations
+
+The runbook's pass/fail section (user-story.md lines 75-84) lists four observations. They fall into two evidentiary classes, kept separate here.
+
+### Maintainer-confirmed (human observation, reported by the person who ran the session)
+
+1. Step 5, pop-out from QuickFiler into the Efc view: the folder area showed one or more suggestion rows, not a blank list. **PASS**.
+2. Step 6, typed search in the popped-out Efc view: the visible rows changed in response to the typed text. **PASS**.
+3. Step 7, ribbon Sort Email: the area under the "Matched Folders:" label showed one or more suggestion rows, not a blank list. **PASS**.
+
+These three are the maintainer's direct observations of the running UI. The executor did not and cannot observe them; they are recorded as reported.
+
+### Instrument-verified (measured by the executor against the session log)
+
+4. Step 9, session log clean. **PASS**.
+ - Log file: the item worktree's `TaskMaster/bin/Debug/logs/debug_2026-09-17.log` (relative path; the file is not committed).
+ - Size 284,409 bytes; 1,361 lines; last written 2026-09-17 23:48:15; first timestamp 21:43:22,837, last timestamp 23:48:15,842. The file has been growing during the session (an earlier figure of 279,805 bytes at 21:47 was supplied to the executor and is superseded by this later measurement).
+ - `Breadcrumb CoreWebView2 initialization failed`: 0 occurrences (case-sensitive literal).
+ - `0x8007139F`: 0 occurrences (case-sensitive literal); `8007139F` case-insensitive: 0.
+ - `resource not in correct state`: 0 occurrences (case-sensitive literal).
+ - `initialization failed` case-insensitive: 0. `Breadcrumb` (any case-sensitive occurrence): 0.
+ - `WebView2` (case-insensitive): 3 lines, all `QfcFormController.ParkFocusAndCancelSelectors entered. WebView2Focused=False ...` DEBUG lines tagged Issue #796 (transcribed below); none is an initialization event or an error.
+
+The verification passes only if all four hold. All four hold.
+
+AC-U5: PASS
+
+## Positive controls that make observation 4 meaningful
+
+A zero-match is uninformative on its own: it is equally consistent with the breadcrumb host's logger never reaching this appender, and with a mistyped pattern. The following establish the instrument.
+
+- **Same pattern form finds known-present text.** In the same invocation, `Select-String -SimpleMatch -CaseSensitive 'tesseract'` returned 38 lines. The zero counts above come from the same cmdlet and switches, so they are true zeros for this file.
+- **The QuickFiler namespace reaches this appender.** A header-regex parse of the file (1,120 of 1,361 lines parse as log headers; the remaining 241 are stack-trace continuation lines) attributes 103 lines to loggers in the `QuickFiler.*` namespace: `QuickFiler.Helper_Classes.ConversationResolver` 38, `QuickFiler.Controllers.QfcFormController` 36, `QuickFiler.Controllers.QfcItemController` 18, `QuickFiler.Controllers.EfcDataModel` 7, `QuickFiler.Controllers.QfcHomeController` 2, `QuickFiler.EfcHomeController` 2. (A looser count of lines containing the token `QuickFiler.` anywhere, including inside messages and stack frames, is 126; the 103 figure is the logger-field count and is the one relied on.)
+- **Inference from log4net hierarchical routing (not a direct observation).** `WebView2BreadcrumbHost` is `QuickFiler.Viewers.WebView2BreadcrumbHost` (re-derived at execution time: `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` line 11 `namespace QuickFiler.Viewers`, line 34 `public sealed class WebView2BreadcrumbHost`; the plan's self-review cites line 12 for the namespace, which is off by one against the current tree). Under log4net's hierarchical logger configuration, a `QuickFiler.Viewers.*` logger inherits the appenders of its `QuickFiler` ancestors, so an `ERROR` from the breadcrumb host would have landed in this file. `QuickFiler.Viewers.*` itself has zero lines, which is the expected shape: that class logs only on failure. This step is an inference from configuration, not something the session log shows directly.
+- **The error path to this file is live.** 40 `ERROR`-level lines exist (level token parsed from the header): 38 from `UtilitiesCS.EmailIntelligence.ImageStripper` (tesseract engine initialisation) and 2 from `UtilitiesCS.OutlookObjects.Store.StoreWrapper` (PrimarySmtpAddress on a secondary inbox). All are unrelated to the breadcrumb host; their presence proves that `ERROR` writes from the add-in reach this file during this session. (A case-insensitive count of the token `error` anywhere in a line is 48; the 40 figure is the level-field count. A figure of 48 `ERROR` entries was supplied to the executor and is superseded by the level-parsed 40.)
+
+## Why observation 4 is the discriminating observation
+
+AC-U1 adds a retry to `CoreWebView2` initialization. A session can therefore look entirely correct to a person (observations 1-3 all PASS) while the log still records the initialization failing on a first attempt and recovering on a retry. Observations 1-3 cannot separate "the three environment-creation sites genuinely converged on one owner and the user-data-folder conflict is gone" from "the retry is masking a conflict that still occurs on every pop-out". A clean log, with the error path proven live, separates them: zero initialization failures across both entry points and a two-hour session means no attempt failed, so nothing was retried and nothing was masked.
+
+## Log lines inspected (transcribed as text; no log file committed)
+
+Lines are transcribed verbatim except that no line containing an absolute host path was selected for transcription (22 lines of the file contain one inside stack frames or file paths; none of them is relevant to observation 4). The line numbers are those of the file at the 23:48:15 measurement.
+
+Session start (line 1):
+
+```
+2026-09-17 21:43:22,837 [VSTA_Main] DEBUG TaskMaster.ThisAddIn [(null)] - ThisAddIn_Startup() fired
+```
+
+The three `WebView2`-mentioning lines (the only such lines; DEBUG, unrelated to initialization):
+
+```
+L1236: 2026-09-17 21:45:15,502 [VSTA_Main] DEBUG QuickFiler.Controllers.QfcFormController [(null)] - Issue #796: QfcFormController.ParkFocusAndCancelSelectors entered. WebView2Focused=False ActiveFormNull=False Groups=8
+L1285: 2026-09-17 21:46:24,814 [VSTA_Main] DEBUG QuickFiler.Controllers.QfcFormController [(null)] - Issue #796: QfcFormController.ParkFocusAndCancelSelectors entered. WebView2Focused=False ActiveFormNull=False Groups=8
+L1322: 2026-09-17 21:47:53,493 [VSTA_Main] DEBUG QuickFiler.Controllers.QfcFormController [(null)] - Issue #796: QfcFormController.ParkFocusAndCancelSelectors entered. WebView2Focused=False ActiveFormNull=False Groups=8
+```
+
+First Efc data-model line (evidence that the Efc view was constructed after QuickFiler was already open):
+
+```
+L1228: 2026-09-17 21:45:13,654 [VSTA_Main] DEBUG QuickFiler.Controllers.EfcDataModel [(null)] - [Data model timing] EfcDataModel constructor load start | constructor load | threadId=1; syncContext=System.Windows.Forms.WindowsFormsSynchronizationContext
+```
+
+Representative `ERROR` lines (the two StoreWrapper lines and the first of the 38 ImageStripper lines; the error path is live and every error is unrelated):
+
+```
+L157: 2026-09-17 21:43:56,433 [VSTA_Main] ERROR UtilitiesCS.OutlookObjects.Store.StoreWrapper [(null)] - Error retrieving PrimarySmtpAddress from secondary inbox. The operation failed.
+L180: 2026-09-17 21:43:56,550 [VSTA_Main] ERROR UtilitiesCS.OutlookObjects.Store.StoreWrapper [(null)] - Error retrieving PrimarySmtpAddress from secondary inbox. The operation failed.
+2026-09-17 21:43:59,742 [5] ERROR UtilitiesCS.EmailIntelligence.ImageStripper [(null)] - Failed to initialise tesseract engine.. See https://github.com/charlesw/tesseract/wiki/Error-1 for details.
+```
+
+Search results for the failure literals (each `Select-String -SimpleMatch -CaseSensitive` over the whole file):
+
+```
+COUNT [Breadcrumb CoreWebView2 initialization failed]: 0
+COUNT [0x8007139F]: 0
+COUNT [resource not in correct state]: 0
+COUNT [Breadcrumb]: 0
+COUNT [QuickFiler.Viewers]: 0
+COUNT [tesseract]: 38 (positive control, same cmdlet and switches)
+```
+
+## Scope notes
+
+- This task is human-executed for observations 1-3 and is not automated; no `[TestMethod]` exists for AC-U5 and none counts toward any figure (plan decision D11).
+- The log file stays in the gitignored `TaskMaster/bin/Debug/logs/` directory; only the transcriptions above are committed.
+- Outlook was running throughout and was not closed or ended by the executor.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t5-terminal.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t5-terminal.md
new file mode 100644
index 000000000..a70186dfc
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t5-terminal.md
@@ -0,0 +1,47 @@
+# [P8-T5] Terminal commit and clean-tree proof
+
+- Issue: #792
+- Timestamp: 2026-09-18T06-34
+- Command: `git add -- docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "chore(792): manual verification evidence and acceptance reconciliation"` (run with `git -C
- ` on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim); then `git status --porcelain --untracked-files=all -- . ':(exclude).claude/agent-memory'` and `git rev-parse HEAD`; then (after this artifact is written) `git add -- docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` and `git commit --amend --no-edit`; then the [P8-T5] check-off in the plan as the final edit
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 56ff697f] chore(792): manual verification evidence and acceptance reconciliation`; `7 files changed, 329 insertions(+), 6 deletions(-)`; five evidence files created (`p8-t1-addin-rebuild.md`, `p8-t2-ac-u5-manual-verification.md`, `p8-t3-ac-u5.md`, `p8-t4-ac-status.md` and the Phase 7 residual `p7-t18-commit.md`), `plan.2026-09-17T07-30.md` modified with the [P7-T18] and [P8-T1] through [P8-T4] check-offs, `spec.md` modified with the AC-U5 check-off; the porcelain capture below is empty; no source, project, solution or configuration path was staged or committed.
+
+## Porcelain capture (verbatim, `git status --porcelain --untracked-files=all -- . ':(exclude).claude/agent-memory'`, immediately after the first commit)
+
+```
+```
+
+The capture is empty: nothing outside the feature folder is dirty and nothing ending `.cs`, `.csproj`, `.sln` or `packages.config` is dirty. The scoped source porcelain of convention 9 (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) also printed nothing when run before the commit.
+
+## HEAD observation
+
+COMMIT-SHA-OBSERVED (before amend): 56ff697f12ab0805fbccf3751fc7d7c21c07d053
+
+PARENT-SHA: 986ce5aafb5cae63fb9a01ce1d904491ea2b3b95 (the [P7-T18] commit)
+
+The amend that follows (sweeping this artifact into the same commit) rewrites the commit object, so the post-amend head SHA differs from the value above. The post-amend SHA is reported in the executor's completion message; this file cannot record it without a further amend, and the plan authorizes exactly one.
+
+## Paths in the first commit (`git show --name-only --format= HEAD`, 7 paths, verbatim)
+
+```
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t3-ac-u5.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p8-t4-ac-status.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t1-addin-rebuild.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p8-t2-ac-u5-manual-verification.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t18-commit.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md
+```
+
+Every path starts with `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/`. After the amend the commit additionally contains `evidence/other/p8-t5-terminal.md` (this file).
+
+## Residual outside the plan's pathspecs (recorded, not an acceptance clause)
+
+`git status --porcelain --untracked-files=all` without the exclusion lists `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from an earlier executor and outside the plan's add pathspecs; they were deliberately left uncommitted, as in [P7-T18].
+
+## Expected end state after the amend and the final check-off
+
+- `git diff --numstat HEAD --
/plan.2026-09-17T07-30.md` prints `1 1` for exactly that one file: the [P8-T5] check-off is the sole permitted residual.
+- `git status --porcelain --untracked-files=all -- . ':(exclude).claude/agent-memory' ':(exclude)/plan.2026-09-17T07-30.md'` prints nothing.
+
+Git printed `LF will be replaced by CRLF` warnings for the Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p2-t13-compile-gate.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p2-t13-compile-gate.md
new file mode 100644
index 000000000..4565d920b
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p2-t13-compile-gate.md
@@ -0,0 +1,73 @@
+# [P2-T13] Phase 2 compile gate
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-24
+- Command: CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true`), then CMD-BUILD-ANALYZE (`msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true`), then CMD-BUILD-NULLABLE (`msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true`), then `dotnet tool run csharpier check QuickFiler/Controllers QuickFiler/Viewers "QuickFiler/Helper Classes" QuickFiler.Test/Controllers QuickFiler.Test/Viewers "QuickFiler.Test/Helper Classes"` (all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; msbuild console output captured to the gitignored `coverage/p2-t13-analyze.log` and `coverage/p2-t13-nullable.log`, formatter output to `coverage/p2-t13-csharpier.log`)
+- EXIT_CODE: 0
+- Output Summary:
+ - `OUTLOOK-CLOSED: true` (printed first; no `HALT:` line)
+ - CMD-BUILD-ANALYZE: `EXIT_CODE: 0`; `Build succeeded.`; ` 0 Warning(s)`; ` 0 Error(s)` (exact-line match `^\s+0 Error\(s\)$` = true); 16 s; 11871 log lines
+ - CMD-BUILD-NULLABLE: `EXIT_CODE: 0`; `Build succeeded.`; ` 0 Warning(s)`; ` 0 Error(s)` (exact-line match = true); 17 s; 11708 log lines
+ - csharpier scoped check: `EXIT_CODE: 0`; `Checked 308 files in 2385ms.` (the exit-0 branch of the acceptance held; no reference to `BASELINE-DRIFT-SET` was needed)
+
+## Non-vacuity of both Rebuilds (from the captured logs)
+
+| Gate | CSC-INVOCATIONS | CORECOMPILE-SKIPPED | PROJECTS-DONE-REBUILD | QuickFiler.dll rewritten | QuickFiler.Test.dll rewritten |
+|---|---|---|---|---|---|
+| analyze | 36 | 0 | 18 | 19:24:14 | 19:24:17 |
+| nullable | 36 | 0 | 18 | 19:24:31 | 19:24:34 |
+
+msbuild was resolved from `PATH` (`MSBUILD-ON-PATH: true`).
+
+## Earlier attempts inside this task (recorded, not counted)
+
+1. Attempt 1 (19:21): CMD-BUILD-ANALYZE failed with `1 Error(s)`: `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs(47,13): error CS1061: 'SynchronizationContext' does not contain a definition for 'GetAwaiter'`. Cause: the moved `InitializeWebViewAsync` body awaits `_itemViewer.UiSyncContext`, which resolves through the extension `UiThread.GetAwaiter(this SynchronizationContext)` in namespace `UtilitiesCS` (`UtilitiesCS/Threading/UiThread.cs:211`); the retained `EfcItemController.cs` imports `UtilitiesCS` (line 21) but the using list [P2-T3] names for the new part does not. Repair: added `using UtilitiesCS;` to the new part (now 70 lines, ceiling 80; CRLF, no BOM; formatter-clean). Deviation from the plan's stated using list, recorded here.
+2. Attempt 2 (19:23): discarded as vacuous. The helper's build function named its parameter `$args`, which PowerShell's automatic `$args` shadows inside a function, so msbuild ran with no arguments (default `/t:Build`, no properties): `CORECOMPILE-SKIPPED: 13`, `PROJECTS-DONE-REBUILD: 0`, and the "nullable" pass ran in 1 s with 0 `csc` invocations. The parameter was renamed and a guard added (`throw 'build arguments missing'` when fewer than five arguments are bound). This attempt's scoped formatter check was, however, a genuine observation and reported two unformatted files (below).
+3. Attempt 3 (19:24): the run recorded above.
+
+## Formatter repair inside this task (new files only, per the task's repair clause)
+
+The attempt-2 scoped check reported `Was not formatted` for two Phase 1 test files, both created new in Phase 1 and neither in `BASELINE-DRIFT-SET` (empty). Each was repaired with `dotnet tool run csharpier format ` and re-checked:
+
+| File | SHA-256 before | SHA-256 after | Lines after | Ceiling |
+|---|---|---|---|---|
+| `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs` | A56A4298214DE585DB52E6F4AB2F264C5D2DD14A87D59D207A63C94A3BC1FCC3 | 961366098F99D4C8FD0D70D2A6BBEADD9CCDBAFF4380AAF606F7451433045543 | 153 | 200 |
+| `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs` | B333546067323A370FBB2CD4BB8DE7338C41F3156FEE907F2443A1EA8E4FBCC2 | 8F319773F59B7CE351C72973E5C396DEDC9078FC9A991728BC5EED128A2C7422 | 40 | 120 |
+
+Both files remained CRLF with no BOM after the rewrite. The re-check over the three test directories printed `Checked 173 files` with exit 0, and the full scoped check in attempt 3 printed `Checked 308 files` with exit 0. Every Phase 2 file (nine new production parts, twelve edited files) had already passed a per-file read-only check before the gate ran.
+
+## Phase 2 line counts at this gate (`(Get-Content -LiteralPath ).Count`)
+
+| File | Lines | Bound |
+|---|---|---|
+| `QuickFiler/Controllers/EfcFormController.cs` | 266 | 400 |
+| `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs` | 243 | 400 |
+| `QuickFiler/Controllers/EfcFormController.EventHandlers.cs` | 383 | 400 |
+| `QuickFiler/Controllers/EfcFormController.Actions.cs` | 184 | 400 |
+| `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` | 125 | 160 |
+| `QuickFiler/Controllers/EfcFormController.Helpers.cs` | 270 | 400 |
+| `QuickFiler/Viewers/WebView2EnvironmentContract.cs` | 53 | 60 |
+| `QuickFiler/Controllers/EfcItemController.cs` | 1076 | 1076 or 1077 |
+| `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` | 70 | 80 |
+| `QuickFiler/Controllers/QfcCollectionController.cs` | 2306 | 2306 or 2307 |
+| `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` | 93 | 120 |
+| `QuickFiler/Controllers/EfcDataModel.cs` | 464 | 464 or 465 |
+| `QuickFiler/Controllers/EfcDataModel.Carry.cs` | 62 | 90 |
+| `QuickFiler/Controllers/QfcItemController.cs` | 340 | 345 |
+| `QuickFiler/Controllers/EfcHomeController.cs` | 464 | 470 |
+| `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` | 421 | (edited; numstat 14 0) |
+| `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` | 73 | (edited; numstat 6 0) |
+| `QuickFiler/Helper Classes/EfcViewerQueue.cs` | 108 | (edited; numstat 7 0) |
+
+Compile items added to `QuickFiler/QuickFiler.csproj` (numstat `9 0` against BASE-SHA; no trailing newline, matching the base file): `Controllers\EfcDataModel.Carry.cs`, `Controllers\EfcFormController.Actions.cs`, `Controllers\EfcFormController.Breadcrumb.cs`, `Controllers\EfcFormController.EventHandlers.cs`, `Controllers\EfcFormController.Helpers.cs`, `Controllers\EfcFormController.SetupAndProperties.cs`, `Controllers\EfcItemController.WebViewEnvironment.cs`, `Controllers\QfcCollectionController.PopOut.cs`, `Viewers\WebView2EnvironmentContract.cs`; each a bare self-closing element immediately after the neighbour its task names.
+
+## Conservation gates (Phase 2 pure moves)
+
+| Task | Type | Before multiset | After multiset | CONSERVATION-DIFF-COUNT | Positive control (a result file omitted) |
+|---|---|---|---|---|---|
+| [P2-T1] | `EfcFormController` | 875 | 875 | 0 | 56 (without `Breadcrumb.cs`) |
+| [P2-T3] | `EfcItemController` | 739 | 739 | 0 | 37 (retained file only) |
+| [P2-T4] | `QfcCollectionController` | 1533 | 1533 | 0 | 15 (retained file only) |
+| [P2-T5] | `EfcDataModel` | 320 | 320 | 0 | 24 (retained file only) |
+
+Instrument correction, recorded: the plan's gate reads the base file through `git show`, and the console decodes that byte stream as code page 437 by default (`[Console]::OutputEncoding` = `ibm437`) while `Get-Content` decodes the result files as UTF-8; the base file's UTF-8 BOM also arrives as U+FEFF on its first line, which `Trim()` does not remove. Run literally, the [P2-T1] gate printed `CONSERVATION-DIFF-COUNT: 3` whose three entries were one mis-decoded em-dash (U+2014 read as `0393 00C7 00F6`) on each side and the BOM-prefixed `using System;` line; the files on disk were verified byte-correct (`git diff --numstat` for the retained file is `1 1056`, i.e. only the declaration line changed). The gate was therefore run with `[Console]::OutputEncoding` set to UTF-8 for the `git show` read and with a leading U+FEFF stripped from the first line; the multiset semantics are unchanged. The uncorrected instrument was re-run once for the record (`UNCORRECTED-INSTRUMENT-DIFF-COUNT: 3`).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p2-t15-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p2-t15-commit.md
new file mode 100644
index 000000000..d7bf2f5df
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p2-t15-commit.md
@@ -0,0 +1,34 @@
+# [P2-T15] Phase 2 commit
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-31
+- Command: `git add -- QuickFiler QuickFiler.Test docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "refactor(792): partial splits, environment contract, declaration-only seams"` (run with `git -C ` against the item worktree on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim)
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 11f5aa59] refactor(792): partial splits, environment contract, declaration-only seams`; `28 files changed, 2082 insertions(+), 1186 deletions(-)`; 12 source files created, 11 source files modified, 5 feature-folder paths (4 created, the plan file modified with the [P2-T1] through [P2-T14] check-offs).
+
+## Acceptance observations
+
+`git show --name-only --format= HEAD` listed 28 paths:
+
+- Nine new production files: `QuickFiler/Viewers/WebView2EnvironmentContract.cs`, `QuickFiler/Controllers/EfcFormController.Actions.cs`, `EfcFormController.Breadcrumb.cs`, `EfcFormController.EventHandlers.cs`, `EfcFormController.Helpers.cs`, `EfcFormController.SetupAndProperties.cs`, `EfcItemController.WebViewEnvironment.cs`, `QfcCollectionController.PopOut.cs`, `EfcDataModel.Carry.cs`.
+- Three new test files (created in Phase 1, first committed here): `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs`, `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs`, `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs`.
+- Two project files: `QuickFiler/QuickFiler.csproj` (9 bare Compile items), `QuickFiler.Test/QuickFiler.Test.csproj` (3 bare Compile items from Phase 1).
+- Nine edited `.cs` files named by [P2-T1] through [P2-T12]: `EfcFormController.cs`, `EfcItemController.cs`, `QfcCollectionController.cs`, `EfcDataModel.cs`, `BreadcrumbBridgeRouter.cs`, `BreadcrumbOutboundQueue.cs`, `QfcItemController.cs`, `EfcHomeController.cs`, `Helper Classes/EfcViewerQueue.cs`.
+- Five paths under the feature folder: `plan.2026-09-17T07-30.md`, `evidence/baseline/p0-t16-commit.md`, `evidence/regression-testing/p1-t4-fail-before.md`, `evidence/qa-gates/p2-t13-compile-gate.md`, `evidence/regression-testing/p2-t14-pure-move-proof.md`.
+- Nothing else.
+
+`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` printed nothing.
+
+`git status --porcelain --untracked-files=all` immediately after the commit listed only `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from the Phase 1 executor and outside the plan's add pathspecs.
+
+COMMIT-SHA-OBSERVED: 11f5aa59816a73a0ee8bb5f6e9545b6b37962563
+
+## Residual (recorded, not an acceptance clause)
+
+This artifact and the [P2-T15] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 2 (convention 9 treats docs and evidence as expected-dirty). No source path is dirty.
+
+Git printed five `LF will be replaced by CRLF` warnings for Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
+
+## Concurrent-actor observation
+
+Between [P2-T14] and [P2-T15] the gitignored helper `coverage/plan792-helper.ps1` was rewritten on disk by an actor other than this executor (a read-only encoding probe over the six `EfcFormController` parts; mtime 19:28:19). No source file changed after this executor's last write (latest source mtime 19:23:59), which was re-verified before committing by re-running the four conservation gates, the seam-token searches, and a read-only formatter check over all 21 Phase 1/2 files (`Checked 21 files`, exit 0). Subsequent helpers for this executor were placed in the session scratchpad outside the worktree.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p4-t12-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p4-t12-commit.md
new file mode 100644
index 000000000..1ad472a16
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p4-t12-commit.md
@@ -0,0 +1,79 @@
+# [P4-T12] Phase 4 commit
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-12
+- Command: `git add -- QuickFiler QuickFiler.Test docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "fix(792): converge WebView2 environment contract, bounded breadcrumb retry, explicit discard, pop-out carry"` (run from `coverage/plan792-helper.ps1` with the item worktree as the working directory, on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim); then `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` and `git diff --name-only $BaseSha HEAD -- '*.cs' '*.csproj'` with `$BaseSha` bound by CMD-BASE
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 c2a55b23] fix(792): converge WebView2 environment contract, bounded breadcrumb retry, explicit discard, pop-out carry`; `14 files changed, 507 insertions(+), 94 deletions(-)`; 9 production files and 1 test file modified, 4 feature-folder paths (3 evidence files created, the plan file modified with the [P3-T8] and [P4-T1] through [P4-T11] check-offs); scoped porcelain printed nothing; the BASE-SHA-to-HEAD `.cs`/`.csproj` footprint lists exactly 30 paths.
+
+COMMIT-SHA-OBSERVED: c2a55b23523636e9f4d47b169d95bf8b596085c9
+
+PARENT-SHA: 494f71381790c1f2f57531c0269eabe79890ad63 (the [P3-T8] commit)
+
+## Paths in the commit (`git show --stat --format= HEAD`, 14 paths)
+
+- `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` (+84)
+- `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` (+32, 0 deletions)
+- `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs`
+- `QuickFiler/Controllers/EfcDataModel.Carry.cs`
+- `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs`
+- `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs`
+- `QuickFiler/Controllers/QfcCollectionController.PopOut.cs`
+- `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs`
+- `QuickFiler/Helper Classes/EfcViewerQueue.cs`
+- `QuickFiler/Viewers/WebView2BreadcrumbHost.cs`
+- `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t8-commit.md` (the Phase 3 residual left uncommitted by construction after [P3-T8])
+- `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t4-site3-mutation.md`
+- `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t11-pass-after.md`
+- `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md`
+
+No `.csproj`, no `.runsettings`, no `.config` and no file outside `QuickFiler/`, `QuickFiler.Test/` or the feature folder is in the commit.
+
+## Acceptance observations
+
+`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` printed nothing.
+
+`git diff --name-only e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3 HEAD -- '*.cs' '*.csproj'` (BASE-SHA to HEAD), recorded verbatim, 30 paths:
+
+```
+QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs
+QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs
+QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs
+QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs
+QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs
+QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs
+QuickFiler.Test/QuickFiler.Test.csproj
+QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs
+QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs
+QuickFiler/Controllers/BreadcrumbBridgeRouter.cs
+QuickFiler/Controllers/BreadcrumbOutboundQueue.cs
+QuickFiler/Controllers/EfcDataModel.Carry.cs
+QuickFiler/Controllers/EfcDataModel.cs
+QuickFiler/Controllers/EfcFormController.Actions.cs
+QuickFiler/Controllers/EfcFormController.Breadcrumb.cs
+QuickFiler/Controllers/EfcFormController.EventHandlers.cs
+QuickFiler/Controllers/EfcFormController.Helpers.cs
+QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs
+QuickFiler/Controllers/EfcFormController.cs
+QuickFiler/Controllers/EfcHomeController.cs
+QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs
+QuickFiler/Controllers/EfcItemController.cs
+QuickFiler/Controllers/QfcCollectionController.PopOut.cs
+QuickFiler/Controllers/QfcCollectionController.cs
+QuickFiler/Controllers/QfcItemController.ViewerSetup.cs
+QuickFiler/Controllers/QfcItemController.cs
+QuickFiler/Helper Classes/EfcViewerQueue.cs
+QuickFiler/QuickFiler.csproj
+QuickFiler/Viewers/WebView2BreadcrumbHost.cs
+QuickFiler/Viewers/WebView2EnvironmentContract.cs
+```
+
+PATH-COUNT: 30. The list is exactly the plan's 31-entry write set minus `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` (listed: 0), and nothing else.
+
+## Residual (recorded, not an acceptance clause)
+
+`git status --porcelain --untracked-files=all` immediately after the commit listed only `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from the Phase 1 executor and outside the plan's add pathspecs; they were deliberately left uncommitted.
+
+This artifact and the [P4-T12] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 4 (convention 9 treats docs and evidence as expected-dirty). No source path is dirty. The Phase 5 commit will sweep them, as this commit swept the Phase 3 residual `p3-t8-commit.md`.
+
+Git printed four `LF will be replaced by CRLF` warnings for Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t1-ac-u6-structural-pass.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t1-ac-u6-structural-pass.md
new file mode 100644
index 000000000..99039e486
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t1-ac-u6-structural-pass.md
@@ -0,0 +1,54 @@
+# [P6-T1] AC-U6 structural gate — observed PASSING on the fixed tree
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-51
+- Command: `pwsh -NoProfile -WorkingDirectory -File coverage/plan792-helper.ps1` where `coverage/plan792-helper.ps1` was rewritten in place (convention 8) to hold the CMD-AC-U6-GATE block from the plan verbatim, character-identical to the block run in [P0-T14] (`` is the item worktree root; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `9ac987a969d1f4786d296fee25817c8e5dde9233`)
+- EXIT_CODE: 0
+- Output Summary: `AC-U6-STRUCTURAL: PASS` — one primary construction site (the contract file), zero direct `CoreWebView2Environment.CreateAsync` calls outside the adapter, three seam callers, three contract readers. Every line of the output matches the [P6-T1] declared post-fix output, including `git ls-files` ordering.
+
+OBSERVED-FAILING: [P0-T14] (`$FEATURE/evidence/regression-testing/p0-t14-ac-u6-structural-fail-before.md`) recorded the identical script printing `PRIMARY-CONSTRUCTION-COUNT: 3`, `CREATEASYNC-OUTSIDE-ADAPTER: 1`, `SEAM-CALLER-COUNT: 2`, `CONTRACT-READER-COUNT: 0`, `AC-U6-STRUCTURAL: FAIL` on the unfixed tree at HEAD `11b107a55fc32078f97e0cd48f893c175be5b6f4`. The gate was therefore seen failing before it was seen passing. The gate text was not adjusted between the two runs.
+
+## Gate output (verbatim, complete)
+
+```
+PRIMARY-CONSTRUCTION-COUNT: 1
+PRIMARY-SITE: QuickFiler/Viewers/WebView2EnvironmentContract.cs:50
+CREATEASYNC-OUTSIDE-ADAPTER: 0
+SEAM-CALLER-COUNT: 3
+SEAM-CALLER: QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs:46
+SEAM-CALLER: QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:66
+SEAM-CALLER: QuickFiler/Viewers/WebView2BreadcrumbHost.cs:279
+CONTRACT-READER-COUNT: 3
+CONTRACT-READER: QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs:40
+CONTRACT-READER: QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:57
+CONTRACT-READER: QuickFiler/Viewers/WebView2BreadcrumbHost.cs:264
+AC-U6-STRUCTURAL: PASS
+```
+
+## Clause-by-clause comparison with the [P6-T1] declaration
+
+| Declared | Observed | Match |
+|---|---|---|
+| `PRIMARY-CONSTRUCTION-COUNT: 1` | `PRIMARY-CONSTRUCTION-COUNT: 1` | true |
+| one `PRIMARY-SITE: QuickFiler/Viewers/WebView2EnvironmentContract.cs:` | `PRIMARY-SITE: QuickFiler/Viewers/WebView2EnvironmentContract.cs:50` (the `return new CoreWebView2EnvironmentOptions(AdditionalBrowserArguments);` statement) | true |
+| `CREATEASYNC-OUTSIDE-ADAPTER: 0`, no `CREATEASYNC-SITE:` line | `CREATEASYNC-OUTSIDE-ADAPTER: 0`, no `CREATEASYNC-SITE:` line printed | true |
+| `SEAM-CALLER-COUNT: 3` | `SEAM-CALLER-COUNT: 3` | true |
+| three `SEAM-CALLER:` lines naming `EfcItemController.WebViewEnvironment.cs`, `QfcItemController.ViewerSetup.cs`, `WebView2BreadcrumbHost.cs` in that (`git ls-files`) order | `:46`, `:66`, `:279` in that order | true |
+| `CONTRACT-READER-COUNT: 3` | `CONTRACT-READER-COUNT: 3` | true |
+| three `CONTRACT-READER:` lines naming the same three files in the same order | `:40`, `:57`, `:264` in that order | true |
+| `AC-U6-STRUCTURAL: PASS` | `AC-U6-STRUCTURAL: PASS` | true |
+
+The `git ls-files` byte order places `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` before `QuickFiler/Controllers/EfcItemController.cs` and both `Controllers/` entries before `Viewers/`, which is the order observed.
+
+## Positive control (independent tool, before trusting the counts)
+
+A separate Grep over `QuickFiler/**/*.cs` (no Designer exclusion, no comment filter) was run alongside the gate:
+
+- Type name `CoreWebView2EnvironmentOptions`: 10 hits in 6 files — `IWebViewCoreInitializer.cs:17` (doc comment), `:51` (parameter); `WebView2BreadcrumbHost.cs:264`; `WebView2EnvironmentContract.cs:48` (return type), `:50` (the sole `new` construction); `WebView2CoreInitializer.cs:37`, `:69` (parameters); `EfcItemController.WebViewEnvironment.cs:25` (doc comment), `:40`; `QfcItemController.ViewerSetup.cs:57`. The two `///` doc-comment lines are removed by the gate's `^\s*//` filter; of the remaining eight, only `WebView2EnvironmentContract.cs:50` matches either construction regex (the three `options = WebView2EnvironmentContract.CreateOptions();` lines contain no `new`), which reproduces `PRIMARY-CONSTRUCTION-COUNT: 1` by an independent path.
+- `\.CreateEnvironmentAsync\(`: exactly 3 hits, `EfcItemController.WebViewEnvironment.cs:46`, `WebView2BreadcrumbHost.cs:279`, `QfcItemController.ViewerSetup.cs:66` — the same three lines the gate lists.
+- `WebView2EnvironmentContract\.CreateOptions\(`: exactly 3 hits, `EfcItemController.WebViewEnvironment.cs:40`, `QfcItemController.ViewerSetup.cs:57`, `WebView2BreadcrumbHost.cs:264` — the same three lines the gate lists.
+- `CoreWebView2Environment\.CreateAsync\(`: 2 hits, `WebView2CoreInitializer.cs:72` (the adapter forward, excluded by the gate's adapter-path filter) and `QfcItemController.ViewerSetup.cs:119` (`//var task = ...`, excluded by the comment filter). No live call outside the adapter exists, so `CREATEASYNC-OUTSIDE-ADAPTER: 0` is a true zero and not a mis-scoped pattern. `EfcItemController.cs:195`, the live call reported by [P0-T14], is gone.
+
+The dead comment lines `QfcItemController.ViewerSetup.cs:61` and `EfcItemController.cs:187` that [P0-T14] reported as excluded by the comment filter no longer exist on the fixed tree (the type-name Grep above returns no hit in `EfcItemController.cs` and no `//`-prefixed hit in `QfcItemController.ViewerSetup.cs`); the comment filter is still exercised by the two `///` doc-comment lines and by `QfcItemController.ViewerSetup.cs:119`.
+
+Gate script not weakened: the block enumerates by type name over `git ls-files -- ':(glob)QuickFiler/**/*.cs'`, excludes Designer files and comment lines, and requires the construction regex; it is not a literal search for `new CoreWebView2EnvironmentOptions`.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t2-line-counts-advisory.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t2-line-counts-advisory.md
new file mode 100644
index 000000000..f9d641223
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t2-line-counts-advisory.md
@@ -0,0 +1,66 @@
+# [P6-T2] Advisory line-count audit and AC-U9 measurement (post-change)
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-53
+- Command: `(Get-Content -LiteralPath ).Count` per write-set `.cs` path (convention 3: total lines, never `Measure-Object -Line`, never non-blank counts), run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `9ac987a969d1f4786d296fee25817c8e5dde9233`)
+- EXIT_CODE: 0
+- Output Summary: 29 write-set `.cs` paths measured (20 production, 9 test), `MISSING-COUNT: 0`; `OVER-CEILING-AFTER: 2` (`EfcItemController.cs` 1076, `QfcCollectionController.cs` 2306, both pre-existing); `UNEXPECTED-OVER-CEILING: 0`; retained `EfcFormController.cs` is 266 (`OVER-CEILING: false`). This audit is advisory; [P7-T3] is authoritative.
+
+## Production write-set `.cs` files (total line count)
+
+| Path | Lines | OVER-CEILING |
+|---|---|---|
+| `QuickFiler/Viewers/WebView2EnvironmentContract.cs` | 53 | false |
+| `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` | 382 | false |
+| `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` | 474 | false |
+| `QuickFiler/Controllers/EfcItemController.cs` | 1076 | true (pre-existing, allowed by the [P6-T2] acceptance) |
+| `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` | 56 | false |
+| `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` | 453 | false |
+| `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` | 80 | false |
+| `QuickFiler/Controllers/EfcFormController.cs` | 266 | false |
+| `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` | 178 | false |
+| `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs` | 243 | false |
+| `QuickFiler/Controllers/EfcFormController.EventHandlers.cs` | 383 | false |
+| `QuickFiler/Controllers/EfcFormController.Actions.cs` | 184 | false |
+| `QuickFiler/Controllers/EfcFormController.Helpers.cs` | 270 | false |
+| `QuickFiler/Controllers/QfcCollectionController.cs` | 2306 | true (pre-existing, allowed by the [P6-T2] acceptance) |
+| `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` | 111 | false |
+| `QuickFiler/Controllers/EfcHomeController.cs` | 464 | false |
+| `QuickFiler/Controllers/EfcDataModel.cs` | 464 | false |
+| `QuickFiler/Controllers/EfcDataModel.Carry.cs` | 100 | false |
+| `QuickFiler/Controllers/QfcItemController.cs` | 340 | false |
+| `QuickFiler/Helper Classes/EfcViewerQueue.cs` | 108 | false |
+
+## Test write-set `.cs` files (total line count)
+
+| Path | Lines | OVER-CEILING |
+|---|---|---|
+| `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs` | 153 | false |
+| `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` | 192 | false |
+| `QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs` | 196 | false |
+| `QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs` | 113 | false |
+| `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs` | 348 | false |
+| `QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs` | 213 | false |
+| `QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs` | 175 | false |
+| `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs` | 40 | false |
+| `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` | 485 | false (unchanged from the [P0-T8] baseline of 485; zero-edit by design) |
+
+PRODUCTION-ROWS: 20
+TEST-ROWS: 9
+MISSING-COUNT: 0
+
+OVER-CEILING-AFTER: 2
+
+UNEXPECTED-OVER-CEILING: 0 (every write-set `.cs` file except `QuickFiler/Controllers/EfcItemController.cs` and `QuickFiler/Controllers/QfcCollectionController.cs` is at most 500)
+
+## AC-U9 statement
+
+PRE-EXISTING-DEBT: EfcItemController.cs before 1122 after 1076; QfcCollectionController.cs before 2333 after 2306
+
+The remaining over-ceiling size of these two files is pre-existing debt that this change neither introduces nor resolves. Both files were over the 500-line ceiling at the [P0-T8] baseline (`OVER-CEILING-BEFORE: 3`, listed there as 2333, 1321 and 1122), and both shrank in this change because members moved out to new partials (`EfcItemController.WebViewEnvironment.cs`, `QfcCollectionController.PopOut.cs`); neither is brought under the ceiling, and no new file exceeds it. The measured values fall inside the plan's expected ranges (1076 or 1077; 2306 or 2307).
+
+`EfcFormController.cs`: before 1321 (from [P0-T8]), after 266; retained file `OVER-CEILING: false`. The third file over the ceiling at baseline is therefore resolved by the six-way split (D9), which is why `OVER-CEILING-BEFORE: 3` becomes `OVER-CEILING-AFTER: 2`.
+
+## Positive control
+
+`CONTROL-KNOWN-OVER: true` — the same `(Get-Content -LiteralPath ...).Count -gt 500` expression applied to `QuickFiler/Controllers/QfcCollectionController.cs` returned true, so the `OVER-CEILING: false` rows are produced by a comparison that does fire when a file is over the ceiling. `MISSING-COUNT: 0` was computed by `Test-Path -LiteralPath` over all 29 paths, so no row is a count over an absent file.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t3-compile-item-parity.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t3-compile-item-parity.md
new file mode 100644
index 000000000..6a8fba16e
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t3-compile-item-parity.md
@@ -0,0 +1,111 @@
+# [P6-T3] AC-U8 compile-item parity
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-54
+- Command: CMD-BASE (binds `$BaseSha` from `p0-t7-git-base.md`), then `git diff --name-status $BaseSha HEAD -- '*.cs'`; `git diff $BaseSha HEAD -- QuickFiler/QuickFiler.csproj QuickFiler.Test/QuickFiler.Test.csproj`; `git diff --numstat $BaseSha HEAD -- QuickFiler.Test/Controllers/EfcFormControllerTests.cs`; `git status --porcelain --untracked-files=all -- '*.cs' '*.csproj'`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `9ac987a969d1f4786d296fee25817c8e5dde9233`)
+- EXIT_CODE: 0
+- Output Summary: name-status lists 28 rows: `A-ROWS: 17`, `D-ROWS: 0`, `M-ROWS: 11`, every `A` and `M` path a write-set member; the two csproj diffs carry `CSPROJ-ADDED-LINES: 17`, all 17 bare self-closing ` ` elements, `CSPROJ-REMOVED-LINES: 0`; `INCLUDE-SET-EQUALS-A-SET: True` (17 = 17, no path on either side only); `EFCFORMCONTROLLERTESTS-DIFF: none`; `UNTRACKED-SOURCE: none`.
+
+BASE-SHA: e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3 (read by CMD-BASE from `$FEATURE/evidence/baseline/p0-t7-git-base.md`, itself the `git merge-base HEAD origin/main` after `git fetch origin`; bare local `main` was not used)
+
+## `git diff --name-status $BaseSha HEAD -- '*.cs'` (verbatim, 28 rows)
+
+```
+A QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs
+A QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs
+A QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs
+A QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs
+A QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs
+A QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs
+A QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs
+A QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs
+M QuickFiler/Controllers/BreadcrumbBridgeRouter.cs
+M QuickFiler/Controllers/BreadcrumbOutboundQueue.cs
+A QuickFiler/Controllers/EfcDataModel.Carry.cs
+M QuickFiler/Controllers/EfcDataModel.cs
+A QuickFiler/Controllers/EfcFormController.Actions.cs
+A QuickFiler/Controllers/EfcFormController.Breadcrumb.cs
+A QuickFiler/Controllers/EfcFormController.EventHandlers.cs
+A QuickFiler/Controllers/EfcFormController.Helpers.cs
+A QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs
+M QuickFiler/Controllers/EfcFormController.cs
+M QuickFiler/Controllers/EfcHomeController.cs
+A QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs
+M QuickFiler/Controllers/EfcItemController.cs
+A QuickFiler/Controllers/QfcCollectionController.PopOut.cs
+M QuickFiler/Controllers/QfcCollectionController.cs
+M QuickFiler/Controllers/QfcItemController.ViewerSetup.cs
+M QuickFiler/Controllers/QfcItemController.cs
+M QuickFiler/Helper Classes/EfcViewerQueue.cs
+M QuickFiler/Viewers/WebView2BreadcrumbHost.cs
+A QuickFiler/Viewers/WebView2EnvironmentContract.cs
+```
+
+A-ROWS: 17 (the nine new production and eight new test files named in the Write set)
+D-ROWS: 0
+M-ROWS: 11
+OTHER-STATUS-ROWS: 0
+M-ROWS-OUTSIDE-WRITE-SET: 0
+A-ROWS-OUTSIDE-WRITE-SET: 0
+
+The eleven `M` rows are `BreadcrumbBridgeRouter.cs`, `BreadcrumbOutboundQueue.cs`, `EfcDataModel.cs`, `EfcFormController.cs`, `EfcHomeController.cs`, `EfcItemController.cs`, `QfcCollectionController.cs`, `QfcItemController.ViewerSetup.cs`, `QfcItemController.cs`, `EfcViewerQueue.cs`, `WebView2BreadcrumbHost.cs`; each is a write-set member. `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` (a write-set member) has no row, consistent with the deliberate zero-edit.
+
+## csproj diffs (`git diff $BaseSha HEAD -- QuickFiler/QuickFiler.csproj QuickFiler.Test/QuickFiler.Test.csproj`)
+
+CSPROJ-ADDED-LINES: 17
+CSPROJ-REMOVED-LINES: 0
+CSPROJ-ADDED-BARE-COMPILE-LINES: 17 (each matches `^\+\s* $`; no metadata, no `DependentUpon`)
+CSPROJ-ADDED-NON-BARE-LINES: 0
+
+Added lines by project (verbatim `+` lines, hunk context omitted):
+
+`QuickFiler.Test/QuickFiler.Test.csproj` (8):
+
+```
++
++
++
++
++
++
++
++
+```
+
+`QuickFiler/QuickFiler.csproj` (9):
+
+```
++
++
++
++
++
++
++
++
++
+```
+
+## Include set versus `A` set
+
+Each `Include` value was normalised with `.Replace('\', '/')` and prefixed with its project directory (`QuickFiler/` or `QuickFiler.Test/`, taken from the `+++ b/` header of the hunk it appears in).
+
+INCLUDE-SET-COUNT: 17
+A-SET-COUNT: 17
+ONLY-IN-INCLUDE-SET: 0
+ONLY-IN-A-SET: 0
+INCLUDE-SET-EQUALS-A-SET: True
+
+## `EfcFormControllerTests.cs` zero-edit
+
+EFCFORMCONTROLLERTESTS-DIFF: none (`git diff --numstat $BaseSha HEAD -- QuickFiler.Test/Controllers/EfcFormControllerTests.cs` printed nothing)
+
+Positive control: the same numstat form against the edited write-set member `QuickFiler/Controllers/EfcHomeController.cs` printed `20 3 QuickFiler/Controllers/EfcHomeController.cs` (`CONTROL-NUMSTAT-EDITED-FILE`), so an empty numstat is a true zero-edit rather than a mis-scoped pathspec.
+
+## Untracked-source companion
+
+UNTRACKED-SOURCE: none (`git status --porcelain --untracked-files=all -- '*.cs' '*.csproj'` printed nothing)
+
+This proves that every path the anchored name-status diff must enumerate is committed and therefore visible to it; an untracked new file would be invisible to `git diff $BaseSha HEAD` and would appear here instead.
+
+Positive control: the unscoped `git status --porcelain --untracked-files=all` at the same moment listed 6 entries (`CONTROL-PORCELAIN-ALL-COUNT: 6`): the plan file and `MEMORY.md` as modified, and `p6-t1-ac-u6-structural-pass.md`, `p6-t2-line-counts-advisory.md`, `p5-t9-commit.md` and one `.claude/agent-memory/atomic-executor/` note as untracked — all docs, evidence or agent-memory paths (convention 9 expected-dirty). The scoped form's emptiness is therefore a property of the source pathspecs, not of a status command that reports nothing.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t4-popout-ordering.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t4-popout-ordering.md
new file mode 100644
index 000000000..8e07e6d60
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t4-popout-ordering.md
@@ -0,0 +1,45 @@
+# [P6-T4] Carry-before-removal ordering gate over `QfcCollectionController.PopOut.cs`
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-56
+- Command: `Select-String -LiteralPath QuickFiler/Controllers/QfcCollectionController.PopOut.cs` for the two member declarations (`^\s*public (async Task|void) PopOutControlGroup(Async)?\(int selection\)`), the two carry reads (`-SimpleMatch '= ReadPopOutCarry(group);'`), the two removal calls (`RemoveSpecificControlGroup(Async)?\(selection\);`) and the class-closing brace (`^ \}$`), then a per-member span check; run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `9ac987a969d1f4786d296fee25817c8e5dde9233`)
+- EXIT_CODE: 0
+- Output Summary: `ORDERING: PASS` — member 1 (`PopOutControlGroup`, declared :77) reads the carry at :81 and removes at :84; member 2 (`PopOutControlGroupAsync`, declared :95) reads at :101 and removes at :104; each read precedes its removal and both calls of each member lie strictly between that member's declaration line and the next boundary.
+
+## The four line numbers
+
+| Member | Declaration | Span upper bound | `= ReadPopOutCarry(group);` | `RemoveSpecificControlGroup` call | Read before removal |
+|---|---|---|---|---|---|
+| 1 `public void PopOutControlGroup(int selection)` | 77 | 95 (next member's declaration) | 81 | 84 (`RemoveSpecificControlGroup(selection);`) | true |
+| 2 `public async Task PopOutControlGroupAsync(int selection)` | 95 | 110 (class-closing brace; there is no following member) | 101 | 104 (`await RemoveSpecificControlGroupAsync(selection);`) | true |
+
+Reads: 81, 101. Removals: 84, 104.
+
+ORDERING: PASS
+
+## Mechanical derivation (helper output, verbatim)
+
+```
+FILE: QuickFiler/Controllers/QfcCollectionController.PopOut.cs
+TOTAL-LINES: 111
+MEMBER-DECLARATIONS: 2
+ DECL: 77 | public void PopOutControlGroup(int selection)
+ DECL: 95 | public async Task PopOutControlGroupAsync(int selection)
+CARRY-READS: 2
+ READ: 81 | (IFolderSearchHandler handler, MailItemHelper helper) = ReadPopOutCarry(group);
+ READ: 101 | (IFolderSearchHandler handler, MailItemHelper helper) = ReadPopOutCarry(group);
+REMOVAL-CALLS: 2
+ REMOVE: 84 | RemoveSpecificControlGroup(selection);
+ REMOVE: 104 | await RemoveSpecificControlGroupAsync(selection);
+CLASS-CLOSING-BRACE-LINES: 1
+ CLASS-CLOSE: 110
+MEMBER 1: decl 77 | bound 95 | read 81 | removal 84 | READ-BEFORE-REMOVAL: true
+MEMBER 2: decl 95 | bound 110 | read 101 | removal 104 | READ-BEFORE-REMOVAL: true
+ORDERING: PASS
+```
+
+The span check requires exactly one read and exactly one removal inside each member's span; a member with zero or two of either, or with the removal before the read, prints `READ-BEFORE-REMOVAL: false` and `ORDERING: FAIL`. The upper bound for the last member is the class-closing brace at :110 because the task's "next member's declaration line" has no successor for it.
+
+## Positive control
+
+`CONTROL-READPOPOUTCARRY-ALL-MENTIONS: 3 (lines 63, 81, 101)` — the bare identifier `ReadPopOutCarry` occurs at the declaration (:63) and the two call sites (:81, :101), so the `-SimpleMatch '= ReadPopOutCarry(group);'` needle correctly selects only the two assignment-form reads and excludes the declaration. The doc-comment mentions of "the removal call" at :73-75 and :91-93 do not contain the `RemoveSpecificControlGroup` identifier, so the removal count of 2 is the two live calls and no comment. A separate Read of the file before the helper ran gave the same line numbers.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t5-literal-sweep.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t5-literal-sweep.md
new file mode 100644
index 000000000..15b266bc1
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t5-literal-sweep.md
@@ -0,0 +1,41 @@
+# [P6-T5] Stale-comment and banned-symbol sweep over the write-set production files
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-56
+- Command: (1) `Select-String -SimpleMatch 'until CoreWebView2InitializationCompleted fires'` across the six `QuickFiler/Controllers/EfcFormController*.cs` files; (2) `Select-String -Pattern 'Thread\.Sleep\(|Task\.Delay\('` across the twenty production write-set `.cs` files; (3) `Select-String -SimpleMatch '"WindowsFormsWebView2"'` and (4) `Select-String -SimpleMatch '"--incognito "'` across the 183 files enumerated by `git ls-files -- ':(glob)QuickFiler/**/*.cs'`; run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `9ac987a969d1f4786d296fee25817c8e5dde9233`)
+- EXIT_CODE: 0
+- Output Summary: `SWEEP-1-STALE-COMMENT-COUNT: 0`; `SWEEP-2-BANNED-WAIT-COUNT: 0`; `SWEEP-3-WindowsFormsWebView2-COUNT: 1` at `QuickFiler/Viewers/WebView2EnvironmentContract.cs:30`; `SWEEP-4-incognito-COUNT: 1` at `QuickFiler/Viewers/WebView2EnvironmentContract.cs:24`. All four counts as stated by the task.
+
+## Sweep 1 — stale comment
+
+Enumeration (`EFCFORMCONTROLLER-FILES: 6`): `EfcFormController.Actions.cs`, `EfcFormController.Breadcrumb.cs`, `EfcFormController.cs`, `EfcFormController.EventHandlers.cs`, `EfcFormController.Helpers.cs`, `EfcFormController.SetupAndProperties.cs` (all under `QuickFiler/Controllers/`).
+
+SWEEP-1-STALE-COMMENT-COUNT: 0
+
+Positive control: `-SimpleMatch 'InitializeBreadcrumbHostAsync'` over the same six-file enumeration returned 2 hits (`SWEEP-1-CONTROL-InitializeBreadcrumbHostAsync-COUNT: 2`), so the enumeration reaches the files that carry the breadcrumb initialization code and a zero for the stale phrase is a true absence. An independent Grep for the same phrase over every `.cs` file in the worktree also returned no match, and a Grep for the bare token `CoreWebView2InitializationCompleted` over `QuickFiler/**/*.cs` returned 19 hits in 6 files (none of them an `EfcFormController*` file), confirming the token family is searchable and the stale phrase no longer exists anywhere.
+
+## Sweep 2 — banned wall-clock waits
+
+Enumeration: the twenty production write-set `.cs` paths listed in the plan's Write set (`PRODUCTION-WRITE-SET-FILES: 20`, `PRODUCTION-WRITE-SET-MISSING: 0`).
+
+SWEEP-2-BANNED-WAIT-COUNT: 0
+
+Positive controls: (a) widening the same alternation to `Thread\.Sleep\(|Task\.Delay\(|Task\.CompletedTask` over the same twenty files returned 1 hit (`SWEEP-2-CONTROL-widened-alternation-COUNT: 1`), so the alternation form and file enumeration fire when a listed term is present; (b) a looser pattern `Task\.Run\(|Task\.FromResult\(|await ` over the same twenty files returned 187 hits; (c) an independent Grep for `Thread\.Sleep\(|Task\.Delay\(` over all of `QuickFiler/**/*.cs` returned 5 `Task.Delay(` hits, every one in a file outside the write set (`QfcFormController.EventHandlers.cs:348`, `QfcItemController.EventWiring.cs:137`, `QfcQueue.cs:77`, `:141`, `:238`), so the pattern itself matches live code and the zero over the write set is a property of those twenty files, not of the pattern.
+
+## Sweep 3 — `"WindowsFormsWebView2"` (quoted literal)
+
+Enumeration: `git ls-files -- ':(glob)QuickFiler/**/*.cs'` (`QUICKFILER-LS-FILES-CS-COUNT: 183`; a PowerShell `-Path` wildcard does not recurse, so the enumeration is fed to `-LiteralPath`).
+
+SWEEP-3-WindowsFormsWebView2-COUNT: 1
+
+HIT: `QuickFiler/Viewers/WebView2EnvironmentContract.cs:30` — `internal const string UserDataFolderName = "WindowsFormsWebView2";` (the contract)
+
+Control: the unquoted token `WindowsFormsWebView2` over the same enumeration also returns exactly 1 hit at the same line, so no unquoted or interpolated duplicate of the folder name survives in `QuickFiler/`. An independent Grep for the quoted literal over `QuickFiler/**/*.cs` returned the same single line.
+
+## Sweep 4 — `"--incognito "` (quoted literal, trailing space)
+
+SWEEP-4-incognito-COUNT: 1
+
+HIT: `QuickFiler/Viewers/WebView2EnvironmentContract.cs:24` — `internal const string AdditionalBrowserArguments = "--incognito ";` (the contract)
+
+Control: the unquoted token `--incognito` over the same enumeration also returns exactly 1 hit at the same line, so no other spelling of the argument (with or without the trailing space) survives in `QuickFiler/`; the former target-typed `new("--incognito ")` at `QfcItemController.ViewerSetup.cs` and the `IncognitoArgument` literal in `EfcItemController.cs` reported by [P0-T14] are gone (the alias now reads `WebView2EnvironmentContract.AdditionalBrowserArguments`). An independent Grep for the quoted literal over `QuickFiler/**/*.cs` returned the same single line.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t6-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t6-commit.md
new file mode 100644
index 000000000..0a167da53
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t6-commit.md
@@ -0,0 +1,39 @@
+# [P6-T6] Phase 6 commit: structural gates and parity evidence
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-57
+- Command: `git add -- docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "chore(792): structural gates and parity evidence"` (run with `git -C - ` on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim), then `git show --name-only --format= HEAD` and `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 c9b457bd] chore(792): structural gates and parity evidence`; `7 files changed, 367 insertions(+), 6 deletions(-)`; five Phase 6 evidence files and the Phase 5 residual `p5-t9-commit.md` created, the plan file modified with the [P6-T1] through [P6-T5] check-offs; every committed path is under the feature folder; scoped porcelain printed nothing.
+
+COMMIT-SHA-OBSERVED: c9b457bda44ef856306a1bc96c94683dc528993c
+
+PARENT-SHA: 9ac987a969d1f4786d296fee25817c8e5dde9233 (the [P5-T9] commit)
+
+## Paths in the commit (`git show --name-only --format= HEAD`, 7 paths, verbatim)
+
+```
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t1-ac-u6-structural-pass.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t2-line-counts-advisory.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t3-compile-item-parity.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t4-popout-ordering.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t5-literal-sweep.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t9-commit.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+```
+
+Every path starts with `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/`; no source, project, solution or configuration path is in the commit. The `p5-t9-commit.md` artifact is the Phase 5 residual left uncommitted by construction after [P5-T9], swept here as that commit swept the Phase 4 residual.
+
+## Acceptance observations
+
+- Commit exit code 0.
+- `git show --name-only --format= HEAD` lists feature-folder paths only (7 of 7).
+- `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` (convention 9) printed nothing.
+
+## Residual (recorded, not an acceptance clause)
+
+`git status --porcelain --untracked-files=all` immediately after the commit listed only `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from an earlier executor and outside the plan's add pathspecs; they were deliberately left uncommitted.
+
+This artifact and the [P6-T6] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 6 (convention 9 treats docs and evidence as expected-dirty). No source path is dirty. The next feature-folder commit ([P7-T17] or later) will sweep them.
+
+Git printed seven `LF will be replaced by CRLF` warnings for Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t18-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t18-commit.md
new file mode 100644
index 000000000..beeef600e
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t18-commit.md
@@ -0,0 +1,52 @@
+# [P7-T18] Phase 7 commit: final toolchain pass, coverage delta, acceptance check-off
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-20
+- Command: `git add -- QuickFiler QuickFiler.Test docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "chore(792): final toolchain pass, coverage delta, acceptance check-off"` (run with `git -C
- ` on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim), then `git show --name-only --format=%H%n%P HEAD`, `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` and `git diff --name-only $BaseSha HEAD -- '*.cs' '*.csproj'` with `$BaseSha` = `e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3` (CMD-BASE)
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 986ce5aa] chore(792): final toolchain pass, coverage delta, acceptance check-off`; `20 files changed, 847 insertions(+), 26 deletions(-)`; 18 evidence files created (the seventeen Phase 7 artifacts and the Phase 6 residual `p6-t6-commit.md`), `plan.2026-09-17T07-30.md` modified with the [P6-T6] and [P7-T1] through [P7-T17] check-offs, `spec.md` modified with the eight acceptance check-offs; `QuickFiler` and `QuickFiler.Test` contributed no change (the final-pass format step rewrote nothing); scoped porcelain printed nothing; the BASE-SHA-to-HEAD `.cs`/`.csproj` footprint lists exactly the 30 paths recorded in [P4-T12].
+
+COMMIT-SHA-OBSERVED: 986ce5aafb5cae63fb9a01ce1d904491ea2b3b95
+
+PARENT-SHA: c9b457bda44ef856306a1bc96c94683dc528993c (the [P6-T6] commit)
+
+## Paths in the commit (`git show --name-only --format= HEAD`, 20 paths, verbatim)
+
+```
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t10-ac-u1.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t11-ac-u2.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t12-ac-u3.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t13-ac-u4.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t14-ac-u6.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t15-ac-u7.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t16-ac-u8.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/issue-updates/p7-t17-ac-u9.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p7-t1-outlook-closed.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t6-commit.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t2-format.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t3-file-size-audit.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t4-analyzers.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t5-nullable.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t6-coverage-final.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t7-taskmaster-sweep.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t8-coverage-delta.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t9-toolchain-pass.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md
+```
+
+Every path starts with `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/`; no source, project, solution or configuration path is in the commit, because the final-pass format step ([P7-T2]) rewrote no file and no other task of this phase edits source.
+
+## Acceptance observations
+
+- Commit exit code 0.
+- `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` (convention 9) printed nothing.
+- `git diff --name-only e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3 HEAD -- '*.cs' '*.csproj'` (BASE-SHA to HEAD) printed 30 paths, identical in content and order to the list recorded verbatim in [P4-T12] (`PATH-COUNT: 30`): the eight new test files, `QuickFiler.Test.csproj`, the twenty production `.cs` files (nine new, eleven modified) and `QuickFiler.csproj`; `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` is still absent from the list (zero-edit by design).
+
+## Residual (recorded, not an acceptance clause)
+
+`git status --porcelain --untracked-files=all` immediately after the commit listed only `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from an earlier executor and outside the plan's add pathspecs; they were deliberately left uncommitted.
+
+This artifact and the [P7-T18] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 7 (convention 9 treats docs and evidence as expected-dirty). No source path is dirty. The Phase 8 terminal commit will sweep them, as this commit swept the Phase 6 residual `p6-t6-commit.md`.
+
+Git printed nineteen `LF will be replaced by CRLF` warnings for Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t2-format.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t2-format.md
new file mode 100644
index 000000000..e57a22b97
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t2-format.md
@@ -0,0 +1,87 @@
+# [P7-T2] Format step (final toolchain loop)
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-03
+- PASS-NUMBER: 1
+- Command: `Get-FileHash -LiteralPath
-Algorithm SHA256` over the 29 write-set `.cs` paths and `git status --porcelain --untracked-files=all` (before); `dotnet tool run csharpier format .`; the same hashes and porcelain (after); `dotnet tool run csharpier check .` (run from `coverage/plan792-helper.ps1 -Step format -PassNumber 1` with the item worktree as the working directory; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`; console output of the two csharpier commands captured to the gitignored `coverage/p7-t2-pass1-format.log` and `coverage/p7-t2-pass1-check.log`)
+- EXIT_CODE: 0
+- Output Summary: format printed `Formatted 1658 files in 4695ms.` (exit 0; this line is recorded and explicitly NOT used as the rewritten count); `REWRITTEN-WRITE-SET-FILES: 0` (no write-set SHA-256 changed); `PORCELAIN-NEW-ENTRIES: 0`; `OUT-OF-SCOPE-REWRITE-COUNT: 0`; check printed `Checked 1658 files in 4924ms.` and exited 0 (the exit-0 branch held); `RESTART-REQUIRED: false`.
+
+## Before
+
+`WRITE-SET-COUNT: 29`, `WRITE-SET-MISSING: 0` (20 production, 9 test; `Test-Path -LiteralPath` over each).
+
+Porcelain before (5 lines, all docs, evidence or agent-memory; convention 9 expected-dirty):
+
+```
+ M .claude/agent-memory/atomic-executor/MEMORY.md
+ M docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+?? .claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/other/p7-t1-outlook-closed.md
+?? docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p6-t6-commit.md
+```
+
+SHA-256 before (repository-relative paths):
+
+```
+14EFB6386CF4F25B5AAC28C1081212CEE25C6E0987DBE69DE695F4ECA0ED55FB QuickFiler/Viewers/WebView2EnvironmentContract.cs
+BD6E5F07AC709BF8C274045C5AC0508E6447A0E686657F742DD0195134BDF0C0 QuickFiler/Viewers/WebView2BreadcrumbHost.cs
+AAD50304873955794E69DFE7957B8550D1F1AAF733ACFC37E7A3ABFC4A6F2D1D QuickFiler/Controllers/QfcItemController.ViewerSetup.cs
+A2E2FA2B6E154AAC9709D1C7268E1E389C39CAA3BB1C12D3178342C11A059C09 QuickFiler/Controllers/EfcItemController.cs
+9E887E98A48FC1DD5AF2043DD6D979864A3807E0020314C6420BC18419BC62E4 QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs
+B5EF211E5A37889A2DBF8B50CB6099A21E6DF2C1CEDEE52BDC2A822DEB786F2B QuickFiler/Controllers/BreadcrumbBridgeRouter.cs
+8E9B17C3FDAA4D987C00C6368159D576746172CA82C7F7258F0989B076764347 QuickFiler/Controllers/BreadcrumbOutboundQueue.cs
+0B122F9A1ABB9C20C252612A4F616456ADCBEBF27E3603CBFCC2F7EA68316320 QuickFiler/Controllers/EfcFormController.cs
+9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C QuickFiler/Controllers/EfcFormController.Breadcrumb.cs
+24496A45628E979FEED192B2955B0F5B36BF21888AE5CBBD112F2EE49A063733 QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs
+5C425D8E9D251B019ABC90DD3FC2FD2B26E62D357E97B3EE0BF46BE572C1F571 QuickFiler/Controllers/EfcFormController.EventHandlers.cs
+2519157517921E8BF9E0496E13C306F78BA88F280BA21477DD57F36DB7E0DF9B QuickFiler/Controllers/EfcFormController.Actions.cs
+B3CB820EFB1C5F6A000A3E98A3E3BE7D3A2669C576E2CCDA409876B94B6E049A QuickFiler/Controllers/EfcFormController.Helpers.cs
+0D5A70322A19516B3A9B1486D613EF571A2C608059C9F5E55E93D6605A9E81A5 QuickFiler/Controllers/QfcCollectionController.cs
+C6696DF941B9CF6886F0EE299555E95307ADE2C95203323D9F9D0A9F006D2DE8 QuickFiler/Controllers/QfcCollectionController.PopOut.cs
+20FC90DB68FB1CA5199311B2494AD1FB33EF43FEDDB2764BB72359BEF14D64DE QuickFiler/Controllers/EfcHomeController.cs
+E40AB978F8E0C7242873F2120F0B27EE1D2F998472C48CE814D6BD6CA571437A QuickFiler/Controllers/EfcDataModel.cs
+C0E4085C52DEE82C074BE3EEC0375D7ADB6761E43AF75B90302A823C670B44DB QuickFiler/Controllers/EfcDataModel.Carry.cs
+93E666BAE5DFE88AC3A56E5C58DA75B1C2F1A9E7D744BB2B405BBF34A4BE8C8B QuickFiler/Controllers/QfcItemController.cs
+39891B2FF0B654CE0BA4CCCE759F5D2FF8155E60055E88A25BCD91DB843020D3 QuickFiler/Helper Classes/EfcViewerQueue.cs
+961366098F99D4C8FD0D70D2A6BBEADD9CCDBAFF4380AAF606F7451433045543 QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs
+31142591645F40ACB833E466035A88D75E2AE46EB9BE117D6822BF21D0C3B7B1 QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs
+890D1E767BECA732C635A4F81EE8B4D5A78B1CCFE4046FB9D3621255A7F24F4B QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs
+9830504A5992DAC793EE2A360B04BB452123E1A811B51B823BF4DFB8E69514B5 QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs
+2CBC9ADAA003D60A6970DC3566766A6C14D33F4F1FE5ED0A95AEC021A59E1428 QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs
+8BE4C3DFE5BC88CDDAC3CA82C100664329CCFBF8D85C8B75719D396A35A6C43F QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs
+0C83657C2C70BE669404434EE0DCE153EDC5F72FE94BF5328E07983EC7C42CC5 QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs
+8F319773F59B7CE351C72973E5C396DEDC9078FC9A991728BC5EED128A2C7422 QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs
+7CB47A85CF35E8E7DB2CC204C119B409B694EDF1EE53185040535982E98F45DF QuickFiler.Test/Controllers/EfcFormControllerTests.cs
+```
+
+## Format run
+
+- FORMAT-EXIT: 0
+- Verbatim output (1 line): `Formatted 1658 files in 4695ms.` — recorded per convention 4 and explicitly NOT used as the rewritten count. The count is 1658 = the 1641 files of the [P0-T9] baseline check plus the 17 `.cs` files this change created, so the formatter's sweep reached the new files.
+
+## After
+
+SHA-256 after: identical to the before list for all 29 paths (each `HA:` line of the helper output equals its `HB:` line; the helper compares per path).
+
+- REWRITTEN-WRITE-SET-FILES: 0
+- Porcelain after: the same 5 lines as before; `PORCELAIN-NEW-ENTRIES: 0`.
+- OUT-OF-SCOPE-REWRITE-RESTORED: (none; no path outside the write set changed, so no `git checkout --` was run and the empty `BASELINE-DRIFT-SET` of [P0-T9] was not consulted)
+- Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`): 0 lines.
+- BOM state of the four BOM-bearing files (`EF BB BF` leading bytes), before and after: `BreadcrumbBridgeRouter.cs` true/true, `QfcItemController.ViewerSetup.cs` true/true, `EfcFormController.cs` true/true, `EfcHomeController.cs` true/true — the formatter altered none.
+
+## Check run
+
+- CHECK-EXIT: 0
+- Verbatim output (1 line): `Checked 1658 files in 4924ms.`
+- Branch held: exit 0 printing `Checked N files in` (the alternative non-zero branch with a reported set was not taken).
+
+## Decision
+
+RESTART-REQUIRED: false
+
+[P7-T3] through [P7-T8] therefore run in this pass (PASS-NUMBER 1).
+
+## Positive control on the hash comparison
+
+The 29 before-hashes are pairwise distinct and the comparison is evaluated per path (`$before[$p] -ne $after[$p]`), so a rewritten file would produce a differing hash and be counted; an unchanged count of 0 is a real observation rather than a constant. The porcelain-difference test was likewise exercised earlier in this plan: the [P4-T11] and [P2-T13] format runs on this same helper pattern reported rewritten files when the tree carried unformatted new files.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t3-file-size-audit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t3-file-size-audit.md
new file mode 100644
index 000000000..60a94b7d7
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t3-file-size-audit.md
@@ -0,0 +1,65 @@
+# [P7-T3] Authoritative post-format file-size audit and AC-U9 figures
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-06
+- PASS-NUMBER: 1
+- Command: `(Get-Content -LiteralPath ).Count` per write-set `.cs` path (convention 3: total lines, never `Measure-Object -Line`, never non-blank counts), measured AFTER the [P7-T2] format step of this pass; run from `coverage/plan792-helper.ps1 -Step sizes -PassNumber 1` with the item worktree as the working directory (the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`)
+- EXIT_CODE: 0
+- Output Summary: 29 write-set `.cs` paths measured (20 production, 9 test), `MISSING-COUNT: 0`; `OVER-CEILING-AFTER: 2` (`EfcItemController.cs` 1076, `QfcCollectionController.cs` 2306, both pre-existing and exempted by the task text); `UNEXPECTED-OVER-CEILING: 0`; every figure equals the [P6-T2] advisory figure, consistent with the formatter rewriting no write-set file in [P7-T2].
+
+## Production write-set `.cs` files (total line count, post-format)
+
+| Path | Lines | OVER-CEILING |
+|---|---|---|
+| `QuickFiler/Viewers/WebView2EnvironmentContract.cs` | 53 | false |
+| `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` | 382 | false |
+| `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` | 474 | false |
+| `QuickFiler/Controllers/EfcItemController.cs` | 1076 | true (pre-existing; excepted by the [P7-T3] acceptance) |
+| `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` | 56 | false |
+| `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` | 453 | false |
+| `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` | 80 | false |
+| `QuickFiler/Controllers/EfcFormController.cs` | 266 | false |
+| `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` | 178 | false |
+| `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs` | 243 | false |
+| `QuickFiler/Controllers/EfcFormController.EventHandlers.cs` | 383 | false |
+| `QuickFiler/Controllers/EfcFormController.Actions.cs` | 184 | false |
+| `QuickFiler/Controllers/EfcFormController.Helpers.cs` | 270 | false |
+| `QuickFiler/Controllers/QfcCollectionController.cs` | 2306 | true (pre-existing; excepted by the [P7-T3] acceptance) |
+| `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` | 111 | false |
+| `QuickFiler/Controllers/EfcHomeController.cs` | 464 | false |
+| `QuickFiler/Controllers/EfcDataModel.cs` | 464 | false |
+| `QuickFiler/Controllers/EfcDataModel.Carry.cs` | 100 | false |
+| `QuickFiler/Controllers/QfcItemController.cs` | 340 | false |
+| `QuickFiler/Helper Classes/EfcViewerQueue.cs` | 108 | false |
+
+## Test write-set `.cs` files (total line count, post-format)
+
+| Path | Lines | OVER-CEILING |
+|---|---|---|
+| `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs` | 153 | false |
+| `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` | 192 | false |
+| `QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs` | 196 | false |
+| `QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs` | 113 | false |
+| `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs` | 348 | false |
+| `QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs` | 213 | false |
+| `QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs` | 175 | false |
+| `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs` | 40 | false |
+| `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` | 485 | false (unchanged from the [P0-T8] baseline of 485; zero-edit by design) |
+
+PRODUCTION-ROWS: 20
+TEST-ROWS: 9
+MISSING-COUNT: 0
+
+OVER-CEILING-AFTER: 2
+
+UNEXPECTED-OVER-CEILING: 0 (every write-set `.cs` file except `QuickFiler/Controllers/EfcItemController.cs` and `QuickFiler/Controllers/QfcCollectionController.cs` is at most 500 lines measured after [P7-T2])
+
+## AC-U9 statement (post-format figures)
+
+PRE-EXISTING-DEBT: EfcItemController.cs before 1122 after 1076; QfcCollectionController.cs before 2333 after 2306
+
+The remaining over-ceiling size of these two files is pre-existing debt that this change neither introduces nor resolves. Both were over the 500-line ceiling at the [P0-T8] baseline (`OVER-CEILING-BEFORE: 3`, listed there as 2333, 1321 and 1122), and both shrank because members moved out to new partials (`EfcItemController.WebViewEnvironment.cs`, `QfcCollectionController.PopOut.cs`); neither is brought under the ceiling, and no new file exceeds it. `EfcFormController.cs` (1321 at baseline) is 266 after the six-way split (D9), which is why `OVER-CEILING-BEFORE: 3` becomes `OVER-CEILING-AFTER: 2`.
+
+## Positive control
+
+`CONTROL-KNOWN-OVER: true` — the same `(Get-Content -LiteralPath ...).Count -gt 500` expression applied to `QuickFiler/Controllers/QfcCollectionController.cs` returned true, so the `over=false` rows come from a comparison that fires when a file is over the ceiling. `MISSING-COUNT: 0` was computed by `Test-Path -LiteralPath` over all 29 paths, so no row is a count over an absent file.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t4-analyzers.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t4-analyzers.md
new file mode 100644
index 000000000..2950b4910
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t4-analyzers.md
@@ -0,0 +1,28 @@
+# [P7-T4] Analyzer step (final toolchain loop)
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-07
+- PASS-NUMBER: 1
+- Command: CMD-OUTLOOK, then `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true` (CMD-BUILD-ANALYZE; run from `coverage/plan792-helper.ps1 -Step analyze -PassNumber 1` with the item worktree as the working directory; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`; console output captured to the gitignored `coverage/p7-t4-pass1-analyze.log`)
+- EXIT_CODE: 0
+- Output Summary:
+ - `OUTLOOK-CLOSED: true` (printed first; no `HALT:` line; no process was ended)
+ - `Build succeeded.` (1 line; `Build FAILED.` 0 lines)
+ - ` 0 Warning(s)` (verbatim msbuild summary line; the [P0-T10] baseline count is 0, so the count is not greater than the baseline)
+ - ` 0 Error(s)` (verbatim msbuild summary line; exact-line match `^\s+0 Error\(s\)$` = true)
+ - `Time Elapsed 00:00:17.81`; 11877 log lines; 0 lines matching `: error `; 0 lines matching `: warning `.
+
+## Non-vacuity check of the Rebuild
+
+From `coverage/p7-t4-pass1-analyze.log`:
+
+- CSC-INVOCATIONS: 36 (lines naming `csc.exe`/`csc.dll`; equal to the [P0-T10] baseline count), of which 1 names `QuickFiler.csproj` or `/out:...QuickFiler.dll`
+- CORECOMPILE lines: 83 counted unanchored (`CoreCompile:`) and 83 with the `^\s*(\d+>)?CoreCompile:` node-prefix-tolerant anchor (an anchored `^CoreCompile:` count is not used because `/m` prefixes secondary-node lines with `N>`)
+- CORECOMPILE-SKIPPED: 0 (no `Skipping target "CoreCompile"` line)
+- PROJECTS-DONE-REBUILD: 18 lines matching `Done Building Project .*\.csproj" \(Rebuild target\(s\)\)`. Reconciliation with the [P0-T10] figure of 19: the log carries 20 `Done Building Project ... (Rebuild target(s))` lines in total = 18 `.csproj` + 1 `Tags.Test.csproj.metaproj` (the solution-generated metaproject, which the baseline's looser `.csproj` pattern also matched, giving 19) + 1 `TaskMaster.sln`; 0 lines carry `(default targets)`, so every project was driven by the Rebuild target.
+- ANALYZER-ARG-LINES: 34 (`/analyzer:` lines; equal to baseline); `CS0006` lines: 0
+- Assemblies rewritten during the run (local time), before and after: `UtilitiesCS/bin/Debug/UtilitiesCS.dll` 20:09:52 to 21:07:06; `QuickFiler/bin/Debug/QuickFiler.dll` 20:46:49 to 21:07:10; `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` 20:46:51 to 21:07:13; `TaskMaster.Test/bin/Debug/TaskMaster.Test.dll` 20:46:54 to 21:07:16.
+
+Three independent signals (csc invocation count, zero skipped CoreCompile targets, and every tracked assembly's LastWriteTime advancing to the run window) agree that the Rebuild compiled every project rather than returning a warm no-op.
+
+msbuild was resolved from `PATH` (`MSBUILD-ON-PATH: True`).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t5-nullable.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t5-nullable.md
new file mode 100644
index 000000000..3f890fda8
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t5-nullable.md
@@ -0,0 +1,28 @@
+# [P7-T5] Nullable step (final toolchain loop)
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-07
+- PASS-NUMBER: 1
+- Command: CMD-OUTLOOK, then `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true` (CMD-BUILD-NULLABLE; no `/p:Nullable=enable`; run from `coverage/plan792-helper.ps1 -Step nullable -PassNumber 1` with the item worktree as the working directory; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`; console output captured to the gitignored `coverage/p7-t5-pass1-nullable.log`)
+- EXIT_CODE: 0
+- Output Summary:
+ - `OUTLOOK-CLOSED: true` (printed first; no `HALT:` line; no process was ended)
+ - `Build succeeded.` (1 line; `Build FAILED.` 0 lines)
+ - ` 0 Warning(s)` (verbatim msbuild summary line)
+ - ` 0 Error(s)` (verbatim msbuild summary line; exact-line match `^\s+0 Error\(s\)$` = true)
+ - `Time Elapsed 00:00:15.80`; 11904 log lines; 0 lines matching `: error `; 0 lines matching `: warning `.
+
+## Non-vacuity check of the Rebuild
+
+From `coverage/p7-t5-pass1-nullable.log`:
+
+- CSC-INVOCATIONS: 36 (equal to the [P0-T11] baseline count), of which 1 names `QuickFiler.csproj` or `/out:...QuickFiler.dll`
+- CORECOMPILE lines: 72 counted unanchored and 72 with the `^\s*(\d+>)?CoreCompile:` node-prefix-tolerant anchor
+- CORECOMPILE-SKIPPED: 0
+- PROJECTS-DONE-REBUILD: 18 `.csproj` lines (plus the `Tags.Test.csproj.metaproj` and `TaskMaster.sln` lines, 20 in total; the same reconciliation as [P7-T4] applies to the baseline's 19)
+- ANALYZER-ARG-LINES: 34; `CS0006` lines: 0
+- Assemblies rewritten during the run (local time), before and after: `UtilitiesCS/bin/Debug/UtilitiesCS.dll` 21:07:06 to 21:08:02; `QuickFiler/bin/Debug/QuickFiler.dll` 21:07:10 to 21:08:05; `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` 21:07:13 to 21:08:08; `TaskMaster.Test/bin/Debug/TaskMaster.Test.dll` 21:07:16 to 21:08:11.
+
+The before timestamps are the [P7-T4] outputs of this pass and every after timestamp is later, so this Rebuild produced the assemblies that [P7-T6] and [P7-T7] run.
+
+msbuild was resolved from `PATH` (`MSBUILD-ON-PATH: True`).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t6-coverage-final.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t6-coverage-final.md
new file mode 100644
index 000000000..1c6078cff
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t6-coverage-final.md
@@ -0,0 +1,174 @@
+# [P7-T6] Test-with-coverage step (final toolchain loop, QuickFiler.Test scope)
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-08
+- PASS-NUMBER: 1
+- Command: `pwsh -NoProfile -WorkingDirectory -File scripts/vscode/Invoke-MSTestWithCoverage.ps1 -SearchRoot QuickFiler.Test -Configuration Debug -CoverageOutput coverage/p7-final.cobertura.xml` (CMD-COVERAGE, stage `p7-final`; `` is the item worktree root; launched from `coverage/plan792-helper.ps1 -Step coverage -PassNumber 1`, whose opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`; console captured to the gitignored `coverage/p7-t6-pass1-coverage-run.log`; the assemblies under test are the [P7-T5] outputs of this pass, written 21:08 local time; no build ran in this task)
+- EXIT_CODE: 1
+- ExpectedExitCode: 1
+- Output Summary: runner exit 1; this run's console carried `is below the required 80% threshold` (1 line) and its `Failed:` category is omitted (0 `Failed ` lines; `Test Run Successful.` 1 line; `Test Run Failed.` 0 lines), so the non-zero exit is the runner's threshold assertion and not a test failure; `Total tests: 1468`; `Passed: 1468`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; `Total time: 13.2033 Seconds`; root line-rate 0.244154.
+
+## Exit-code branch (keyed off this run)
+
+- THRESHOLD-MESSAGE-LINES: 1 (`is below the required 80% threshold`)
+- FAILED-CATEGORY: omitted
+- `Done. Coverage artifact:` lines: 0 (the runner throws at its line 386 after writing the processed document at line 384, so the success banner is not printed on the threshold branch; this is the branch the plan anticipates)
+- Branch taken: `ExpectedExitCode: 1` declared. No other cause of non-zero exit was observed.
+
+## Processed document
+
+- PROCESSED-DOCUMENT-EXISTS: true (`coverage/p7-final.cobertura.xml`, gitignored, not copied under the feature folder; absent before the run, `DOC-PRESENT-BEFORE-RUN: False`)
+- CONTAINS-SOURCES-ELEMENT: true
+
+## Root (document-level) figures
+
+- ROOT line-rate: 0.244154
+- ROOT branch-rate: 0.231969
+- ROOT lines-covered: 15182
+- ROOT lines-valid: 62182
+- ROOT branches-covered: 3763
+- ROOT branches-valid: 16222
+- QUICKFILER-SCOPED-DOCUMENT-LINE-RATE: 0.244154
+- REPO-WIDE-FLOOR: NOT MEASURED (single test assembly; see D10)
+
+## Package `QuickFiler` figures
+
+- PACKAGE-ELEMENTS-TOTAL: 6
+- PACKAGE-NAMES: QuickFiler, UtilitiesCS, TaskVisualization, SVGControl, ToDoModel, Tags
+- PACKAGE QuickFiler line-rate (attribute): 0.820056
+- PACKAGE QuickFiler branch-rate (attribute): 0.782406
+- PACKAGE QuickFiler line-rate (Get-CoberturaPackageLineSummary): 0.820056
+- PACKAGE QuickFiler branch-rate (Get-CoberturaPackageLineSummary): 0.782406
+- PACKAGE QuickFiler lines-covered: 10459
+- PACKAGE QuickFiler lines-valid: 12754
+- PACKAGE QuickFiler branches-covered: 2517
+- PACKAGE QuickFiler branches-valid: 3217
+- Note: the four counts are rolled up from the class elements with the repository helper `Get-CoberturaPackageLineSummary` (`scripts/vscode/Invoke-MSTestWithCoverage.PackageRate.ps1`, dot-sourced through `Invoke-MSTestWithCoverage.Helpers.ps1` in a child scope), the same reducer the [P0-T12] baseline used; the attribute and the rollup agree.
+
+## Console transcription
+
+- Total tests: 1468
+- Passed: 1468
+- Failed: 0 (omitted category)
+- Skipped: 0 (omitted category)
+
+(The baseline [P0-T12] ran 1436 tests; the 32 additional tests are the Issue-792 test classes added by Phases 1, 3 and 4.)
+
+## Per-file rows (max-hits merge over `./lines/line` and `./methods/method/lines/line` of every matching `class`; same derivation as [P0-T12]; `filename` values are repository-relative with backslashes and are matched after `.Replace('\', '/')`)
+
+- CLASS-ELEMENTS-TOTAL: 544
+
+### Viewers/WebView2BreadcrumbHost.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 100/110
+- LINE-MAP: 36:1 37:1 38:1 45:1 46:1 50:1 70:1 87:1 88:1 89:1 90:1 91:1 92:1 93:1 94:1 95:1 100:1 101:1 102:1 103:1 104:1 105:1 106:1 108:1 109:1 111:1 112:1 113:1 114:1 120:1 126:1 136:1 160:1 163:1 164:1 165:1 166:1 167:1 168:1 169:1 170:1 173:0 174:1 176:1 177:1 178:1 179:1 180:1 183:1 184:1 211:1 214:1 215:1 216:1 217:1 218:1 219:1 220:1 221:1 224:0 225:1 227:1 228:1 229:1 230:1 231:1 234:1 235:1 257:1 258:1 259:0 260:0 263:1 264:1 271:1 272:1 273:1 274:1 277:1 279:1 280:1 281:1 282:1 283:1 284:1 292:0 293:0 294:0 302:1 303:1 305:1 306:1 307:1 308:1 309:1 310:1 311:1 312:1 313:1 314:1 315:1 323:1 324:1 328:1 329:1 330:0 331:0 332:0 334:1 335:1
+
+### Controllers/BreadcrumbBridgeRouter.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 237/239
+- LINE-MAP: 21:1 22:1 23:1 36:1 38:1 41:1 47:1 48:1 49:1 50:1 51:1 52:1 53:1 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 87:1 88:1 89:1 105:1 106:1 107:1 108:1 111:1 112:1 113:1 114:1 115:1 116:1 117:1 118:1 119:1 120:1 121:1 122:1 123:1 124:1 125:1 126:1 129:1 130:1 131:1 132:1 133:1 134:1 135:1 136:1 137:1 143:1 144:1 145:1 146:1 147:1 148:1 149:1 150:1 151:1 152:1 154:1 155:1 156:1 157:1 158:1 159:1 164:1 165:1 170:1 171:1 172:1 173:1 174:1 176:1 177:1 187:1 192:1 193:1 194:1 197:1 198:1 199:1 200:1 201:1 202:0 203:0 208:1 209:1 210:1 211:1 212:1 213:1 214:1 215:1 216:1 218:1 219:1 230:1 231:1 232:1 233:1 236:1 237:1 238:1 239:1 240:1 241:1 246:1 247:1 249:1 250:1 251:1 252:1 253:1 256:1 260:1 261:1 262:1 263:1 264:1 267:1 268:1 269:1 270:1 276:1 277:1 278:1 279:1 280:1 281:1 282:1 283:1 284:1 285:1 286:1 287:1 290:1 291:1 292:1 293:1 294:1 295:1 296:1 300:1 301:1 302:1 303:1 304:1 305:1 306:1 311:1 312:1 313:1 314:1 321:1 322:1 323:1 324:1 325:1 326:1 328:1 329:1 347:1 348:1 349:1 350:1 353:1 354:1 355:1 356:1 357:1 358:1 359:1 360:1 361:1 362:1 363:1 364:1 365:1 366:1 368:1 369:1 370:1 371:1 372:1 373:1 374:1 375:1 383:1 384:1 385:1 386:1 387:1 388:1 389:1 392:1 395:1 400:1 401:1 402:1 403:1 404:1 405:1 406:1 407:1 408:1 409:1 410:1 411:1 412:1 415:1 416:1 417:1 418:1 420:1 423:1 424:1 426:1 427:1 429:1 430:1 432:1 433:1 435:1 436:1 438:1 441:1 443:1 444:1 445:1 446:1 447:1 450:1 451:1
+
+### Controllers/BreadcrumbBridgeRouter.Selection.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 140/143
+- LINE-MAP: 18:1 19:1 20:1 21:1 22:1 23:1 24:1 27:1 28:1 29:0 30:0 33:1 34:1 37:1 38:1 39:1 40:1 41:1 42:1 43:1 44:1 47:1 48:1 54:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 66:1 68:1 69:1 70:1 71:1 72:1 73:1 75:1 76:1 78:1 79:1 81:1 84:1 85:1 86:1 87:1 90:1 91:1 92:1 93:1 95:1 96:1 97:1 98:1 99:1 100:1 101:1 102:1 103:1 104:1 105:1 106:1 109:1 110:1 111:1 112:1 115:1 116:1 118:1 119:1 122:1 123:1 124:1 125:1 126:1 131:1 132:1 133:1 134:1 135:1 136:1 137:1 140:1 141:1 144:1 145:1 146:1 147:1 148:1 149:1 150:1 151:1 154:1 155:1 156:1 157:1 158:1 159:1 160:1 161:1 164:1 165:1 166:1 169:1 170:1 171:1 172:1 173:1 174:1 175:1 177:1 178:1 179:1 180:1 183:1 184:1 185:1 186:1 187:1 188:1 190:1 192:1 193:1 196:1 197:1 198:1 199:1 200:1 201:1 203:1 205:0 206:1 209:1 210:1 211:1 212:1 213:1 214:1 216:1 218:1 219:1
+
+### Controllers/BreadcrumbOutboundQueue.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 29/29
+- LINE-MAP: 18:1 23:1 24:1 25:1 26:1 29:1 38:1 39:1 40:1 41:1 44:1 45:1 46:1 47:1 49:1 50:1 51:1 52:1 60:1 61:1 62:1 63:1 64:1 65:1 74:1 75:1 76:1 77:1 78:1
+
+### Controllers/EfcFormController.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 74/108
+- LINE-MAP: 30:1 31:1 32:1 33:1 34:1 35:1 36:1 37:1 38:1 39:1 40:1 41:1 42:1 43:1 44:1 45:1 46:1 47:1 48:1 49:1 51:1 52:1 53:1 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 64:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 72:1 73:1 74:1 75:1 77:1 80:0 81:0 82:0 83:0 84:0 85:0 86:0 87:0 88:0 89:0 90:0 91:0 92:0 93:0 94:0 95:0 96:0 97:0 100:0 101:0 102:0 103:0 104:0 105:0 106:0 107:0 108:0 109:0 112:0 113:0 114:0 115:0 116:0 117:0 123:1 124:1 125:1 129:1 138:1 139:1 140:1 141:1 151:1 152:1 153:1 154:1 155:1 156:1 160:1 161:1 162:1 163:1 164:1 165:1 166:1 167:1 168:1 173:1 174:1 183:1 184:1 238:1
+
+### Controllers/EfcHomeController.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 230/241
+- LINE-MAP: 20:1 21:1 22:1 24:1 25:1 30:1 31:1 32:1 33:1 36:1 37:1 38:1 41:1 42:1 43:1 54:0 55:0 56:0 57:0 58:0 59:0 60:0 61:0 63:1 64:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 72:1 73:1 74:1 75:1 76:1 77:1 78:1 79:1 80:1 81:1 82:1 87:1 88:1 90:1 91:1 92:1 93:1 94:1 95:1 96:1 97:1 98:1 99:1 100:1 101:1 102:1 103:1 104:1 105:1 106:1 107:1 108:1 109:1 110:1 111:1 112:1 114:1 115:1 116:1 117:1 118:1 119:1 126:1 127:1 128:1 136:1 137:1 138:1 139:1 141:1 142:1 143:1 144:1 146:1 147:1 148:1 149:1 150:1 151:1 152:1 153:1 154:1 155:1 162:1 163:1 164:1 172:1 173:1 174:1 175:1 177:1 178:1 179:1 180:1 182:1 184:1 185:1 192:1 193:1 194:1 195:1 196:1 197:1 198:1 199:1 200:1 201:1 203:1 205:1 206:1 207:1 208:1 209:1 210:1 211:1 214:1 217:1 218:1 225:1 228:1 229:1 230:1 231:1 232:1 233:1 234:1 235:1 236:1 237:1 238:1 241:1 242:1 243:1 244:1 245:1 246:1 247:1 248:1 249:1 250:1 251:1 252:1 253:1 254:1 256:1 257:1 259:1 262:1 263:1 265:1 267:1 268:1 269:1 270:1 277:1 278:1 279:1 284:1 285:1 291:1 292:1 298:1 299:1 305:0 306:0 311:1 314:1 322:1 326:1 327:1 328:1 329:1 330:1 332:1 333:1 334:1 335:1 336:1 337:1 338:1 339:1 340:1 343:1 344:1 345:1 346:1 347:1 349:1 350:1 351:1 352:1 353:1 354:1 355:1 356:1 357:1 360:1 361:1 362:1 363:1 364:1 365:1 366:1 367:1 368:1 369:1 378:1 379:1 385:1 391:1 392:1 398:1 399:1 405:1 414:1 417:1 418:1 419:1 420:1 425:1 431:1 437:0 440:1 447:1 448:1 449:1 452:1 453:1 454:1
+
+### Controllers/EfcDataModel.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 193/255
+- LINE-MAP: 23:1 24:1 25:1 28:1 29:1 30:1 33:1 34:1 35:1 38:1 39:1 40:1 41:1 42:1 43:1 44:1 48:1 49:1 50:1 51:1 52:1 53:1 54:1 55:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 63:1 64:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 72:1 73:1 74:1 75:1 77:1 78:1 79:1 80:1 81:1 83:1 84:1 85:1 86:1 87:1 96:1 97:1 98:1 99:1 101:1 102:1 103:1 104:1 105:1 107:1 108:1 109:1 110:1 111:1 114:1 115:1 116:1 117:1 118:1 119:1 120:1 121:1 122:1 123:1 125:1 126:1 127:1 128:1 129:1 130:1 131:1 132:1 133:1 134:1 136:1 137:1 138:1 139:1 141:1 142:1 154:1 159:1 160:1 166:1 167:1 173:1 174:1 181:1 183:1 184:1 185:1 191:1 192:1 199:1 200:1 201:1 202:1 203:1 206:1 209:1 211:1 212:1 213:0 214:0 215:0 218:0 219:0 222:1 223:1 224:1 226:1 246:1 248:1 249:1 250:1 252:1 253:1 254:1 255:1 256:1 257:1 258:1 259:1 260:1 262:1 275:1 276:1 277:1 278:1 281:1 282:1 283:1 284:1 286:1 287:1 288:1 289:1 292:1 293:1 294:1 297:1 298:1 299:1 300:1 301:1 302:1 303:1 304:1 305:1 306:1 308:1 309:1 310:1 311:1 324:0 325:0 326:0 329:1 330:1 331:1 332:1 335:1 336:1 337:1 338:1 341:0 342:0 343:0 344:0 345:0 346:0 347:0 349:0 350:0 351:1 354:1 355:1 356:1 357:1 359:1 360:1 361:1 362:1 365:0 366:0 367:0 368:0 369:0 370:0 371:0 373:0 374:0 375:1 385:0 386:0 387:0 388:0 389:0 390:0 391:0 392:0 393:0 394:0 395:0 396:0 397:0 398:0 414:1 415:1 416:1 417:1 418:1 419:1 420:1 421:1 422:1 425:1 426:1 427:1 430:0 431:0 432:0 433:0 436:0 437:0 439:0 442:0 443:0 444:0 445:0 446:0 448:0 449:0 450:0 451:0 452:0 453:0 454:0 457:0 459:0 460:0
+
+### Controllers/QfcItemController.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 74/74
+- LINE-MAP: 30:1 31:1 32:1 37:1 38:1 98:1 99:1 102:1 105:1 106:1 112:1 113:1 116:1 119:1 120:1 123:1 126:1 127:1 132:1 137:1 138:1 144:1 146:1 150:1 151:1 157:1 158:1 160:1 165:1 174:1 183:1 184:1 189:1 195:1 197:1 198:1 199:1 200:1 201:1 202:1 203:1 204:1 205:1 207:1 208:1 209:1 210:1 211:1 215:1 216:1 219:1 222:1 224:1 225:1 226:1 227:1 228:1 229:1 231:1 232:1 233:1 234:1 240:1 265:1 271:1 275:1 276:1 281:1 293:1 294:1 295:1 296:1 297:1 298:1
+
+### Controllers/QfcItemController.ViewerSetup.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 194/213
+- LINE-MAP: 89:0 90:0 91:0 92:0 93:0 96:0 97:0 98:0 99:0 100:0 101:0 102:0 133:1 134:1 135:1 136:1 144:1 145:1 146:0 147:1 148:1 149:1 152:1 153:1 154:1 155:1 156:1 157:1 163:1 164:1 165:0 166:1 167:0 168:0 169:1 170:1 184:1 185:1 186:1 191:1 192:1 193:1 194:1 197:1 198:1 199:1 200:1 203:1 204:1 205:1 210:1 211:1 212:1 213:1 216:1 217:1 218:1 219:1 223:1 230:1 232:1 233:1 234:1 236:1 237:1 238:1 240:1 242:1 244:1 245:1 246:1 247:1 248:1 249:1 250:1 252:1 253:1 254:1 255:1 256:1 257:1 258:1 260:1 261:1 262:1 263:1 265:1 266:1 277:1 278:1 280:1 281:1 282:1 283:1 284:1 285:1 287:1 288:1 296:1 297:1 298:1 299:1 301:1 302:1 303:1 304:1 307:1 308:1 309:1 310:1 311:1 312:1 313:1 315:1 316:1 317:1 318:1 319:1 320:1 321:1 323:1 324:1 325:1 326:1 328:1 329:1 332:1 333:1 335:1 336:1 339:1 340:1 341:1 342:1 349:1 352:1 354:1 357:1 358:1 361:1 373:1 374:1 375:1 376:1 377:1 380:1 381:1 384:1 386:1 387:1 388:1 389:1 392:1 393:1 394:1 395:1 396:1 397:1 398:1 399:1 400:1 401:1 403:1 404:1 405:1 406:1 408:1 409:1 411:1 412:1 414:1 415:1 417:1 418:1 419:1 422:1 425:1 426:1 427:1 428:1 429:1 430:1 432:1 433:1 434:1 435:1 436:1 437:1 439:1 440:1 441:1 442:1 443:1 444:1 445:1 447:1 448:1 449:1 450:1 451:1 453:1 454:1 456:1 457:1 462:1 463:1 464:0 465:0 466:0 467:1 468:1 469:1 472:1
+
+### Helper Classes/EfcViewerQueue.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 46/51
+- LINE-MAP: 11:1 14:1 20:1 25:1 27:1 30:1 31:1 32:1 35:1 36:1 37:1 38:1 39:1 40:1 41:1 42:1 43:1 49:1 50:1 51:1 57:1 58:1 59:1 60:1 63:1 64:1 65:1 66:1 67:0 68:1 69:1 76:0 79:1 80:1 81:1 82:1 83:1 84:1 85:1 86:1 89:0 90:0 91:0 99:1 100:1 101:1 102:1 103:1 104:1 105:1 106:1
+
+### Viewers/WebView2EnvironmentContract.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 9/9
+- LINE-MAP: 37:1 38:1 39:1 40:1 41:1 42:1 49:1 50:1 51:1
+
+### Controllers/EfcFormController.Breadcrumb.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 62/97
+- LINE-MAP: 42:0 43:0 44:0 45:0 46:0 47:0 48:0 49:0 50:0 51:0 52:0 53:0 54:0 55:0 56:0 57:0 58:0 59:0 60:0 61:0 62:0 70:1 71:1 72:1 73:1 75:1 76:1 77:1 79:1 80:1 81:1 82:1 84:1 85:1 86:1 87:1 88:1 89:1 90:1 91:1 92:1 93:1 95:1 96:1 97:1 98:1 99:1 100:1 101:1 105:1 106:1 107:1 108:1 109:1 110:1 115:1 116:1 117:1 118:1 119:1 122:1 123:1 124:1 125:1 128:0 129:1 134:1 135:1 136:1 137:1 138:1 141:0 142:1 147:0 148:0 149:0 150:0 151:0 154:0 155:0 156:0 160:1 162:1 163:1 164:1 165:1 166:1 167:1 168:0 169:0 170:0 171:0 172:1 173:1 174:1 175:1 176:1
+
+### Controllers/EfcFormController.SetupAndProperties.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 47/123
+- LINE-MAP: 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 39:0 40:0 41:0 42:0 43:0 44:0 45:0 46:0 47:0 48:0 49:0 50:0 51:0 55:1 57:1 58:1 59:0 60:0 61:0 62:1 63:1 64:1 67:1 68:1 69:1 70:1 71:1 72:1 73:1 76:0 77:0 78:0 79:0 80:0 81:0 82:0 83:0 86:0 87:0 88:0 89:0 90:0 92:0 94:0 96:0 98:0 99:0 100:0 101:0 102:0 104:0 105:0 106:0 107:0 108:0 109:0 110:0 111:0 112:0 115:0 116:0 117:0 118:0 119:0 120:0 121:0 122:0 124:0 125:0 137:1 138:1 139:1 141:0 142:0 143:0 144:0 145:0 149:1 150:1 151:1 152:0 153:0 154:0 155:1 156:1 164:1 165:1 166:1 167:1 168:0 169:1 170:1 171:1 172:1 173:0 176:0 183:1 189:1 191:1 192:1 195:1 201:1 203:1 204:1 207:1 213:1 215:1 216:1 219:1 225:1 227:1 228:1 231:1 237:1 238:0
+
+### Controllers/EfcFormController.EventHandlers.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 44/260
+- LINE-MAP: 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 39:0 40:0 41:0 42:0 45:0 49:0 50:0 51:0 52:0 53:0 54:0 55:0 56:0 57:0 58:0 59:0 60:0 61:0 62:0 63:0 64:0 65:0 66:0 67:0 68:0 69:0 70:0 71:0 72:0 73:0 74:0 75:0 76:0 79:0 80:0 81:0 84:0 85:0 86:0 87:0 90:0 93:1 95:1 96:1 97:1 99:0 100:0 101:1 102:1 103:1 104:1 105:1 107:0 110:1 112:1 113:1 114:1 116:0 117:0 118:1 119:1 120:1 121:1 122:1 125:0 128:1 130:1 131:1 132:1 134:0 135:0 136:1 137:1 138:1 139:1 140:1 143:0 146:1 148:1 149:1 150:1 152:0 153:0 154:0 155:0 156:0 157:0 158:0 159:0 160:0 162:0 163:0 164:0 166:0 167:0 168:0 169:0 170:0 172:0 173:0 174:0 175:0 176:0 177:0 178:0 179:0 180:0 182:0 183:0 184:0 185:0 186:0 187:0 188:0 189:0 190:0 191:0 193:0 194:0 195:0 196:0 197:0 198:1 199:1 200:1 201:1 202:1 205:0 208:1 210:1 211:1 212:0 213:1 214:1 215:1 216:1 217:1 220:0 221:0 222:0 225:0 226:0 227:0 230:0 231:0 232:0 235:0 236:0 237:0 240:0 241:0 242:0 245:0 246:0 247:0 248:0 249:0 253:0 256:0 257:0 258:0 259:0 260:0 261:0 262:0 263:0 264:0 265:0 266:0 267:0 268:0 269:0 270:0 271:0 272:0 273:0 274:0 275:0 276:0 277:0 278:0 279:0 280:0 281:0 282:0 283:0 284:0 285:0 286:0 310:0 313:0 314:0 315:0 316:0 317:0 318:0 319:0 320:0 321:0 322:0 323:0 324:0 325:0 326:0 327:0 328:0 329:0 330:0 331:0 332:0 333:0 334:0 335:0 336:0 337:0 338:0 339:0 340:0 341:0 342:0 343:0 344:0 345:0 346:0 347:0 348:0 349:0 350:0 351:0 352:0 353:0 354:0 355:0 356:0 357:0 358:0 359:0 360:0 363:0 364:0 365:0 366:0 367:0 368:0 369:0 370:0 372:0 373:0 374:0 377:0 378:0 379:0
+
+### Controllers/EfcFormController.Actions.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 23/108
+- LINE-MAP: 31:0 32:0 33:0 35:0 37:0 38:0 39:0 40:0 41:0 42:0 43:0 44:0 47:0 48:0 49:0 50:0 51:0 52:0 53:0 54:0 55:0 56:0 58:0 59:0 61:0 62:0 63:0 64:0 67:0 69:0 71:0 72:0 73:0 80:1 81:1 82:0 83:0 85:1 86:1 87:1 89:1 90:1 91:1 92:1 96:1 97:1 98:1 99:1 102:1 103:1 104:1 105:1 108:0 109:0 110:0 111:0 112:0 113:0 114:0 115:0 116:0 118:0 119:0 120:0 121:0 122:0 123:0 125:0 126:0 127:0 128:0 129:0 130:0 131:0 132:0 133:0 134:0 135:0 136:0 137:0 138:0 139:0 140:0 141:0 142:0 143:0 144:0 145:0 146:0 147:0 148:0 149:0 150:0 157:1 158:1 159:1 160:1 162:1 163:1 170:0 171:0 173:0 174:0 175:0 176:0 177:0 179:0 180:0
+
+### Controllers/EfcFormController.Helpers.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 45/162
+- LINE-MAP: 37:1 39:1 40:1 41:1 42:1 43:1 47:1 48:1 49:1 50:1 51:1 52:1 53:1 56:1 57:1 58:1 59:1 60:1 61:1 62:1 65:1 66:1 67:1 68:1 69:1 70:1 71:1 74:0 75:0 77:0 78:0 81:0 82:0 83:0 86:0 87:0 88:0 90:0 93:0 94:0 95:0 96:0 99:0 100:0 101:0 102:0 103:0 104:0 105:0 108:0 109:0 110:0 111:0 112:0 113:0 114:0 117:0 118:0 119:0 120:0 121:0 124:0 125:0 126:0 127:0 128:0 129:0 130:0 133:0 134:0 135:0 136:0 137:0 138:0 139:0 141:0 142:0 143:0 144:0 145:0 148:0 149:0 150:0 151:0 152:0 153:0 154:0 155:0 156:0 158:0 159:0 160:0 161:0 162:0 163:0 164:0 167:0 168:0 171:0 172:0 173:0 175:0 182:0 185:0 186:0 187:0 189:0 190:0 192:0 193:0 195:0 196:0 197:0 201:1 203:1 207:1 208:1 209:1 211:1 213:0 215:0 216:0 217:1 218:1 219:1 220:1 221:1 225:1 226:1 227:1 228:1 229:1 233:1 234:1 236:0 241:0 242:0 243:0 244:0 245:0 246:0 247:0 248:0 249:0 250:0 251:0 252:0 253:0 254:0 256:0 257:0 258:0 259:0 260:0 261:0 262:0 263:0 264:0 265:0 266:0 267:0 268:0
+
+### Controllers/EfcDataModel.Carry.cs
+
+- CLASS-ELEMENTS: 1
+- COVERED/VALID: 34/56
+- LINE-MAP: 30:1 31:1 32:1 33:1 34:1 37:1 38:1 39:1 42:1 43:1 44:1 45:1 46:1 47:1 48:1 49:1 50:1 51:1 52:1 53:1 56:1 57:1 59:1 60:1 61:1 62:1 63:1 65:0 66:0 67:0 68:0 69:0 70:0 71:0 72:0 73:0 74:0 75:0 77:1 78:1 80:0 81:0 82:0 83:0 84:0 85:0 86:0 87:0 88:0 89:0 90:0 91:1 95:1 96:1 97:1 98:1
+
+## Uninstrumented, not comparable
+
+- Controllers/EfcItemController.cs: CLASS-ELEMENTS: 0 (class-level `[ExcludeFromCodeCoverage]` at `QuickFiler/Controllers/EfcItemController.cs:26`)
+- Controllers/EfcItemController.WebViewEnvironment.cs: CLASS-ELEMENTS: 0 (partial of the same class; the class-level `[ExcludeFromCodeCoverage]` at `QuickFiler/Controllers/EfcItemController.cs:26` applies to every part)
+- Controllers/QfcCollectionController.cs: CLASS-ELEMENTS: 0 (class-level `[ExcludeFromCodeCoverage]` at `QuickFiler/Controllers/QfcCollectionController.cs:22`)
+- Controllers/QfcCollectionController.PopOut.cs: CLASS-ELEMENTS: 0 (partial of the same class; the class-level `[ExcludeFromCodeCoverage]` at `QuickFiler/Controllers/QfcCollectionController.cs:22` applies to every part)
+
+INSTRUMENTED-FILES-WITH-ZERO-CLASS-ELEMENTS: 0 (every one of the 17 instrumented rows above has `CLASS-ELEMENTS: 1`)
+
+## Positive control on the per-file matcher
+
+The same normalised-equality matcher returned `CLASS-ELEMENTS: 1` for each of the ten baseline files with figures reconcilable to [P0-T12] (for example `QfcItemController.ViewerSetup.cs` 194/213 in both runs, `BreadcrumbBridgeRouter.Selection.cs` 140/143 in both), so a `CLASS-ELEMENTS: 0` row for the four excluded files is a true absence of class elements rather than a matcher miss.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t7-taskmaster-sweep.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t7-taskmaster-sweep.md
new file mode 100644
index 000000000..f0f1c2bd9
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t7-taskmaster-sweep.md
@@ -0,0 +1,28 @@
+# [P7-T7] Regression sweep (TaskMaster.Test, no coverage)
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-12
+- PASS-NUMBER: 1
+- Command: CMD-VSTEST (`vstest.console.exe` resolved through `vswhere -latest -products * -find 'Common7/IDE/Extensions/TestPlatform/vstest.console.exe'`, `VSTEST-RESOLVED: True`), then `& $vstest TaskMaster.Test/bin/Debug/TaskMaster.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:TestCategory!=LiveOutlook" "/Blame:CollectHangDump;TestTimeout=4min;HangDumpType=None" "/ResultsDirectory:coverage/test-results/p7-t7" "/Logger:trx;LogFileName=p7-t7.trx"` (CMD-SWEEP with `` = `p7-t7`; run from `coverage/plan792-helper.ps1 -Step sweep -PassNumber 1` with the item worktree as the working directory; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`; console captured to the gitignored `coverage/p7-t7-pass1-sweep.log`; the TRX stays under the gitignored `coverage/test-results/p7-t7/`, `TRX-EXISTS: True`)
+- EXIT_CODE: 0
+- Output Summary: `Test Run Successful.`; `Total tests: 452`; `Passed: 452`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; `Total time: 2.6925 Seconds`; 0 lines beginning `Failed ` (a test name); no Blame hang output; the run completed with a summary well inside the 4-minute per-test timeout.
+
+## Console transcription
+
+- Total tests: 452
+- Passed: 452
+- Failed: 0 (omitted category)
+- Skipped: 0 (omitted category)
+
+FAILED-SET: (empty)
+
+NEW-FAILURES: none (the empty failed set is a subset of `BASELINE_FAILURE_SET: none` from [P0-T13]; the baseline also ran 452 tests with 452 passed)
+
+## Hang check
+
+A first, deliberately broad pattern (`hang|Hang dump|The active test run was aborted`) matched 11 log lines; every one is a `Passed ` line whose test name contains the word `Unchanged` (for example `SetHighConfidenceThresholdText_WithNonNumericInput_LeavesValueUnchanged`), that is the substring `hang` inside `Unchanged`. The strict pattern `Hang dump|The active test run was aborted|test host process crashed` matched 0 lines (`STRICT-HANG: 0`). No hang dump was produced.
+
+## Notes
+
+- The assembly under test was produced by the [P7-T5] nullable Rebuild of this pass (`TaskMaster.Test/bin/Debug/TaskMaster.Test.dll`, written 21:08:11 local time; unchanged between the before and after checks of this task); no build ran in this task.
+- `scripts/vscode/TaskMaster.cli.runsettings` was passed unchanged (Workers=0, ClassLevel).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t8-coverage-delta.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t8-coverage-delta.md
new file mode 100644
index 000000000..825e68be9
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t8-coverage-delta.md
@@ -0,0 +1,126 @@
+# [P7-T8] Coverage delta (baseline `p0-baseline` versus final `p7-final`, QuickFiler.Test scope)
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-15
+- PASS-NUMBER: 1
+- Command: CMD-BASE (binds `$BaseSha` from `p0-t7-git-base.md`); both processed documents loaded from the gitignored `coverage/p0-baseline.cobertura.xml` and `coverage/p7-final.cobertura.xml`; per-file maps by the [P0-T12] max-hits merge; `git show $BaseSha:QuickFiler/Controllers/EfcFormController.cs` and `git show $BaseSha:QuickFiler/Controllers/EfcDataModel.cs` for the gate (2) text sets; `git diff --unified=0 $BaseSha HEAD -- ` for the gate (3) and (5) hunks; `Get-CoberturaPackageLineSummary` for gate (6); all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed; HEAD `c9b457bda44ef856306a1bc96c94683dc528993c`; console output encoding forced to UTF-8 before the `git show` reads)
+- EXIT_CODE: 0
+- Output Summary: gates (1) through (5) PASS; gate (6) `BRANCH: A`, PASS; gate (7) reported (0.242471 baseline, 0.244154 final); no `BLOCKED: coverage` condition.
+
+BASE-SHA: e7cbb57229c63a228e7fe0bcbcdbfbc06db8bcd3 (the `git merge-base HEAD origin/main` after `git fetch origin`, per [P0-T7]; bare local `main` was not used)
+
+## Gate (1) — `WebView2EnvironmentContract.cs` per-file line rate
+
+- COVERED/VALID: 9/9; rate 1.0000 (>= 0.90)
+- GATE-1: PASS
+
+## Gate (2) — new executable lines of the relocated parts (>= 90 percent excluding the pre-declared misses)
+
+New executable line = a Cobertura row of the file whose trimmed source text does not occur (trimmed) anywhere in the BASE-SHA text of the originating file.
+
+### `Controllers/EfcFormController.Breadcrumb.cs` (against `git show $BaseSha:QuickFiler/Controllers/EfcFormController.cs`, 1321 lines read)
+
+- ROWS-TOTAL: 97; NEW-EXECUTABLE-LINES: 23 (line numbers 71 72 76 81 86 87 88 89 90 95 96 97 98 99 106 107 108 109 116 117 122 124 128)
+- PRE-DECLARED-MISSES: 1 — line 128 `label.BeginInvoke(new MethodInvoker(() => label.Text = message));` (the `BeginInvoke` branch of `ShowFolderAreaError`), hits=0
+- COUNTED-NEW-LINES: 22; COUNTED-NEW-COVERED: 22; RATIO: 1.0000
+- Every uncovered new line, by number and text: 128 `label.BeginInvoke(new MethodInvoker(() => label.Text = message));` (the pre-declared miss; no other)
+- GATE-2-FILE: PASS
+
+### `Controllers/EfcDataModel.Carry.cs` (against `git show $BaseSha:QuickFiler/Controllers/EfcDataModel.cs`, 499 lines read)
+
+- ROWS-TOTAL: 56; NEW-EXECUTABLE-LINES: 15 (line numbers 31 33 37 44 46 47 51 52 59 60 70 72 77 96 97)
+- PRE-DECLARED-MISSES: 2 — line 70 `scoringInput,` and line 72 `).InitAsync(scoringInput, FolderPredictor.InitOptions.FromField),` (the lines of the `FromField` scoring lambda in the null-list branch that read `scoringInput`; reachable only with a live `MailItemHelper`), both hits=0
+- COUNTED-NEW-LINES: 13; COUNTED-NEW-COVERED: 13; RATIO: 1.0000
+- Every uncovered new line, by number and text: 70 `scoringInput,`; 72 `).InitAsync(scoringInput, FolderPredictor.InitOptions.FromField),` (both pre-declared; no other)
+- GATE-2-FILE: PASS
+
+GATE-2: PASS
+
+Positive controls on the classifier: the known-new line `private Task InitializeBreadcrumbHostOnceAsync()` is present once in `Breadcrumb.cs` and classified new (true); the known-moved line `private void BindFolderRows(string[] rows)` is present once and classified not-new (false). The 1321- and 499-line reads equal the [P0-T8] totals of the two originating files, so the base text sets are complete.
+
+## Gate (3) — changed-line no-regression for the seven instrumented edited files
+
+Every added line of `git diff --unified=0 $BaseSha HEAD -- ` is listed below as `hits=` (a Cobertura row) or `hits=non-executable` (no row); `n/a` marks the three cited clauses. The ratio is over the added executable lines other than the `n/a` lines.
+
+### `Viewers/WebView2BreadcrumbHost.cs` — 7 hunks, 27 added, 13 deleted
+
+- Added lines: 16-19 non-executable (doc comment); 154-157 non-executable (remarks); 161 non-executable (comment); 162 non-executable (`void NavigateCore()`); 163 hits=1; 164 hits=1 (`CoreWebView2? core = _control.CoreWebView2;`); 165 hits=1; 166 hits=1; 167-169 hits=1 (the `log.Error(` call); 170 hits=1 (`return;`); 171-172 non-executable; **173 hits=0 n/a** (`ForwardNavigateToString(html);` inside `NavigateCore`, by citation of the forwarder's exemption remark — re-derived in the post-change file at `WebView2BreadcrumbHost.cs:187-192` with `[ExcludeFromCodeCoverage]` at `:193`; the plan's citation `:170-172` referred to the pre-change file, where the remark sat at `:171-172`); 174 hits=1; 175 non-executable; 179 hits=1 (`NavigateCore();`, the null-dispatcher inline path); 183 hits=1 (`_ = dispatcher.Dispatch(NavigateCore);`); 263 hits=1 (`string cacheFolder = WebView2EnvironmentContract.ResolveUserDataFolder();`); 264 hits=1 (`CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();`)
+- ADDED-EXECUTABLE (after n/a): 13; COVERED: 13; N/A: 1; NON-EXECUTABLE: 13; RATIO: 1.0000 (plan expectation: 100 percent) — PASS
+
+### `Controllers/BreadcrumbBridgeRouter.cs` — 1 hunk, 46 added, 0 deleted
+
+- Added lines: 331-346 non-executable (const declaration text, doc comment, signature); 347-350 hits=1 (null guard and throw); 351-352 non-executable; 353-366 hits=1 (`hadPendingDocument`, `_pendingDocument = null;`, `DiscardPending()`, `BuildRows(...)` four lines, `_selectedRowId = null;`, the selection-clearing `if` block with `SelectedFolderPathChanged?.Invoke(this, null);`); 367 non-executable; 368 hits=1 (`_host.NavigateToString(...)`); 369-374 hits=1 (the `log.Error(` call); 375 hits=1; 376 non-executable
+- ADDED-EXECUTABLE (after n/a): 26; COVERED: 26; N/A: 0; NON-EXECUTABLE: 20; RATIO: 1.0000 (plan expectation: 100 percent, selection-clearing branch included) — PASS
+
+### `Controllers/BreadcrumbOutboundQueue.cs` — 1 hunk, 13 added, 0 deleted
+
+- Added lines: 66-73 non-executable (doc comment, signature); 74 hits=1; 75 hits=1 (`int discarded = _pending.Count;`); 76 hits=1 (`_pending.Clear();`); 77 hits=1 (`return discarded;`); 78 hits=1
+- ADDED-EXECUTABLE (after n/a): 5; COVERED: 5; N/A: 0; NON-EXECUTABLE: 8; RATIO: 1.0000 (plan expectation: 100 percent, the three `DiscardPending` statements) — PASS
+
+### `Controllers/EfcHomeController.cs` — 4 hunks, 20 added, 3 deleted
+
+- Added lines: 50-52 non-executable (public constructor parameters); **54-61 hits=0 n/a** (the public constructor's forwarding initializer `: this(` through `) { }`, by citation of `EfcHomeController.cs:40`, re-derived: `private static EfcHomeControllerDependencies CreateDefaultDependencies()` is at line 40 and binds the production factories, and every QuickFiler.Test call site passes a dependencies instance); 67-69 hits=1 (internal constructor parameters); 84-86 non-executable (comment); 87 hits=1 (`DataModel.CarriedFolderHandler = carriedFolderHandler;`); 88 hits=1 (`DataModel.CarriedMailHelper = carriedMailHelper;`); 89 non-executable
+- The two deposit statements (87, 88) are covered, as required.
+- ADDED-EXECUTABLE (after n/a): 5; COVERED: 5; N/A: 8; NON-EXECUTABLE: 7; RATIO: 1.0000 (plan expectation: 100 percent) — PASS
+
+### `Controllers/QfcItemController.cs` — 1 hunk, 6 added, 0 deleted
+
+- Added lines: 267-270 non-executable (doc comment); 271 hits=1 (`internal IFolderSearchHandler FolderHandler => _folderHandler;`); 272 non-executable
+- ADDED-EXECUTABLE (after n/a): 1; COVERED: 1; N/A: 0; NON-EXECUTABLE: 5; RATIO: 1.0000 (plan expectation: 100 percent) — PASS
+
+### `Helper Classes/EfcViewerQueue.cs` — 3 hunks, 9 added, 2 deleted
+
+- Added lines: 25 hits=1 (`> ProductionBlockingPriorityScheduler { get; set; } = InvokeOnUiDispatcher;`, the initializer); 68 hits=1 (`ProductionBlockingPriorityScheduler = InvokeOnUiDispatcher;`, the reset); 71-75 non-executable (doc comment and signature); **76 hits=0 n/a** (`UiThread.Dispatcher.Invoke(action, priority);`, the single body line of `InvokeOnUiDispatcher`, by citation of D8: `UiThread.Dispatcher` throws `InvalidOperationException` outside an initialized UI thread, re-derived at `UtilitiesCS/Threading/UiThread.cs:264-282`, throw at `:277`); 77 non-executable
+- Its remaining added executable lines (25, 68) are covered, as required.
+- ADDED-EXECUTABLE (after n/a): 2; COVERED: 2; N/A: 1; NON-EXECUTABLE: 6; RATIO: 1.0000 (plan expectation: 100 percent) — PASS
+
+### `Controllers/QfcItemController.ViewerSetup.cs` — 1 hunk, 3 added, 8 deleted
+
+- Added lines: 55 non-executable (comment); 56 non-executable (`string cacheFolder = WebView2EnvironmentContract.ResolveUserDataFolder();`); 57 non-executable (`CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();`) — no Cobertura row exists for any of them because they sit inside the method-level-exempt `InitializeWebViewAsync` (`[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]` re-derived at `QfcItemController.ViewerSetup.cs:48`, the method signature at `:49`)
+- Recorded `n/a` by citation of `ViewerSetup.cs:48` — PASS (not ratio-gated)
+
+GATE-3: PASS (no file carries an added executable line that no test reached other than the three `n/a` lines; no `BLOCKED: coverage`)
+
+## Gate (4) — type-level no-regression for the split
+
+- `EfcFormController` parts, final `lines-covered`: `EfcFormController.cs` 74 + `Breadcrumb.cs` 62 + `SetupAndProperties.cs` 47 + `EventHandlers.cs` 44 + `Actions.cs` 23 + `Helpers.cs` 45 = 295; baseline `EfcFormController.cs` 251; 295 >= 251 — PASS
+- `EfcDataModel`: `EfcDataModel.cs` 193 + `EfcDataModel.Carry.cs` 34 = 227; baseline `EfcDataModel.cs` 189; 227 >= 189 — PASS
+
+GATE-4: PASS
+
+## Gate (5) — per-file no-regression for the seven files (post >= base minus deleted covered lines)
+
+| File | post `lines-covered` | base `lines-covered` | deleted lines with base hits >= 1 | floor | result |
+|---|---|---|---|---|---|
+| `Viewers/WebView2BreadcrumbHost.cs` | 100 | 91 | 6 (old lines 166, 246-250) | 85 | PASS |
+| `Controllers/BreadcrumbBridgeRouter.cs` | 237 | 211 | 0 | 211 | PASS |
+| `Controllers/BreadcrumbOutboundQueue.cs` | 29 | 23 | 0 | 23 | PASS |
+| `Controllers/EfcHomeController.cs` | 230 | 226 | 1 (old line 58) | 225 | PASS |
+| `Controllers/QfcItemController.cs` | 74 | 73 | 0 | 73 | PASS |
+| `Helper Classes/EfcViewerQueue.cs` | 46 | 46 | 2 (old lines 25, 68) | 44 | PASS |
+| `Controllers/QfcItemController.ViewerSetup.cs` | 194 | 194 | 0 (the 8 deleted lines had no baseline row; method-level exempt) | 194 | PASS |
+
+GATE-5: PASS
+
+## Gate (6) — package comparability
+
+- `QuickFiler` package `lines-valid`: baseline 12633, final 12754; absolute difference 121; 1 percent of the baseline figure 126.33; 121 <= 126.33
+- BRANCH: A
+- `QuickFiler` package `line-rate`: baseline 0.817304, final 0.820056; baseline minus 0.005 = 0.812304; 0.820056 >= 0.812304
+- GATE-6: PASS
+
+(Branch B not taken.)
+
+## Gate (7) — scoped document line-rate, reported, not gated (D10)
+
+- QUICKFILER-SCOPED-DOCUMENT-LINE-RATE: baseline 0.242471 | final 0.244154
+- REPO-WIDE-FLOOR: NOT MEASURED (single test assembly; see D10)
+
+## Summary against the Phase 0 baseline
+
+- `QuickFiler` package: 10325/12633 lines (0.817304), 2487/3187 branches (0.780358) at baseline; 10459/12754 lines (0.820056), 2517/3217 branches (0.782406) final; +134 covered lines, +121 valid lines.
+- Tests: 1436 passed at baseline; 1468 passed final (+32).
+
+## Acceptance
+
+Gates (1) through (5) are PASS; exactly one branch of (6) is named (A). No `BLOCKED: coverage`.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t9-toolchain-pass.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t9-toolchain-pass.md
new file mode 100644
index 000000000..cb4902aad
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p7-t9-toolchain-pass.md
@@ -0,0 +1,30 @@
+# [P7-T9] Single-pass closure of the final toolchain loop
+
+- Issue: #792
+- Timestamp: 2026-09-17T21-16
+- Command: none (closure record over the artifacts of the final pass; no command run by this task)
+- EXIT_CODE: 0
+- Output Summary: the loop closed on PASS-NUMBER 1; all four steps (format, analyzers, nullable, tests-with-coverage) passed without errors in that one pass; no restart occurred.
+
+## The four step artifacts of the final pass
+
+| Step | Artifact | PASS-NUMBER | Result |
+|---|---|---|---|
+| Format ([P7-T2]) | `evidence/qa-gates/p7-t2-format.md` | 1 | `Formatted 1658 files in 4695ms.` (exit 0); `REWRITTEN-WRITE-SET-FILES: 0`; `OUT-OF-SCOPE-REWRITE-COUNT: 0`; `Checked 1658 files in 4924ms.` (exit 0); `RESTART-REQUIRED: false` |
+| Analyzers ([P7-T4]) | `evidence/qa-gates/p7-t4-analyzers.md` | 1 | `EXIT_CODE: 0`; `Build succeeded.`; ` 0 Warning(s)`; ` 0 Error(s)`; 36 csc invocations, 0 skipped CoreCompile |
+| Nullable ([P7-T5]) | `evidence/qa-gates/p7-t5-nullable.md` | 1 | `EXIT_CODE: 0`; `Build succeeded.`; ` 0 Warning(s)`; ` 0 Error(s)`; 36 csc invocations, 0 skipped CoreCompile |
+| Tests with coverage ([P7-T6]) | `evidence/qa-gates/p7-t6-coverage-final.md` | 1 | `Test Run Successful.`; `Total tests: 1468`; `Passed: 1468`; `Failed: 0 (omitted category)`; runner `EXIT_CODE: 1` with `ExpectedExitCode: 1` (threshold assertion only); processed document present with `` |
+
+## Format observation
+
+The format step of the final pass rewrote no write-set file (all 29 SHA-256 values unchanged) and no file outside the write set (no new porcelain entry), and the read-only check exited 0 printing `Checked 1658 files in 4924ms.`. The empty `BASELINE-DRIFT-SET` of [P0-T9] was therefore never consulted.
+
+## Companion tasks of the same pass
+
+- [P7-T3] `evidence/qa-gates/p7-t3-file-size-audit.md` (PASS-NUMBER 1): `OVER-CEILING-AFTER: 2`, `UNEXPECTED-OVER-CEILING: 0`.
+- [P7-T7] `evidence/qa-gates/p7-t7-taskmaster-sweep.md` (PASS-NUMBER 1): 452/452, `NEW-FAILURES: none` — PASS.
+- [P7-T8] `evidence/qa-gates/p7-t8-coverage-delta.md` (PASS-NUMBER 1): gates (1) through (5) PASS, gate (6) `BRANCH: A` PASS, gate (7) reported — PASS.
+
+## Statement
+
+All four toolchain steps — `dotnet tool run csharpier format .` (verified by `dotnet tool run csharpier check .`), `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true`, `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true`, and the QuickFiler.Test coverage run through `scripts/vscode/Invoke-MSTestWithCoverage.ps1` — passed without errors in one pass (PASS-NUMBER 1), and Outlook was verified closed before each rebuild ([P7-T1], [P7-T4], [P7-T5]). LOOP-PASSES-RUN: 1; RESTARTS: 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/fail-before-exception.p0-t15.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/fail-before-exception.p0-t15.md
new file mode 100644
index 000000000..364a98e29
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/fail-before-exception.p0-t15.md
@@ -0,0 +1,23 @@
+# [P0-T15] AC-U4 pass-before observation — `PopulateFolderCombobox` half (fail-before exception dossier)
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-49
+- Command: CMD-VSTEST, then CMD-OUTLOOK and CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`, exit 0, `0 Error(s)`, incremental: `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` unchanged from the [P0-T11] Rebuild at 18:42:46), then `& $vstest QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:FullyQualifiedName~EfcFormControllerTests.PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault" "/ResultsDirectory:coverage/test-results/p0-t15" "/Logger:trx;LogFileName=p0-t15.trx"` (CMD-SCOPED-RUN with `` = `p0-t15`; run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; console captured to the gitignored `coverage/p0-t15-scoped.log`; TRX under the gitignored `coverage/test-results/p0-t15/`)
+- EXIT_CODE: 0
+- Output Summary: `Passed PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault [50 ms]`; `Test Run Successful.`; `Total tests: 1`; `Passed: 1`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; the filter discovered exactly one test, so the run is not vacuous.
+
+## Why a failing run is impossible for this half of AC-U4
+
+WhyFailingRunImpossible: `TryReportBoundaryFault(ex.Message, ex)` already exists at `QuickFiler/Controllers/EfcFormController.cs:1270` inside the catch block of `PopulateFolderCombobox` (declared at `EfcFormController.cs:1251`), so the `PopulateFolderCombobox` half of AC-U4 is already satisfied on the unfixed tree and cannot be observed failing. The work for this half is the strengthened user-surface test `PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink` (created in [P1-T2] in `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs`), whose non-vacuity is proven by mutation in [P5-T1] (dropping the notifier call inside `DefaultBoundaryErrorSink`, which the existing test at `EfcFormControllerTests.cs:300` cannot detect because it asserts only the sink call count).
+
+The other half of AC-U4 (`InitializeBreadcrumbHostAsync`) is a real change and is observed failing at [P1-T4]; it is not covered by this dossier.
+
+## Alternative proof (pass-before observation)
+
+The existing test `QuickFiler.Controllers.Tests.EfcFormControllerTests.PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault` (`QuickFiler.Test/Controllers/EfcFormControllerTests.cs:300`) passed on the unfixed tree as transcribed above, which pins the current behaviour that the strengthened test extends.
+
+## Negative-evidence search (no prior dossier or failing run exists)
+
+- SearchScope: `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/` and the whole feature folder `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/` (the feature is single-version; no `v1/` scope exists)
+- SearchPatterns: `**/fail-before-exception.*.md`
+- SearchResult: none (this file is the first dossier written for the feature)
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p0-t14-ac-u6-structural-fail-before.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p0-t14-ac-u6-structural-fail-before.md
new file mode 100644
index 000000000..a4a658263
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p0-t14-ac-u6-structural-fail-before.md
@@ -0,0 +1,35 @@
+# [P0-T14] AC-U6 structural gate — observed FAILING on the unfixed tree
+
+- Issue: #792
+- Timestamp: 2026-09-17T18-48
+- Command: `pwsh -NoProfile -WorkingDirectory -File coverage/plan792-helper.ps1` where `coverage/plan792-helper.ps1` holds the CMD-AC-U6-GATE block from the plan verbatim (`` is the item worktree root; the helper's opening branch assertion `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` is the worktree proof and passed)
+- EXIT_CODE: 0
+- Output Summary: `AC-U6-STRUCTURAL: FAIL` — three primary construction sites, one direct `CoreWebView2Environment.CreateAsync` outside the adapter, two seam callers, zero contract readers. Every line of the output matches the plan's declared unfixed-tree output.
+
+OBSERVED-FAILING: AC-U6 structural gate
+
+## Gate output (verbatim, complete)
+
+```
+PRIMARY-CONSTRUCTION-COUNT: 3
+PRIMARY-SITE: QuickFiler/Controllers/EfcItemController.cs:188
+PRIMARY-SITE: QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:62
+PRIMARY-SITE: QuickFiler/Viewers/WebView2BreadcrumbHost.cs:250
+CREATEASYNC-OUTSIDE-ADAPTER: 1
+CREATEASYNC-SITE: QuickFiler/Controllers/EfcItemController.cs:195
+SEAM-CALLER-COUNT: 2
+SEAM-CALLER: QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:71
+SEAM-CALLER: QuickFiler/Viewers/WebView2BreadcrumbHost.cs:265
+CONTRACT-READER-COUNT: 0
+AC-U6-STRUCTURAL: FAIL
+```
+
+No `CONTRACT-READER:` line was printed. The three `PRIMARY-SITE:` lines and the two `SEAM-CALLER:` lines appear in `git ls-files` order.
+
+## Comment-filter observation
+
+The dead comment lines `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:61` and `QuickFiler/Controllers/EfcItemController.cs:187` (both `// CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions("--disk-cache-size=1 ");`) were excluded by the `^\s*//` comment filter, so the gate counts the live target-typed construction at `ViewerSetup.cs:62` and not the dead comment above it; the commented-out `//var task = CoreWebView2Environment.CreateAsync(...)` at `ViewerSetup.cs:124` was excluded the same way. The adapter forward at `QuickFiler/Viewers/WebView2CoreInitializer.cs:72` was excluded by the adapter-path filter, which is why `CREATEASYNC-OUTSIDE-ADAPTER` is 1 and names only `EfcItemController.cs:195`.
+
+## Positive control
+
+Independent re-derivation with a separate tool before the gate ran (Grep over `QuickFiler/**/*.cs`) reached the same 3 + 2 dead-comment hits for the type name, the same 1 live + 1 adapter + 1 commented `CreateAsync` hits, the same 2 seam callers, and 0 occurrences of `WebView2EnvironmentContract` anywhere under `QuickFiler/`; the gate's zero contract-reader count is therefore a true zero rather than a mis-scoped pattern.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p1-t4-fail-before.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p1-t4-fail-before.md
new file mode 100644
index 000000000..fa9b77a4b
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p1-t4-fail-before.md
@@ -0,0 +1,57 @@
+# [P1-T4] [expect-fail] Phase 1 regression tests observed failing on the unfixed tree
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-01
+- Command: CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true`), then CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`, exit 0, `0 Warning(s)`, exact line `0 Error(s)`, `Build succeeded.`, 4 s incremental; `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` rewritten at 19:01:15 so the three new Phase 1 files compiled), then CMD-VSTEST (vswhere resolved `vstest.console.exe`), then `& $vstest QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:FullyQualifiedName~WebView2BreadcrumbHostIssue792Tests|FullyQualifiedName~EfcFormControllerIssue792Tests|FullyQualifiedName~EfcViewerQueueIssue792Tests" "/ResultsDirectory:coverage/test-results/p1-t4" "/Logger:trx;LogFileName=p1-t4.trx"` (CMD-SCOPED-RUN with `` = `p1-t4`; run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; console captured to the gitignored `coverage/p1-t4-scoped.log`; TRX under the gitignored `coverage/test-results/p1-t4/`)
+- EXIT_CODE: 1
+- ExpectedExitCode: 1
+- Output Summary: `Test Run Failed.`; `Total tests: 5`; `Passed: 1`; `Failed: 4`; `Skipped: 0 (omitted category)`; `Total time: 1.3937 Seconds`. The partition matches the plan's declaration exactly (5 / 1 / 4, the four declared tests failing, the declared control passing), and each failing test failed on its pre-predicted assertion. The filter discovered exactly five tests, so the run is not vacuous.
+
+## Observed partition
+
+Declared by the plan: `Total tests: 5`, `Passed: 1`, `Failed: 4`, failing set = the two host tests, `InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser`, `ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke`; pass-before control = `PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink`.
+
+Observed (console, in reported order):
+
+- `Passed PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink [57 ms]`
+- `Failed InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser [66 ms]`
+- `Failed ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke [136 ms]`
+- `Failed InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam [193 ms]`
+- `Failed NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing [8 ms]`
+
+PARTITION-MATCHES-DECLARATION: true
+
+## Fail-before evidence (first assertion message line per failed test)
+
+FAIL-BEFORE: QuickFiler.Test.Viewers.WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam | Expected capturedOptions.AdditionalBrowserArguments to be "--incognito " because every WebView2 site must share the same incognito browser argument, but found .
+
+FAIL-BEFORE: QuickFiler.Test.Viewers.WebView2BreadcrumbHostIssue792Tests.NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing | Did not expect any exception because a document navigated before core initialization must be dropped, not forwarded to a control with no core, but found System.InvalidOperationException: The instance of CoreWebView2 is uninitialized and unable to complete this operation. See EnsureCoreWebView2Async.
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser | Expected captured to contain a single item because the final initialization failure must be reported to the user exactly once, but the collection is empty.
+
+FAIL-BEFORE: QuickFiler.Test.HelperClasses.EfcViewerQueueIssue792Tests.ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke | Expected scheduler.Method.Name to be a match with the expectation because the blocking scheduler must be the named UI-dispatcher invoke, not a lambda, but it differs at index 0: (actual) "<.cctor>b__25_2" / (expected) "InvokeOnUiDispatcher"
+
+PASS-BEFORE-CONTROL: EfcFormControllerIssue792Tests.PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink
+
+## Correspondence to the plan's predictions
+
+- Host test 1: the plan predicts the second assertion (the `AdditionalBrowserArguments` literal) fails because the parameterless options carry null. Observed: the folder assertion passed and the arguments assertion failed with `found `. Matches.
+- Host test 2: the plan predicts the inline forward reaches `WebView2.NavigateToString` on a control with no core and throws `InvalidOperationException`. Observed: `System.InvalidOperationException: The instance of CoreWebView2 is uninitialized`. Matches.
+- `InitializeBreadcrumbHostAsync` test: the plan predicts the null host raises `NullReferenceException`, which the old catch logs only, so the list stays empty. Observed: the method did not throw (the `NotThrowAsync` assertion passed) and the captured list was empty. Matches.
+- Scheduler test: the plan predicts the default is a lambda whose compiler-generated name is not `InvokeOnUiDispatcher`. Observed actual name `<.cctor>b__25_2` (compiler-generated, static-constructor lambda). Matches.
+
+## Observed-failing map entries satisfied by this run
+
+- AC-U3 UI-thread half: `ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke` observed failing.
+- AC-U4 `InitializeBreadcrumbHostAsync` half: `InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser` observed failing.
+- AC-U6 site-1 seam test: `InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` observed failing.
+- Host pre-initialization guard (D4): `NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing` observed failing.
+
+## Files created in Phase 1 (line counts by `(Get-Content -LiteralPath ).Count`)
+
+- `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs`: 151 (ceiling 200)
+- `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs`: 148 (ceiling 260)
+- `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs`: 42 (ceiling 120); contains no `DoNotParallelize` token and no `ResetProductionCoreDefaultsForTesting` token (positive control: the same search hits `ViewerQueueStaticWrapperTests.cs` at lines 11 and 18,20)
+- `QuickFiler.Test/QuickFiler.Test.csproj`: three bare self-closing `` items added (numstat `3 0` against `origin/main`), at lines 128, 219 and 233, each immediately after its named neighbour (127, 218, 232); CRLF preserved.
+
+No production `.cs` file, no other `.csproj`, and no `.runsettings` file differs from `origin/main` after Phase 1.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p2-t14-pure-move-proof.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p2-t14-pure-move-proof.md
new file mode 100644
index 000000000..ea72fa0f3
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p2-t14-pure-move-proof.md
@@ -0,0 +1,22 @@
+# [P2-T14] Pure-move proof by the pre-existing suites
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-26
+- Command: CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true`), then CMD-VSTEST (vswhere resolved `vstest.console.exe`), then CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), then `& $vstest QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:FullyQualifiedName~EfcFormControllerTests|FullyQualifiedName~EfcItemControllerTests|FullyQualifiedName~EfcDataModel|FullyQualifiedName~QfcCollectionControllerTests|FullyQualifiedName~ViewerQueueStaticWrapperTests|FullyQualifiedName~BreadcrumbBridgeRouterQueueTests|FullyQualifiedName~WebView2BreadcrumbHostTests|FullyQualifiedName~EfcHomeController" "/ResultsDirectory:coverage/test-results/p2-t14" "/Logger:trx;LogFileName=p2-t14.trx"` (CMD-SCOPED-RUN with `` = `p2-t14`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; build console captured to the gitignored `coverage/p2-t14-build-plain.log`, test console to `coverage/p2-t14-scoped.log`, TRX under the gitignored `coverage/test-results/p2-t14/`)
+- EXIT_CODE: 0
+- Output Summary: `Test Run Successful.`; `Total tests: 187`; `Passed: 187`; `Failed: 0 (omitted category)`; `Skipped: 0 (omitted category)`; `Total time: 2.4446 Seconds`. `Total tests:` equals `Passed:` and exceeds the required minimum of 60. No test failed, so no HALT.
+
+## Build step
+
+- `BUILD-EXIT_CODE: 0`; `Build succeeded.`; ` 0 Warning(s)`; ` 0 Error(s)` (exact-line match `^\s+0 Error\(s\)$` = true); 1 s (incremental, nothing to do).
+- `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` timestamp 19:24:34, i.e. the assembly produced by the [P2-T13] nullable Rebuild, which ran after the last Phase 2 source edit (the `using UtilitiesCS;` repair recorded in `qa-gates/p2-t13-compile-gate.md`). The assemblies under test therefore contain every Phase 2 change.
+
+## Run observations
+
+- `PASSED-LINES-COUNTED: 187` (`Passed ` console lines) and `PASSED-TEST-NAMES-UNIQUE: 187`, consistent with the summary; no `Failed ` line and no discovery warning (`No test is available` / `No test matches`) in the 198-line console log.
+- The filter discovered 187 tests, so the run is not vacuous.
+- `scripts/vscode/TaskMaster.cli.runsettings`: `git diff --numstat origin/main -- scripts/vscode/TaskMaster.cli.runsettings` printed nothing (byte-identical to `origin/main`; `Workers=0`, `ClassLevel` unchanged). The run used `/Settings:` with that file and `/InIsolation`, as the plan's CMD-SCOPED-RUN specifies.
+
+## What this run proves
+
+Phase 2 made no behaviour change: the six-way `EfcFormController` split, the three verbatim member moves (`EfcItemController.WebViewEnvironment.cs`, `QfcCollectionController.PopOut.cs`, `EfcDataModel.Carry.cs`), the new `WebView2EnvironmentContract` type (no consumers yet), the declaration-only seams ([P2-T6] through [P2-T10], [P2-T12]) and the trailing optional constructor parameters plus carry deposit in `EfcHomeController` ([P2-T11]) leave every pre-existing test in the eight named suites passing. The conservation gates for the four moves are recorded in `qa-gates/p2-t13-compile-gate.md` (each `CONSERVATION-DIFF-COUNT: 0` with a non-zero positive control).
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t7-fail-before.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t7-fail-before.md
new file mode 100644
index 000000000..f597f2fff
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t7-fail-before.md
@@ -0,0 +1,118 @@
+# [P3-T7] [expect-fail] Whole-set regression tests observed failing on the unfixed tree
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-47
+- Command: CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true`), then CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`, exit 0, `0 Warning(s)`, exact line `0 Error(s)`, `Build succeeded.`, 6 s incremental; the log contains 19 `CoreCompile:` target lines and 2 `csc.exe` lines both naming `QuickFiler.Test`, and `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` was rewritten at 19:47:43, so the six Phase 3 files compiled and the build was not vacuous), then CMD-VSTEST (vswhere resolved `vstest.console.exe`), then `& $vstest QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:FullyQualifiedName~Issue792|FullyQualifiedName~WebView2EnvironmentContractTests" "/ResultsDirectory:coverage/test-results/p3-t7" "/Logger:trx;LogFileName=p3-t7.trx"` (CMD-SCOPED-RUN with `` = `p3-t7`; run from a helper script with the item worktree as the working directory; console captured to the gitignored `coverage/p3-t7-scoped.log`; build console to the gitignored `coverage/p3-t7-build.log`; TRX under the gitignored `coverage/test-results/p3-t7/`)
+- EXIT_CODE: 1
+- ExpectedExitCode: 1
+- Output Summary: `Test Run Failed.`; `Total tests: 31`; `Passed: 13`; `Failed: 18`; `Skipped: 0 (omitted category)`; `Total time: 1.6525 Seconds`. The partition matches the plan's declaration exactly (31 / 13 / 18; the eighteen declared tests fail, the thirteen declared controls pass), and each failing test failed on its pre-predicted assertion. The filter discovered exactly thirty-one tests, so the run is not vacuous.
+
+## Observed partition
+
+Declared by the plan: `Total tests: 31` (2 + 2 + 1 from Phase 1, 3 + 4 + 3 + 5 + 6 + 5 from Phase 3), `Passed: 13`, `Failed: 18`, with both sets enumerated by name in [P3-T7].
+
+Observed: `Total tests: 31`, `Passed: 13`, `Failed: 18`. The TRX contains 31 `UnitTestResult` rows: 18 `Failed`, 13 `Passed`.
+
+PARTITION-MATCHES-DECLARATION: true
+
+## Fail-before evidence (first assertion message line per failed test; fully qualified from the TRX)
+
+FAIL-BEFORE: QuickFiler.Test.Viewers.WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam | Expected capturedOptions.AdditionalBrowserArguments to be "--incognito " because every WebView2 site must share the same incognito browser argument, but found .
+
+FAIL-BEFORE: QuickFiler.Test.Viewers.WebView2BreadcrumbHostIssue792Tests.NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing | Did not expect any exception because a document navigated before core initialization must be dropped, not forwarded to a control with no core, but found System.InvalidOperationException: The instance of CoreWebView2 is uninitialized and unable to complete this operation. See EnsureCoreWebView2Async.
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser | Expected captured to contain a single item because the final initialization failure must be reported to the user exactly once, but the collection is empty.
+
+FAIL-BEFORE: QuickFiler.Test.HelperClasses.EfcViewerQueueIssue792Tests.ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke | Expected scheduler.Method.Name to be a match with the expectation because the blocking scheduler must be the named UI-dispatcher invoke, not a lambda, but it differs at index 0: (actual) "<.cctor>b__26_2" / (expected) "InvokeOnUiDispatcher"
+
+FAIL-BEFORE: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner | Expected _navigated to contain a single item because the failure must navigate exactly one document, the error banner, but the collection is empty.
+
+FAIL-BEFORE: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_LeavesNoStashForALaterInitialization | Expected _navigated[0] "... (5,000-character rendered folder document, elided) ..." to contain "Folder list unavailable" because the single navigation must be the error banner.
+
+FAIL-BEFORE: QuickFiler.Test.Controllers.BreadcrumbOutboundQueueIssue792Tests.DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending | Expected discarded to be 3 because the discarded count must equal the number buffered, but found 0 (difference of -3).
+
+FAIL-BEFORE: QuickFiler.Test.Controllers.BreadcrumbOutboundQueueIssue792Tests.NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting | Expected queue.PendingCount to be 0 because a failed initialization must discard the buffered payloads, but found 2 (difference of 2).
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce | Expected initializer.Invocations to be 3 because the host initializer must be attempted exactly the limit of three times, but found 0 (difference of -3).
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing | Expected initializer.Invocations to be 2 because the loop must stop on the first successful attempt, but found 0 (difference of -2).
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_WhenCanceled_DoesNotRetryOrReport | Expected initializer.Invocations to be 1 because a canceled attempt must not be retried, but found 0 (difference of -1).
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_OnFinalFailure_ShowsTheErrorTextInTheFolderAreaLabel | Expected label.Text to be "Matched Folders: unavailable (breadcrumb initialization failed)" with a length of 63 because the folder-area label is the visible carrier of the final failure, but "" has a length of 0, differs near "" (index 0).
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_OnFinalFailure_NotifiesTheRouter | Expected navigated to contain a single item because the router must navigate exactly one document on failure, but the collection is empty.
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts | Expected adopts to be True because a concrete predictor with no explicit list must be adopted, but found False.
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry | Test method QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry threw exception: System.NullReferenceException: Object reference not set to an instance of an object. (thrown from `UtilitiesCS.FolderPredictor..ctor(IApplicationGlobals AppGlobals)` inside the `InitFolderHandlerAsync` closure)
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithNonPredictorCarry_RunsTheExistingPathAndReleasesTheCarry | Expected model.CarriedFolderHandler to be because the carry must be released after the existing path has run, but found Mock.Object.
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.ReadPopOutCarry_WithConcreteItemController_ReturnsHandlerAndHelper | Expected carry.FolderHandler to refer to Mock.Object because the concrete controller's folder handler must be carried, but found .
+
+FAIL-BEFORE: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.ReadPopOutCarry_WithInterfaceOnlyController_ReturnsNullHandlerAndTheHelper | Expected carry.MailHelper to refer to Mock.Object because the interface helper must be carried, but found .
+
+## Pass-before controls (one line per passing test; fully qualified from the TRX)
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink
+
+PASS-BEFORE-CONTROL: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace
+
+PASS-BEFORE-CONTROL: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.ResolveUserDataFolder_CombinesLocalApplicationDataWithTheSharedLeafName
+
+PASS-BEFORE-CONTROL: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.CreateOptions_CarriesTheSharedArgumentsOnAFreshInstance
+
+PASS-BEFORE-CONTROL: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_WithNullFailure_Throws
+
+PASS-BEFORE-CONTROL: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyCoreInitialized_AfterAnEarlierStash_StillNavigatesIt
+
+PASS-BEFORE-CONTROL: QuickFiler.Test.Controllers.BreadcrumbOutboundQueueIssue792Tests.DiscardPending_OnAnEmptyQueue_ReturnsZero
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNullCarry_DoesNotAdopt
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNonPredictorHandler_DoesNotAdopt
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithExplicitListAndPredictor_DoesNotAdopt
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.ReadPopOutCarry_WithNullController_ReturnsNulls
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.PopOutHomeControllerFactory_DefaultIsTheNamedProductionFactory
+
+PASS-BEFORE-CONTROL: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController
+
+## Correspondence to the plan's predictions
+
+- Phase 1 tests (four failures, one control): identical outcomes and identical first assertions to [P1-T4], with one cosmetic difference. The scheduler test's actual lambda name is now `<.cctor>b__26_2` where [P1-T4] recorded `<.cctor>b__25_2`: the [P2-T12] declaration of `InvokeOnUiDispatcher` shifted the compiler-generated ordinal of the unchanged inline lambda. The default is still a lambda, so the assertion still discriminates.
+- [P3-T2] `NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner`: the plan predicts the `_navigated` assertion fails first, before either selection assertion is reached. Observed: `Expected _navigated to contain a single item ... but the collection is empty.` Matches.
+- [P3-T2] `NotifyInitializationFailed_LeavesNoStashForALaterInitialization`: the plan predicts the only navigation is the stale stash, which contains `Alpha`, so the count assertion passes and the content assertion fails. Observed: the `HaveCount(1)` assertion passed; the failing clause is `to contain "Folder list unavailable"` against an actual value that is the rendered folder document and contains `Alpha`. Matches, and it is the count-only trap the plan warns about: a count-only form would have passed on the unfixed tree.
+- [P3-T3] `DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending`: the stub returns 0 for three buffered payloads. Matches. `NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting`: two payloads remain pending. Matches.
+- [P3-T4] five tests: the plan predicts the seam is not consulted before the fix. Observed invocation counts of 0 against expected 3, 2 and 1; the label text is empty; the router navigated nothing. Matches on all five.
+- [P3-T5] `TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts`: the stub returns false. Matches. `InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry`: the plan allows either an assertion failure or the exception the unguarded construction path raises against null `Globals`; observed `NullReferenceException` from `FolderPredictor..ctor(IApplicationGlobals)` inside the `InitFolderHandlerAsync` closure, which is the second allowed outcome and is recorded as the fail-before. `InitFolderHandlerAsync_WithNonPredictorCarry_RunsTheExistingPathAndReleasesTheCarry`: the plan predicts the existing null-list path runs (a predictor is constructed over the mocked globals) and the carry is never released, so the release assertion fails. Observed: the `FolderHelper` not-null and not-same-as assertions passed and the release assertion failed with the carried mock still present. Matches; the carry is *not consulted* rather than declined, as the plan states.
+- [P3-T6] `ReadPopOutCarry_WithConcreteItemController_ReturnsHandlerAndHelper` and `ReadPopOutCarry_WithInterfaceOnlyController_ReturnsNullHandlerAndTheHelper`: the stub returns a null pair. Matches (the first fails on the handler, the second on the helper, each being that test's first discriminating assertion).
+- Thirteen controls: all passed, as declared.
+
+## Observed-failing map entries satisfied by this run
+
+- AC-U1: retry, label and router tests observed failing (`InitializeBreadcrumbHostAsync_*` five tests, `NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner`).
+- AC-U2: pending-cleared tests observed failing (`NotifyInitializationFailed_LeavesNoStashForALaterInitialization`, `NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner`).
+- AC-U3: adoption and carry-read tests observed failing (`TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts`, both `InitFolderHandlerAsync_*` tests, both `ReadPopOutCarry_With*Controller_*` tests); the UI-thread half was observed failing at [P1-T4] and again here.
+- AC-U7: queue tests observed failing (`DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending`, `NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting`).
+
+## Files created or edited in Phase 3 (line counts by `(Get-Content -LiteralPath ).Count`; every file UTF-8 without BOM, CRLF)
+
+- `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs`: 108 (ceiling 120)
+- `QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs`: 196 (ceiling 200; the first formatted draft measured 215 and was shortened by trimming doc comments and `because` strings only)
+- `QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs`: 113 (ceiling 150)
+- `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs`: 348 (ceiling 470; was 148 after Phase 1); contains no `DoNotParallelize` token and no `Thread.Sleep` or `Task.Delay` token (positive controls: the same searches hit `ViewerQueueStaticWrapperTests.cs` once and six lines elsewhere under `QuickFiler.Test`)
+- `QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs`: 175 (ceiling 230)
+- `QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs`: 213 (ceiling 260)
+- `QuickFiler.Test/QuickFiler.Test.csproj`: five bare self-closing `` items added (numstat `5 0` against HEAD `11f5aa598`), at lines 60 and 61 (after `BreadcrumbBridgeRouterQueueTests.Part2.cs`, line 59), 128 (after `EfcDataModelArchiveRootTests.cs`, line 127), 172 (after `QfcCollectionControllerTests.Part2.cs`, line 171) and 225 (after `WebView2BreadcrumbHostIssue792Tests.cs`, line 224); the plan's anchor citations 125 and 167 were authored before the Phase 1 and Phase 3 insertions above them and resolve to the same named items.
+
+All six `.cs` files were passed through `dotnet tool run csharpier format` (pinned 1.2.6) before the run; a second pass rewrote nothing.
+
+## Determinism note
+
+`InitializeBreadcrumbHostAsync_OnFinalFailure_ShowsTheErrorTextInTheFolderAreaLabel` constructs a real `System.Windows.Forms.Label` (required by the plan), which installs `WindowsFormsSynchronizationContext` on the test thread; the test clears that context immediately after construction so no continuation can be posted to an unpumped thread. No sleep, no pump, no `[DoNotParallelize]`; `scripts/vscode/TaskMaster.cli.runsettings` is unchanged.
+
+No production `.cs` file, no other `.csproj`, and no `.runsettings` file differs from HEAD after Phase 3.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t8-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t8-commit.md
new file mode 100644
index 000000000..6548f59c4
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p3-t8-commit.md
@@ -0,0 +1,32 @@
+# [P3-T8] Phase 3 commit
+
+- Issue: #792
+- Timestamp: 2026-09-17T19-52
+- Command: `git add -- QuickFiler.Test docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "test(792): seam-dependent regression tests recorded failing before the fix"` (run with `git -C ` against the item worktree on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim)
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 494f7138] test(792): seam-dependent regression tests recorded failing before the fix`; `11 files changed, 1204 insertions(+), 8 deletions(-)`; 5 test files created, 2 test-project files modified, 4 feature-folder paths (3 evidence files created, the plan file modified with the [P3-T1] through [P3-T7] check-offs).
+
+## Acceptance observations
+
+`git show --name-only --format= HEAD` listed 11 paths, all under `QuickFiler.Test/` or the feature folder:
+
+- Five new test files: `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs`, `QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs`, `BreadcrumbOutboundQueueIssue792Tests.cs`, `EfcDataModelIssue792CarryTests.cs`, `QfcCollectionControllerIssue792PopOutTests.cs`.
+- Two modified test-project files: `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs` (five tests and the scripted seam appended by [P3-T4]), `QuickFiler.Test/QuickFiler.Test.csproj` (five bare Compile items).
+- Four paths under the feature folder: `plan.2026-09-17T07-30.md`, `evidence/regression-testing/p3-t7-fail-before.md`, and the two Phase 2 residuals left uncommitted after [P2-T15] by construction (`evidence/other/p2-t14-independent-confirmation.md`, `evidence/qa-gates/p2-t15-commit.md`).
+- Nothing else.
+
+`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` printed nothing.
+
+`git status --porcelain --untracked-files=all` immediately after the commit listed only `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from the Phase 1 executor and outside the plan's add pathspecs.
+
+COMMIT-SHA-OBSERVED: 494f71381790c1f2f57531c0269eabe79890ad63
+
+PARENT-SHA: 11f5aa59816a73a0ee8bb5f6e9545b6b37962563 (the [P2-T15] commit)
+
+## Residual (recorded, not an acceptance clause)
+
+This artifact and the [P3-T8] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 3 (convention 9 treats docs and evidence as expected-dirty). No source path is dirty. The Phase 4 commit will sweep them, as this commit swept the Phase 2 residuals.
+
+Git printed four `LF will be replaced by CRLF` warnings for Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
+
+No production `.cs` file, no `QuickFiler/QuickFiler.csproj` change, and no `.runsettings` change is in this commit: Phase 3 touched the test project only.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t11-pass-after.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t11-pass-after.md
new file mode 100644
index 000000000..cd8625156
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t11-pass-after.md
@@ -0,0 +1,101 @@
+# [P4-T11] Green gate: analyzer build, nullable build, and the pass-after scoped run
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-10
+- Command: `dotnet tool run csharpier check .` (formatter gate, read-only); CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true` before each build); CMD-BUILD-ANALYZE (`msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true`); CMD-BUILD-NULLABLE (`msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true`); CMD-VSTEST (vswhere resolved `vstest.console.exe`); CMD-SCOPED-RUN `& $vstest QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:FullyQualifiedName~Issue792|FullyQualifiedName~WebView2EnvironmentContractTests|FullyQualifiedName~EfcFormControllerTests|FullyQualifiedName~EfcItemControllerTests|FullyQualifiedName~EfcDataModel|FullyQualifiedName~QfcCollectionControllerTests|FullyQualifiedName~ViewerQueueStaticWrapperTests|FullyQualifiedName~BreadcrumbBridgeRouterQueueTests|FullyQualifiedName~WebView2BreadcrumbHostTests|FullyQualifiedName~EfcHomeController|FullyQualifiedName~QfcItemController_InitializationTests" "/ResultsDirectory:coverage/test-results/p4-t11" "/Logger:trx;LogFileName=p4-t11.trx"` (`` = `p4-t11`); all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; consoles captured to the gitignored `coverage/p4-t11-csharpier-check.log`, `coverage/p4-t11-analyze.log`, `coverage/p4-t11-nullable.log`, `coverage/p4-t11-scoped.log`; TRX under the gitignored `coverage/test-results/p4-t11/`
+- EXIT_CODE: 0
+- Output Summary: formatter `Checked 1658 files`, exit 0; analyzer Rebuild exit 0, `0 Warning(s)`, exact line `0 Error(s)`, `Build succeeded.`; nullable Rebuild exit 0, `0 Warning(s)`, exact line `0 Error(s)`, `Build succeeded.`; scoped run `Test Run Successful.`, `Total tests: 234`, `Passed: 234`, `Failed: 0 (omitted category)`, `Skipped: 0 (omitted category)`, `Total time: 2.9408 Seconds`, exit 0; all 32 Issue792/contract tests passed (31 from [P3-T7] plus the [P4-T4] test), so the 18 tests recorded failing in [P3-T7] now pass and the 13 controls still pass.
+
+## Formatter gate
+
+`dotnet tool run csharpier check .` printed `Checked 1658 files in 4681ms.` and exited 0. Each Phase 4 file had been passed through `dotnet tool run csharpier format ` (pinned 1.2.6) as it was edited; the whole-tree check confirms no drift anywhere.
+
+## CMD-BUILD-ANALYZE (non-vacuity)
+
+Exit 0; `0 Warning(s)`; `0 Error(s)`; `Build succeeded.`; 63 `CoreCompile:` target lines (unanchored count, per the `/m` node-prefix note), 36 `csc.exe` lines of which 3 name the `QuickFiler` production project and 2 name `QuickFiler.Test`, 17 `csc.exe` lines carry `/analyzer:` switches; `QuickFiler/bin/Debug/QuickFiler.dll` rewritten 20:04:57 to 20:09:17 and `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` rewritten 20:04:58 to 20:09:20; no `error`/`warning` diagnostic line in the log; elapsed 15 s.
+
+## CMD-BUILD-NULLABLE (non-vacuity)
+
+Exit 0; `0 Warning(s)`; `0 Error(s)`; `Build succeeded.`; 66 `CoreCompile:` target lines, 36 `csc.exe` lines (3 `QuickFiler`, 2 `QuickFiler.Test`), 18 `csc.exe` lines carry `/warnaserror+`; `QuickFiler.dll` rewritten 20:09:17 to 20:09:54 and `QuickFiler.Test.dll` 20:09:20 to 20:09:57; no diagnostic line in the log; elapsed 15 s. No `/p:Nullable=enable` was passed.
+
+## Scoped run
+
+Console: `Test Run Successful.`; `Total tests: 234`; `Passed: 234`; no `Failed:` line and no `Skipped:` line (transcribed as `Failed: 0 (omitted category)`, `Skipped: 0 (omitted category)`); `Total time: 2.9408 Seconds`; exit 0. TRX counters: `total=234 executed=234 passed=234 failed=0`; 234 `UnitTestResult` rows, all `Passed`.
+
+TOTAL-EQUALS-PASSED: true
+
+`scripts/vscode/TaskMaster.cli.runsettings` is byte-identical to HEAD (`git status --porcelain` on that path prints nothing); the run used it with `/InIsolation`.
+
+### PASS-AFTER lines (one per Issue792/contract test; fully qualified from the TRX; 32 lines)
+
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithNonPredictorCarry_RunsTheExistingPathAndReleasesTheCarry
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithExplicitListAndPredictor_DoesNotAdopt
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNonPredictorHandler_DoesNotAdopt
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNullCarry_DoesNotAdopt
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_OnFinalFailure_NotifiesTheRouter
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_OnFinalFailure_ShowsTheErrorTextInTheFolderAreaLabel
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_WhenCanceled_DoesNotRetryOrReport
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser
+PASS-AFTER: QuickFiler.Controllers.Tests.EfcFormControllerIssue792Tests.PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink
+PASS-AFTER: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController
+PASS-AFTER: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.PopOutHomeControllerFactory_DefaultIsTheNamedProductionFactory
+PASS-AFTER: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.ReadPopOutCarry_WithConcreteItemController_ReturnsHandlerAndHelper
+PASS-AFTER: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.ReadPopOutCarry_WithInterfaceOnlyController_ReturnsNullHandlerAndTheHelper
+PASS-AFTER: QuickFiler.Controllers.Tests.QfcCollectionControllerIssue792PopOutTests.ReadPopOutCarry_WithNullController_ReturnsNulls
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyCoreInitialized_AfterAnEarlierStash_StillNavigatesIt
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_LeavesNoStashForALaterInitialization
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_WithNullFailure_Throws
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbOutboundQueueIssue792Tests.DiscardPending_OnAnEmptyQueue_ReturnsZero
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbOutboundQueueIssue792Tests.DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending
+PASS-AFTER: QuickFiler.Test.Controllers.BreadcrumbOutboundQueueIssue792Tests.NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting
+PASS-AFTER: QuickFiler.Test.HelperClasses.EfcViewerQueueIssue792Tests.ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke
+PASS-AFTER: QuickFiler.Test.Viewers.WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam
+PASS-AFTER: QuickFiler.Test.Viewers.WebView2BreadcrumbHostIssue792Tests.NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing
+PASS-AFTER: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace
+PASS-AFTER: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.CreateOptions_CarriesTheSharedArgumentsOnAFreshInstance
+PASS-AFTER: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam
+PASS-AFTER: QuickFiler.Test.Viewers.WebView2EnvironmentContractTests.ResolveUserDataFolder_CombinesLocalApplicationDataWithTheSharedLeafName
+
+ISSUE792-AND-CONTRACT-COUNT: 32 (declared 32)
+
+### Pass for the reason the fix supplies (no assertion weakened)
+
+`git diff --stat HEAD -- QuickFiler.Test` lists exactly one file, `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` (84 insertions, 0 deletions: the [P4-T4] test and its `SetPrivateField` helper). No test recorded failing in [P3-T7] was edited, so each passes on the clause it failed on:
+
+- `InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` (failed on `AdditionalBrowserArguments ... found `): the host now passes `WebView2EnvironmentContract.CreateOptions()` [P4-T1].
+- `NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing` (failed on `InvalidOperationException: The instance of CoreWebView2 is uninitialized`): the inline path now reads `CoreWebView2`, logs `document dropped.` and returns [P4-T1].
+- `NotifyInitializationFailed_LeavesNoStashForALaterInitialization` (failed on the CONTENT clause while `HaveCount(1)` already passed): the single navigation is now the banner document containing `Folder list unavailable` and not `Alpha`, and the stash is null so `NotifyCoreInitialized` replays nothing [P4-T6]; the test still asserts both count and content.
+- `NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner` (failed on `_navigated` empty): one banner navigation, selection cleared, subscriber notified with null [P4-T6].
+- `ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke` (failed on `<.cctor>b__26_2` versus `InvokeOnUiDispatcher`): the default is now the method group [P4-T10].
+- `DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending` (failed on `expected 3, found 0`) and `NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting` (failed on `PendingCount expected 0, found 2`): `DiscardPending` clears and reports the count [P4-T5]; the router calls it [P4-T6].
+- The five `InitializeBreadcrumbHostAsync_*` tests plus `InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser` (failed on invocation counts 0 against 3/2/1, empty label text, no router navigation, empty capture): the bounded loop over the seam, the `OperationCanceledException` stop, `ShowFolderAreaError`, `_router?.NotifyInitializationFailed` and the single `TryReportBoundaryFault` naming `after 3 attempts` [P4-T7].
+- `TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts` (failed on `False`), `InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry` (threw `NullReferenceException` from the predictor constructor), `InitFolderHandlerAsync_WithNonPredictorCarry_RunsTheExistingPathAndReleasesTheCarry` (failed on `CarriedFolderHandler` still holding the mock): adoption, `MailInfo ?? CarriedMailHelper`, and `ReleaseCarry()` on both branches [P4-T8].
+- `ReadPopOutCarry_WithConcreteItemController_ReturnsHandlerAndHelper` (failed on null handler) and `ReadPopOutCarry_WithInterfaceOnlyController_ReturnsNullHandlerAndTheHelper` (failed on null helper): the pattern-matched read [P4-T9].
+
+### Composition of the 234-test run (per class, from the TRX)
+
+EfcDataModelIssue792CarryTests 6; EfcDataModelTests 6; EfcFormControllerIssue792Tests 7; EfcFormControllerTests 32; EfcHomeControllerDependenciesTests 9; EfcHomeControllerDependenciesTestsProductionFactory 5; EfcHomeControllerExecuteMovesTests 7; EfcHomeControllerLifecycleTests 11; EfcHomeControllerMetricsTests 15; EfcHomeControllerSeamTests 4; EfcHomeControllerTests 6; EfcItemControllerTests 10; QfcCollectionControllerIssue792PopOutTests 5; QfcCollectionControllerTests 13; QfcItemController_InitializationTests 15; BreadcrumbBridgeRouterIssue792Tests 4; BreadcrumbBridgeRouterQueueTests 26; BreadcrumbOutboundQueueIssue792Tests 3; EfcDataModelArchiveRootTests 11; EfcDataModelIssue614Tests 8; EfcDataModelIssue637Tests 8; EfcViewerQueueIssue792Tests 1; ViewerQueueStaticWrapperTests 8; WebView2BreadcrumbHostIssue792Tests 2; WebView2BreadcrumbHostTests 8; WebView2EnvironmentContractTests 4. Every one of the eleven filter alternatives matched at least one class, so no alternative was silently empty.
+
+## Phase 4 file footprint (line counts by `(Get-Content -LiteralPath ).Count`; every file CRLF; BOM state preserved as at HEAD)
+
+- `QuickFiler/Viewers/WebView2BreadcrumbHost.cs`: 382 (ceiling 390); no BOM
+- `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs`: 474 (ceiling 476); BOM preserved; numstat 3/8 against BASE-SHA
+- `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs`: 56 (ceiling 90); no BOM
+- `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs`: 192 (ceiling 200); no BOM
+- `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs`: 80 (ceiling 90); no BOM
+- `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs`: 453 (ceiling 470); BOM preserved; numstat 46/0 against BASE-SHA and 32/0 against HEAD (deletions 0, `NotifyCoreInitialized` untouched at lines 320-329)
+- `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs`: 178 (ceiling 230); no BOM; `ConfigureBreadcrumbControl` byte-identical to its moved form (1059 characters at HEAD and now)
+- `QuickFiler/Controllers/EfcDataModel.Carry.cs`: 100 (ceiling 120); no BOM
+- `QuickFiler/Controllers/QfcCollectionController.PopOut.cs`: 111 (ceiling 140); no BOM
+- `QuickFiler/Helper Classes/EfcViewerQueue.cs`: 108 (ceiling 115); no BOM; numstat 4/4 against HEAD (the two scheduler lines and the two summary lines of `InvokeOnUiDispatcher`)
+
+## Deviations recorded for the caller (plan text versus the tree; no task text was changed)
+
+1. [P4-T3] `Select-String -SimpleMatch 'IncognitoArgument = WebView2EnvironmentContract.AdditionalBrowserArguments;'` returns 0: CSharpier breaks the 105-column declaration after `=`. Verified instead by `internal const string IncognitoArgument =` (1) immediately followed by `WebView2EnvironmentContract.AdditionalBrowserArguments;` (1); multiline regex match count 1. Detailed in `p4-t4-site3-mutation.md`.
+2. [P4-T4] `git diff --numstat HEAD -- QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` cannot read `0 0` before [P4-T12] because HEAD predates the [P4-T3] rewrite (observed `18 32`); restoration proven by SHA-256 identity and a no-index diff against the pre-mutation snapshot. Detailed in `p4-t4-site3-mutation.md`.
+3. [P4-T7] `Select-String -SimpleMatch 'catch (OperationCanceledException)'` returns 2, not 1: the moved `BindBreadcrumbRowsAsync` already carried one such catch at HEAD line 115 (positive control: HEAD count 1), and the retry loop adds the second. The plan's count omitted the pre-existing catch.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t4-site3-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t4-site3-mutation.md
new file mode 100644
index 000000000..02f8700c8
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-t4-site3-mutation.md
@@ -0,0 +1,53 @@
+# [P4-T4] Site-3 seam test authored after [P4-T3]; non-vacuity mutation observed
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-04
+- Command: CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true` before each build), then for each of the two runs CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST (vswhere resolved `vstest.console.exe`), then CMD-SCOPED-RUN with `` = `FullyQualifiedName~WebView2EnvironmentContractTests.EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam` and `` = `p4-t4` (unmutated) and `p4-t4-mutation` (mutated); all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; build and test consoles captured to the gitignored `coverage/p4-t4-build.log`, `coverage/p4-t4-scoped.log`, `coverage/p4-t4-mutation-build.log`, `coverage/p4-t4-mutation-scoped.log`; TRX under the gitignored `coverage/test-results/p4-t4/` and `coverage/test-results/p4-t4-mutation/`
+- EXIT_CODE: 0
+- Output Summary: unmutated run `Test Run Successful.`, `Total tests: 1`, `Passed: 1` (exit 0); mutated run `Test Run Failed.`, `Total tests: 1`, `Failed: 1` (exit 1) on the pre-predicted assertion; site-3 file restored byte-identical (SHA-256 equal before mutation and after restoration; `git diff --no-index --numstat` between the pre-mutation snapshot and the restored file prints nothing and exits 0).
+
+## Test authored (after [P4-T3]; never run against the direct-SDK body)
+
+`QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` now carries `EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam` (method name on a single line; `Select-String -SimpleMatch` count 1). The file is 192 lines (ceiling 200), UTF-8 without BOM, CRLF, `dotnet tool run csharpier check` exit 0.
+
+Arrangement: `new SynchronizationContext()` installed as `SynchronizationContext.Current` and restored in `finally`; `EfcItemController` and `ItemViewer` obtained through `FormatterServices.GetUninitializedObject`; the viewer's `_context` field set to the same context so `await _itemViewer.UiSyncContext` completes inline (`SynchronizationContextAwaiter.IsCompleted` returns true on reference equality, `UtilitiesCS/Threading/UiThread.cs:155-163`); `controller.WebViewInitializer` set to a `Mock` capturing the `CreateEnvironmentAsync` arguments and returning completed tasks. Assertions: captured folder equals `WebView2EnvironmentContract.ResolveUserDataFolder()`; captured `options` not null; `options.AdditionalBrowserArguments` equals `WebView2EnvironmentContract.AdditionalBrowserArguments`; `EnsureCoreWebView2Async(null, null)` verified `Times.Once` (the uninitialized viewer's control and the mocked environment are both null, so the exact-argument form pins the one awaited seam call).
+
+The direct-SDK body was replaced by [P4-T3] before this test was written, so no run of this test ever reached `CoreWebView2Environment.CreateAsync`; the only WebView2 SDK type the test constructs is none (the options object is produced by the code under test).
+
+## Unmutated run (`p4-t4`)
+
+Build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 19 `CoreCompile:` lines (unanchored count), 2 `csc.exe` lines both naming `QuickFiler.Test`; `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` rewritten 20:03:02 to 20:04:53 (the earlier 20:03:02 build was the first compile of the Phase 4 production changes plus the initial 206-line draft of this test, which also passed 1/1 before the draft was tightened to fit the ceiling).
+
+Run: `Passed EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam [161 ms]`; `Test Run Successful.`; `Total tests: 1`; `Passed: 1`; `Failed: 0 (omitted category)`; exit 0.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` the second argument of the `WebViewInitializer.CreateEnvironmentAsync(` call was changed from `options` to `new CoreWebView2EnvironmentOptions()` (needle matched exactly once; mutated line 48 read `new CoreWebView2EnvironmentOptions()`).
+
+PREDICTED-FAILING-ASSERTION: `actualArguments.Should().Be(expectedArguments, "the shared browser arguments")` - expected `"--incognito "`, found `` (a parameterless options object carries null `AdditionalBrowserArguments`); the folder assertion and the not-null assertion before it still pass, so this is the first assertion to fail.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 29 `CoreCompile:` lines, 10 `csc.exe` lines (2 naming `QuickFiler.Test`, 3 naming the `QuickFiler` production project); test dll rewritten 20:04:53 to 20:04:58.
+
+OBSERVED-FAILING-ASSERTION (first `Error Message` line, verbatim from the console): `Expected actualArguments to be "--incognito " because the shared browser arguments, but found .`
+
+Observed run: `Failed EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam [255 ms]`; `Test Run Failed.`; `Total tests: 1`; `Failed: 1`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true
+
+## Restoration proof
+
+- SITE3-SHA256-BEFORE-MUTATION: `9E887E98A48FC1DD5AF2043DD6D979864A3807E0020314C6420BC18419BC62E4`
+- SITE3-SHA256-AFTER-RESTORE: `9E887E98A48FC1DD5AF2043DD6D979864A3807E0020314C6420BC18419BC62E4`
+- RESTORED-IDENTICAL: true
+- `Select-String -SimpleMatch 'new CoreWebView2EnvironmentOptions()'` over the restored file: 0
+- `git diff --no-index --numstat coverage/p4-t4-site3-snapshot.cs QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` (snapshot = the bytes captured immediately before the mutation, i.e. the [P4-T3] state): prints nothing (identical files; git emits no numstat row for a zero-change pair), exit 0.
+
+DEVIATION (recorded, not a change to the plan): the task text asks for `git diff --numstat HEAD -- QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` showing `0 0` after restoration. At this point HEAD is the Phase 3 commit `494f71381`, which predates the [P4-T3] rewrite of this file, so that command necessarily reports the uncommitted [P4-T3] change: observed `18 32`. The clause is unsatisfiable by construction until [P4-T12] commits; the intended fact (the mutation left no residue) is proven above by the SHA-256 identity and the no-index diff against the pre-mutation snapshot.
+
+## Note on the [P4-T3] alias literal
+
+`Select-String -SimpleMatch 'IncognitoArgument = WebView2EnvironmentContract.AdditionalBrowserArguments;'` returns 0 in the site-3 file because the declaration is 105 columns at its 8-space indent and CSharpier 1.2.6 breaks it after `=` (`dotnet tool run csharpier check` exits 0 on that two-line shape, so it is the formatter's own output). The delivered form is verified by `internal const string IncognitoArgument =` (1 hit) immediately followed by `WebView2EnvironmentContract.AdditionalBrowserArguments;` (1 hit); a multiline regex `IncognitoArgument =\s+WebView2EnvironmentContract\.AdditionalBrowserArguments;` over the raw text matches once. Every other [P4-T3] clause passed as written (`CoreWebView2Environment.CreateAsync(` 0, `ContinueWith(` 0, `WebViewInitializer.CreateEnvironmentAsync(` 1, `WebViewInitializer.EnsureCoreWebView2Async(` 1, `"WindowsFormsWebView2"` 0, `using System.IO;` absent, 56 lines; positive controls at HEAD for the four zero-gates: 1, 1, 1, 1).
+
+## Line-ending and encoding note
+
+`QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` and `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` carry a UTF-8 BOM at HEAD (the other eight Phase 4 targets do not). A normalisation pass in [P4-T2] briefly stripped the ViewerSetup BOM (numstat read 4/9 with a line-1 hunk); it was restored before the task was accepted (numstat 3/8 against BASE-SHA, the only hunk being lines 55-62). No later step rewrites whole files, so the router's BOM is untouched.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t1-ac-u4-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t1-ac-u4-mutation.md
new file mode 100644
index 000000000..2557a2c4d
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t1-ac-u4-mutation.md
@@ -0,0 +1,36 @@
+# [P5-T1] AC-U4 non-vacuity mutation: notifier call dropped from the default boundary sink
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-21
+- Command: CMD-OUTLOOK (`Get-Process -Name OUTLOOK`, printed `OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST (vswhere resolved `vstest.console.exe`), CMD-SCOPED-RUN with `` = `FullyQualifiedName~EfcFormControllerIssue792Tests.PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink|FullyQualifiedName~EfcFormControllerTests.PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault` and `` = `p5-t1-mutation` (mutated) and `p5-t1-restored` (restored); restoration by `git checkout -- QuickFiler/Controllers/EfcFormController.cs`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory (branch asserted by the helper); build and test consoles in the gitignored `coverage/p5-t1-mutation-build.log`, `coverage/p5-t1-mutation-scoped.log`, `coverage/p5-t1-restore-build.log`, `coverage/p5-t1-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t1-mutation/` and `coverage/test-results/p5-t1-restored/`
+- EXIT_CODE: 0
+- Output Summary: mutated run `Test Run Failed.`, `Total tests: 2`, `Passed: 1`, `Failed: 1` (exit 1): the new default-sink test failed on the pre-predicted `ContainSingle` assertion and the pre-existing sink-substituting test PASSED; restored run `Test Run Successful.`, `Total tests: 2`, `Passed: 2` (exit 0); file restored byte-identical (SHA-256 equal before mutation and after restoration), BOM preserved, `git diff --numstat HEAD -- QuickFiler/Controllers/EfcFormController.cs` prints nothing.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Controllers/EfcFormController.cs` the statement line `UserFaultNotifier?.Invoke(message);` (line 140, inside `DefaultBoundaryErrorSink` at lines 137-141, re-derived before the edit) was deleted. Needle matched exactly once before the edit and zero times after; the file went from 266 to 265 lines; `git diff --numstat HEAD` on the mutated file read `0 1` and the only hunk was `- UserFaultNotifier?.Invoke(message);`. The file carries a UTF-8 BOM at HEAD; the BOM was present before the edit, after the edit and after restoration (`BOM-BEFORE-MUTATION: True`, `BOM-AFTER-MUTATION: True`, `BOM-AFTER-RESTORE: True`).
+
+PREDICTED-FAILING-ASSERTION: `EfcFormControllerIssue792Tests.PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink` fails on `captured.Should().ContainSingle("the default boundary sink must surface the contained fault to the user exactly once")` (`EfcFormControllerIssue792Tests.cs:101-106`): expected one captured notification, actual none (the `NotThrowAsync` assertion before it still passes because the fault is still contained by the sink's logger call). `EfcFormControllerTests.PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault` (`EfcFormControllerTests.cs:299-328`) PASSES because it substitutes `BoundaryErrorSink` with a counting lambda, so the default sink's body never runs for it.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 21 `CoreCompile:` lines (unanchored count), 10 `csc.exe` lines; `QuickFiler/bin/Debug/QuickFiler.dll` rewritten at 20:21:59 and `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` at 20:22:01, both after the 20:21:56 edit (the helper's first invocation compiled the mutation and then stopped on a helper-side reporting defect before the test run; the second invocation's build was incremental, 18 `CoreCompile:` lines, 0 `csc.exe`, DLL mtimes unchanged, and ran the tests against those mutated assemblies).
+
+OBSERVED (first `Error Message` line, verbatim from the console): `Expected captured to contain a single item because the default boundary sink must surface the contained fault to the user exactly once, but the collection is empty.`
+
+Observed run: `Passed PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault [51 ms]`; `Failed PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink [144 ms]`; `Test Run Failed.`; `Total tests: 2`; `Passed: 1`; `Failed: 1`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true (new test red on the notifier-count assertion; pre-existing test green under the same mutation, which is the recorded proof that the pre-existing test alone could not pin the user surface).
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `0B122F9A1ABB9C20C252612A4F616456ADCBEBF27E3603CBFCC2F7EA68316320` (also the SHA-256 of the pre-mutation snapshot `coverage/p5-t1-snapshot.cs`, gitignored)
+- SHA256-AFTER-RESTORE: `0B122F9A1ABB9C20C252612A4F616456ADCBEBF27E3603CBFCC2F7EA68316320`
+- RESTORED-IDENTICAL: true
+- BOM-AFTER-RESTORE: true
+- Needle count after restore: 1
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/EfcFormController.cs` prints nothing
+- `git diff --no-index --numstat` between the pre-mutation snapshot and the restored file: exit 0 (identical)
+- Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) after restoration: prints nothing
+
+Restored build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 25 `CoreCompile:` lines, 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:21:59 to 20:23:02, test DLL 20:22:01 to 20:23:05.
+
+Restored run: `Passed PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault [66 ms]`; `Passed PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink [72 ms]`; `Test Run Successful.`; `Total tests: 2`; `Passed: 2`; `Failed: 0 (omitted category)`; exit 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t2-ac-u6-site1-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t2-ac-u6-site1-mutation.md
new file mode 100644
index 000000000..2f5e70b14
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t2-ac-u6-site1-mutation.md
@@ -0,0 +1,76 @@
+# [P5-T2] AC-U6 non-vacuity mutations: site 1 (seam test plus structural gate) and site 2 (structural gate)
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-23
+- Command: site 1: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` and `` = `p5-t2-mutation` / `p5-t2-restored`, then CMD-AC-U6-GATE; restoration by `git checkout -- QuickFiler/Viewers/WebView2BreadcrumbHost.cs`. Site 2 (with site 1 restored): the ViewerSetup edit, CMD-AC-U6-GATE, `git checkout -- QuickFiler/Controllers/QfcItemController.ViewerSetup.cs`, CMD-AC-U6-GATE again. All run from `coverage/plan792-helper.ps1` (the gate block embedded verbatim) with the item worktree as the working directory; consoles in the gitignored `coverage/p5-t2-mutation-build.log`, `coverage/p5-t2-mutation-scoped.log`, `coverage/p5-t2-restore-build.log`, `coverage/p5-t2-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t2-mutation/` and `coverage/test-results/p5-t2-restored/`
+- EXIT_CODE: 0
+- Output Summary: site 1 mutated: `Test Run Failed.`, `Total tests: 1`, `Failed: 1` (exit 1) on the pre-predicted `AdditionalBrowserArguments` assertion (found ``), gate `PRIMARY-CONSTRUCTION-COUNT: 2`, `AC-U6-STRUCTURAL: FAIL`; site 1 restored: `Test Run Successful.`, `Total tests: 1`, `Passed: 1` (exit 0), gate 1/0/3/3 `PASS`. Site 2 mutated: gate `PRIMARY-CONSTRUCTION-COUNT: 2`, `CONTRACT-READER-COUNT: 2`, `AC-U6-STRUCTURAL: FAIL`; site 2 restored: gate 1/0/3/3 `PASS`. Both files restored byte-identical (SHA-256 equal before mutation and after restoration), BOM state preserved (host: none; ViewerSetup: BOM present throughout), `git diff --numstat HEAD` prints nothing for both.
+
+## Site 1 (`QuickFiler/Viewers/WebView2BreadcrumbHost.cs`)
+
+MUTATION: line 264 (re-derived before the edit; the plan's premise table cites the pre-fix line 250) `CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();` became `CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions();`. Needle matched once before and zero after; replacement present once; 382 lines before and after; `git diff --numstat HEAD` read `1 1`. The file carries no BOM at HEAD (`BOM-BEFORE-MUTATION: False`, `BOM-AFTER-MUTATION: False`, `BOM-AFTER-RESTORE: False`).
+
+PREDICTED-FAILING-ASSERTION: `WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` fails on `capturedOptions.AdditionalBrowserArguments.Should().Be("--incognito ", ...)` (`WebView2BreadcrumbHostIssue792Tests.cs:93-98`): expected `"--incognito "`, actual `` (a parameterless options object carries null arguments); the folder assertion (`:82-87`) and the not-null assertion (`:88-92`) before it still pass. Structural gate predicted `PRIMARY-CONSTRUCTION-COUNT: 2` and `AC-U6-STRUCTURAL: FAIL`.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 27 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:23:02 to 20:23:57, test DLL 20:23:05 to 20:24:00.
+
+OBSERVED (first `Error Message` line, verbatim): `Expected capturedOptions.AdditionalBrowserArguments to be "--incognito " because every WebView2 site must share the same incognito browser argument, but found .`
+
+Observed run: `Failed InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam [305 ms]`; `Test Run Failed.`; `Total tests: 1`; `Failed: 1`; exit 1.
+
+Observed gate (mutated):
+
+```
+PRIMARY-CONSTRUCTION-COUNT: 2
+PRIMARY-SITE: QuickFiler/Viewers/WebView2BreadcrumbHost.cs:264
+PRIMARY-SITE: QuickFiler/Viewers/WebView2EnvironmentContract.cs:50
+CREATEASYNC-OUTSIDE-ADAPTER: 0
+SEAM-CALLER-COUNT: 3
+CONTRACT-READER-COUNT: 2
+AC-U6-STRUCTURAL: FAIL
+```
+
+PREDICTION-MATCHES-OBSERVATION: true (test and gate).
+
+Restoration proof (site 1):
+
+- SHA256-BEFORE-MUTATION: `BD6E5F07AC709BF8C274045C5AC0508E6447A0E686657F742DD0195134BDF0C0` (equal to the gitignored snapshot `coverage/p5-t2-snapshot.cs`)
+- SHA256-AFTER-RESTORE: `BD6E5F07AC709BF8C274045C5AC0508E6447A0E686657F742DD0195134BDF0C0`
+- RESTORED-IDENTICAL: true; needle count after restore 1, replacement count 0
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Viewers/WebView2BreadcrumbHost.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+
+Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 27 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:23:57 to 20:24:16, test DLL 20:24:00 to 20:24:17. Restored run: `Passed InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam [209 ms]`; `Test Run Successful.`; `Total tests: 1`; `Passed: 1`; `Failed: 0 (omitted category)`; exit 0. Restored gate: `PRIMARY-CONSTRUCTION-COUNT: 1` (`QuickFiler/Viewers/WebView2EnvironmentContract.cs:50`), `CREATEASYNC-OUTSIDE-ADAPTER: 0`, `SEAM-CALLER-COUNT: 3` (`EfcItemController.WebViewEnvironment.cs:46`, `QfcItemController.ViewerSetup.cs:66`, `WebView2BreadcrumbHost.cs:279`), `CONTRACT-READER-COUNT: 3` (`EfcItemController.WebViewEnvironment.cs:40`, `QfcItemController.ViewerSetup.cs:57`, `WebView2BreadcrumbHost.cs:264`), `AC-U6-STRUCTURAL: PASS`.
+
+## Site 2 (`QuickFiler/Controllers/QfcItemController.ViewerSetup.cs`), applied with site 1 restored
+
+This half is the site-2 proof cited by [P7-T14]. Per the task text it is gate-only: no build and no test run were performed on the site-2 mutation.
+
+MUTATION: line 57 (re-derived; the plan's premise table cites the pre-fix line 62) `CoreWebView2EnvironmentOptions options = WebView2EnvironmentContract.CreateOptions();` became `CoreWebView2EnvironmentOptions options = new("--incognito ");`. Needle matched once before and zero after; replacement present once; 474 lines before and after; `git diff --numstat HEAD` read `1 1`. The file carries a UTF-8 BOM at HEAD and the BOM was present before the edit, after the edit and after restoration (`True`, `True`, `True`); the edit was written through a BOM-preserving encoder, so the [P4-T2] strip-and-restore incident did not recur.
+
+PREDICTED: `PRIMARY-CONSTRUCTION-COUNT: 2`, `CONTRACT-READER-COUNT: 2`, `AC-U6-STRUCTURAL: FAIL` (the target-typed `new(` form is caught by the gate's second construction pattern `CoreWebView2EnvironmentOptions\s+\w+\s*=\s*new\s*\(`).
+
+OBSERVED gate (mutated):
+
+```
+PRIMARY-CONSTRUCTION-COUNT: 2
+PRIMARY-SITE: QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:57
+PRIMARY-SITE: QuickFiler/Viewers/WebView2EnvironmentContract.cs:50
+CREATEASYNC-OUTSIDE-ADAPTER: 0
+SEAM-CALLER-COUNT: 3
+CONTRACT-READER-COUNT: 2
+CONTRACT-READER: QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs:40
+CONTRACT-READER: QuickFiler/Viewers/WebView2BreadcrumbHost.cs:264
+AC-U6-STRUCTURAL: FAIL
+```
+
+PREDICTION-MATCHES-OBSERVATION: true.
+
+Restoration proof (site 2):
+
+- SHA256-BEFORE-MUTATION: `AAD50304873955794E69DFE7957B8550D1F1AAF733ACFC37E7A3ABFC4A6F2D1D` (equal to the gitignored snapshot `coverage/p5-t2-site2-snapshot.cs`)
+- SHA256-AFTER-RESTORE: `AAD50304873955794E69DFE7957B8550D1F1AAF733ACFC37E7A3ABFC4A6F2D1D`
+- RESTORED-IDENTICAL: true; BOM-AFTER-RESTORE: true; needle count after restore 1, replacement count 0
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+- Restored gate: `PRIMARY-CONSTRUCTION-COUNT: 1`, `CREATEASYNC-OUTSIDE-ADAPTER: 0`, `SEAM-CALLER-COUNT: 3`, `CONTRACT-READER-COUNT: 3`, `AC-U6-STRUCTURAL: PASS`
+
+Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) after each restoration: prints nothing.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t3-ac-u6-constant-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t3-ac-u6-constant-mutation.md
new file mode 100644
index 000000000..0537be876
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t3-ac-u6-constant-mutation.md
@@ -0,0 +1,43 @@
+# [P5-T3] AC-U6 non-vacuity mutation: shared constant loses its trailing space
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-25
+- Command: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~WebView2EnvironmentContractTests|FullyQualifiedName~EfcItemControllerTests.IncognitoArgument_IsAsciiDoubleHyphenIncognitoWithTrailingSpace|FullyQualifiedName~WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` and `` = `p5-t3-mutation` / `p5-t3-restored`; restoration by `git checkout -- QuickFiler/Viewers/WebView2EnvironmentContract.cs`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; consoles in the gitignored `coverage/p5-t3-mutation-build.log`, `coverage/p5-t3-mutation-scoped.log`, `coverage/p5-t3-restore-build.log`, `coverage/p5-t3-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t3-mutation/` and `coverage/test-results/p5-t3-restored/`
+- EXIT_CODE: 0
+- Output Summary: mutated run `Test Run Failed.`, `Total tests: 6`, `Passed: 3`, `Failed: 3` (exit 1): the three pre-predicted tests failed on their string-equality assertions and the three pre-predicted contract-relative tests passed; restored run `Test Run Successful.`, `Total tests: 6`, `Passed: 6` (exit 0); file restored byte-identical (SHA-256 equal before mutation and after restoration), no BOM at HEAD and none introduced, `git diff --numstat HEAD -- QuickFiler/Viewers/WebView2EnvironmentContract.cs` prints nothing.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Viewers/WebView2EnvironmentContract.cs` line 24 (re-derived before the edit) `internal const string AdditionalBrowserArguments = "--incognito ";` became `internal const string AdditionalBrowserArguments = "--incognito";` (trailing space removed). Needle matched once before and zero after; replacement present once; 53 lines before and after; `git diff --numstat HEAD` read `1 1`. `BOM-BEFORE-MUTATION: False`, `BOM-AFTER-MUTATION: False`, `BOM-AFTER-RESTORE: False`.
+
+PREDICTED-FAILING-ASSERTION (three tests, each on its first string-equality assertion):
+
+- `WebView2EnvironmentContractTests.AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace` on `actual.Should().Be(expected, ...)` (`WebView2EnvironmentContractTests.cs:43-48`): expected `"--incognito "`, actual `"--incognito"`.
+- `EfcItemControllerTests.IncognitoArgument_IsAsciiDoubleHyphenIncognitoWithTrailingSpace` on `actual.Should().Be(expected, ...)` (`EfcItemControllerTests.cs:381-386`): the alias `EfcItemController.IncognitoArgument = WebView2EnvironmentContract.AdditionalBrowserArguments` carries the mutation, expected `"--incognito "`, actual `"--incognito"`.
+- `WebView2BreadcrumbHostIssue792Tests.InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam` on `capturedOptions.AdditionalBrowserArguments.Should().Be("--incognito ", ...)` (`WebView2BreadcrumbHostIssue792Tests.cs:93-98`): actual `"--incognito"`.
+
+PREDICTED PASSING (asserting relative to the contract, so they move with it): `ResolveUserDataFolder_CombinesLocalApplicationDataWithTheSharedLeafName`, `CreateOptions_CarriesTheSharedArgumentsOnAFreshInstance` (`:101-112`, compares to `WebView2EnvironmentContract.AdditionalBrowserArguments`), `EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam` (`:180`, compares to the contract value).
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 26 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:24:16 to 20:25:33, test DLL 20:24:17 to 20:25:35.
+
+OBSERVED (first `Error Message` line of each failed test, verbatim):
+
+- `IncognitoArgument_IsAsciiDoubleHyphenIncognitoWithTrailingSpace`: `Expected actual to be "--incognito " because Chromium command-line switches are introduced by two ASCII hyphen-minus characters, but it misses some extra whitespace at the end.`
+- `AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace`: `Expected actual to be "--incognito " because Chromium command-line switches are introduced by two ASCII hyphen-minus characters, but it misses some extra whitespace at the end.`
+- `InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam`: `Expected capturedOptions.AdditionalBrowserArguments to be "--incognito " because every WebView2 site must share the same incognito browser argument, but it misses some extra whitespace at the end.`
+
+Observed run: `Failed IncognitoArgument_IsAsciiDoubleHyphenIncognitoWithTrailingSpace [148 ms]`; `Failed AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace [146 ms]`; `Passed ResolveUserDataFolder_CombinesLocalApplicationDataWithTheSharedLeafName [< 1 ms]`; `Passed CreateOptions_CarriesTheSharedArgumentsOnAFreshInstance [1 ms]`; `Passed EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam [30 ms]`; `Failed InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam [199 ms]`; `Test Run Failed.`; `Total tests: 6`; `Passed: 3`; `Failed: 3`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true (all three predicted failures on the predicted assertions, expressed by FluentAssertions as "misses some extra whitespace at the end", which is its rendering of expected `"--incognito "` versus actual `"--incognito"`; all three predicted passes observed passing).
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `14EFB6386CF4F25B5AAC28C1081212CEE25C6E0987DBE69DE695F4ECA0ED55FB` (equal to the gitignored snapshot `coverage/p5-t3-snapshot.cs`)
+- SHA256-AFTER-RESTORE: `14EFB6386CF4F25B5AAC28C1081212CEE25C6E0987DBE69DE695F4ECA0ED55FB`
+- RESTORED-IDENTICAL: true; needle count after restore 1, replacement count 0
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Viewers/WebView2EnvironmentContract.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+- Scoped porcelain after restoration: prints nothing
+
+Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 26 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:25:33 to 20:25:50, test DLL 20:25:35 to 20:25:52.
+
+Restored run: all six `Passed`; `Test Run Successful.`; `Total tests: 6`; `Passed: 6`; `Failed: 0 (omitted category)`; exit 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t4-ac-u7-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t4-ac-u7-mutation.md
new file mode 100644
index 000000000..6421dbfa7
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t4-ac-u7-mutation.md
@@ -0,0 +1,33 @@
+# [P5-T4] AC-U7 non-vacuity mutation: outbound-queue discard skipped in the router failure path
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-26
+- Command: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~BreadcrumbOutboundQueueIssue792Tests.NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting` and `` = `p5-t4-mutation` / `p5-t4-restored`; restoration by `git checkout -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; consoles in the gitignored `coverage/p5-t4-mutation-build.log`, `coverage/p5-t4-mutation-scoped.log`, `coverage/p5-t4-restore-build.log`, `coverage/p5-t4-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t4-mutation/` and `coverage/test-results/p5-t4-restored/`
+- EXIT_CODE: 0
+- Output Summary: mutated run `Test Run Failed.`, `Total tests: 1`, `Failed: 1` (exit 1) on the pre-predicted `PendingCount` assertion (expected 0, found 2); restored run `Test Run Successful.`, `Total tests: 1`, `Passed: 1` (exit 0); file restored byte-identical (SHA-256 equal before mutation and after restoration), UTF-8 BOM present at HEAD and preserved through the edit and the restoration, `git diff --numstat HEAD -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` prints nothing.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` line 355 (re-derived before the edit; inside `NotifyInitializationFailed` at lines 346-376) `int discardedPayloads = _outboundQueue.DiscardPending();` became `int discardedPayloads = 0;`. Needle matched once before and zero after; replacement present once; 453 lines before and after; `git diff --numstat HEAD` read `1 1`. The file carries a UTF-8 BOM at HEAD: `BOM-BEFORE-MUTATION: True`, `BOM-AFTER-MUTATION: True`, `BOM-AFTER-RESTORE: True`.
+
+PREDICTED-FAILING-ASSERTION: `BreadcrumbOutboundQueueIssue792Tests.NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting` fails on `queue.PendingCount.Should().Be(0, "a failed initialization must discard the buffered payloads")` (`BreadcrumbOutboundQueueIssue792Tests.cs:103-105`): expected 0, actual 2 (the two payloads buffered at `:95-97` are never discarded). The arrange-time `PendingCount.Should().Be(2)` at `:97` still passes.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 26 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:25:50 to 20:26:40, test DLL 20:25:52 to 20:26:42.
+
+OBSERVED (first `Error Message` line, verbatim): `Expected queue.PendingCount to be 0 because a failed initialization must discard the buffered payloads, but found 2 (difference of 2).`
+
+Observed run: `Failed NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting [249 ms]`; `Test Run Failed.`; `Total tests: 1`; `Failed: 1`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true.
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `B5EF211E5A37889A2DBF8B50CB6099A21E6DF2C1CEDEE52BDC2A822DEB786F2B` (equal to the gitignored snapshot `coverage/p5-t4-snapshot.cs`)
+- SHA256-AFTER-RESTORE: `B5EF211E5A37889A2DBF8B50CB6099A21E6DF2C1CEDEE52BDC2A822DEB786F2B`
+- RESTORED-IDENTICAL: true; BOM-AFTER-RESTORE: true; needle count after restore 1, replacement count 0
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+- Scoped porcelain after restoration: prints nothing
+
+Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 25 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:26:40 to 20:26:57, test DLL 20:26:42 to 20:26:59.
+
+Restored run: `Passed NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting [175 ms]`; `Test Run Successful.`; `Total tests: 1`; `Passed: 1`; `Failed: 0 (omitted category)`; exit 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t5-ac-u1-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t5-ac-u1-mutation.md
new file mode 100644
index 000000000..57c522067
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t5-ac-u1-mutation.md
@@ -0,0 +1,77 @@
+# [P5-T5] AC-U1 non-vacuity: two mutations of the bounded breadcrumb retry (attempt limit; per-attempt reporting)
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-39
+- Command: for each mutation (A then B), from `coverage/plan792-helper.ps1` with the item worktree as the working directory: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), mutate `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs`, CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce|FullyQualifiedName~EfcFormControllerIssue792Tests.InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing` and `` = `p5-t5-a` (A) / `p5-t5-b` (B); restore with `git checkout -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs`, CMD-BUILD-PLAIN, re-run the same filter with `` = `p5-t5-a-restored` / `p5-t5-b-restored`. Consoles in the gitignored `coverage/p5-t5-a-mutation-build.log`, `coverage/p5-t5-a-scoped.log`, `coverage/p5-t5-a-restore-build.log`, `coverage/p5-t5-a-restored-scoped.log` and the same four with `p5-t5-b`; TRX under the gitignored `coverage/test-results/p5-t5-a/`, `coverage/test-results/p5-t5-a-restored/`, `coverage/test-results/p5-t5-b/`, `coverage/test-results/p5-t5-b-restored/`.
+- EXIT_CODE: 0
+- Output Summary: both mutations discriminated on their pre-predicted assertions. Mutation A (limit 3 to 1): `Total tests: 2`, `Failed: 2` (exit 1), `RetriesUpToTheAttemptLimitThenReportsOnce` on `Invocations to be 3 ... but found 1`, `SucceedsOnALaterAttempt_ReportsNothing` on `Invocations to be 2 ... but found 1`; the `:244` notification assertion is unreachable under A. Mutation B (per-attempt report in the general catch, limit 3): `Total tests: 2`, `Failed: 2` (exit 1), `SucceedsOnALaterAttempt_ReportsNothing` on `captured ... to be empty ... {"boom"}` at `:244` with its two earlier assertions passing, and the sibling on `to contain a single item` (four captured, expected). Both mutated builds printed `0 Error(s)`. After each restoration `Test Run Successful.`, `Total tests: 2`, `Passed: 2` (exit 0); SHA-256 equal before mutation and after each restoration, no BOM at HEAD and none introduced, `git diff --numstat HEAD -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` prints nothing.
+
+## Pre-state (re-derived before mutation A)
+
+- `git diff --numstat HEAD -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` prints nothing (scoped porcelain over `*.cs`, `*.csproj`, `*.sln`, `packages.config` empty at HEAD `c2a55b235`), so no `PRE-STATE: restored` step was needed.
+- Line citations re-derived on disk: `internal const int BreadcrumbInitializationAttemptLimit = 3;` is line 29; `catch (System.Exception ex)` opens at line 84 and closes at line 92; `lastFailure = ex;` is line 86; the final `TryReportBoundaryFault(...)` call spans lines 97-100. `TryReportBoundaryFault` is `private void` in the same partial class at `QuickFiler/Controllers/EfcFormController.cs:150`, and its default sink (`:137-141`) invokes `UserFaultNotifier` with the message, which the tests capture through `CaptureUserFaults` (`EfcFormControllerIssue792Tests.cs:54-57`).
+- Test assertion order re-derived in `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs`: `InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce` asserts `NotThrowAsync` (`:204`), then `Invocations.Should().Be(3, ...)` (`:205-210`), then `captured.Should().ContainSingle(...)` (`:211-218`). `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing` asserts `NotThrowAsync` (`:240`), then `Invocations.Should().Be(2, ...)` (`:241-243`), then `captured.Should().BeEmpty(...)` (`:244`). Its scripted initializer (`:231`) throws `InvalidOperationException("boom")` on the first call and succeeds on the second.
+- SHA256-BEFORE-MUTATION: `9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C` (`Get-FileHash -Algorithm SHA256`)
+- BOM-BEFORE-MUTATION: False (first three bytes are not `EF BB BF`)
+
+## Mutation A: attempt limit 3 to 1
+
+MUTATION-A: in `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` line 29, `internal const int BreadcrumbInitializationAttemptLimit = 3;` becomes `internal const int BreadcrumbInitializationAttemptLimit = 1;`.
+
+PREDICTED-FAILING-ASSERTION-A (written before the mutated run):
+
+- `InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce` fails on `initializer.Invocations.Should().Be(3, ...)` (`:205-210`): the loop makes one call, so the `OBSERVED:` line contains `Invocations to be 3` and `but found 1`.
+- `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing` fails on `initializer.Invocations.Should().Be(2, ...)` (`:241-243`): the loop makes one call (which fails) and never reaches the scripted success, so the `OBSERVED:` line contains `Invocations to be 2` and `but found 1`.
+- `Total tests: 2`, `Failed: 2`, `Test Run Failed.`, exit 1.
+
+Under mutation A the notification assertion `captured.Should().BeEmpty(...)` at `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs:244` is downstream of the `Be(2)` assertion at `:241-243`, which fails first and ends the test, so mutation A does not prove that assertion. Mutation B exists to prove it.
+
+Mutated build A (20:40): exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 26 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:28:02 to 20:40:33, test DLL 20:28:04 to 20:40:35. Needle matched once before and zero after the edit; replacement present once; 178 lines before and after; `git diff --numstat HEAD` read `1 1`; the hunk was the single line 29 change. `BOM-AFTER-MUTATION-A: False`.
+
+OBSERVED-A (first `Error Message` line of each failed test, verbatim; run id `p5-t5-a`):
+
+- `InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce`: `Expected initializer.Invocations to be 3 because the host initializer must be attempted exactly the limit of three times, but found 1.`
+- `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing`: `Expected initializer.Invocations to be 2 because the loop must stop on the first successful attempt, but found 1.`
+
+Observed run A: `Failed InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce [164 ms]`; `Failed InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing [2 ms]`; `Test Run Failed.`; `Total tests: 2`; `Failed: 2`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION-A: true (both tests, on the predicted invocation-count assertions).
+
+Restore A: `git checkout -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` exit 0; `SHA256-AFTER-RESTORE-A: 9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C` (equal to `SHA256-BEFORE-MUTATION`); `BOM-AFTER-RESTORE-A: False`; needle count 1, replacement count 0; `RESTORED: git diff --numstat HEAD -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0. Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 26 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:40:33 to 20:40:52, test DLL 20:40:35 to 20:40:54. Restored run (`p5-t5-a-restored`): `Passed InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce [75 ms]`; `Passed InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing [4 ms]`; `Test Run Successful.`; `Total tests: 2`; `Passed: 2`; `Failed: 0 (omitted category)`; exit 0. Scoped porcelain after restoration: prints nothing.
+
+## Mutation B: per-attempt report inside the general catch (limit restored to 3)
+
+MUTATION-B: in `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs`, inside the `catch (System.Exception ex)` block of `InitializeBreadcrumbHostAsync` (`:84-92`), the single statement `TryReportBoundaryFault(ex.Message, ex);` is inserted on its own line immediately after `lastFailure = ex;` (`:86`), so every failed attempt reports through the boundary sink instead of only the final failure at `:97-100`. Applied only after mutation A was restored byte-identically (limit is 3).
+
+PREDICTED-FAILING-ASSERTION-B (written before the mutated run):
+
+- `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing` fails on `captured.Should().BeEmpty("a recovered initialization must not be reported")` (`:244`): the first attempt throws `boom` and now reports `boom` through the default sink into `captured`; the second attempt succeeds and returns before the final report, so `Invocations` is 2 and `:240` and `:241-243` pass. FluentAssertions outside an assertion scope raises on the first failing assertion, so an `OBSERVED:` line naming `captured` proves the two earlier assertions passed. The `OBSERVED:` line contains `to be empty` and `boom`.
+- `InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce` fails on `captured.Should().ContainSingle(...)` (`:211-218`): three per-attempt reports plus the final `after 3 attempts` report give four captured notifications; its `Invocations.Should().Be(3)` passed. The `OBSERVED:` line contains `to contain a single item`. Recorded as expected, not as the load-bearing proof.
+- `Total tests: 2`, `Failed: 2`, `Test Run Failed.`, exit 1.
+- The mutated build prints the exact `0 Error(s)` line (the inserted call targets a private member of the same partial class, `EfcFormController.cs:150`); a compile error is a HALT, not a prediction miss.
+
+Mutated build B (20:41): exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 27 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:40:52 to 20:41:26, test DLL 20:40:54 to 20:41:29. The needle `lastFailure = ex;` (plus CRLF) matched once before the edit and the inserted line was present once after; 178 lines before, 179 after; `git diff --numstat HEAD` read `1 0`; the hunk was the single added line `TryReportBoundaryFault(ex.Message, ex);` at line 87 (after `lastFailure = ex;` at line 86). `BOM-AFTER-MUTATION-B: False`.
+
+OBSERVED-B (first `Error Message` line of each failed test, verbatim; run id `p5-t5-b`):
+
+- `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing`: `Expected captured to be empty because a recovered initialization must not be reported, but found at least one item {"boom"}.`
+- `InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce`: `Expected captured to contain a single item because the exhausted limit must be reported to the user exactly once, but found {"boom", "boom", "boom", "Breadcrumb WebView2 initialization failed after 3 attempts: boom"}.`
+
+Observed run B: `Failed InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce [169 ms]`; `Failed InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing [4 ms]`; `Test Run Failed.`; `Total tests: 2`; `Failed: 2`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION-B: true. The load-bearing test failed on `captured` at `:244` (`to be empty`, `boom`), so `:240` and `:241-243` passed and the recovered-initialization-is-not-reported property is now proven non-vacuous by a mutation. The sibling test failed on `to contain a single item` with four captured notifications (three per-attempt `boom` plus the final `after 3 attempts` report), its `Invocations` assertion of 3 having passed; this is recorded as expected and is not the load-bearing proof.
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C` (recorded before mutation A; re-read identical before mutation B; equal to the gitignored snapshots `coverage/p5-t5-a-snapshot.cs` and `coverage/p5-t5-b-snapshot.cs`)
+- SHA256-AFTER-RESTORE-A: `9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C`
+- SHA256-AFTER-RESTORE-B: `9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C`
+- BOM-BEFORE-MUTATION: False; BOM-AFTER-MUTATION-A: False; BOM-AFTER-RESTORE-A: False; BOM-AFTER-MUTATION-B: False; BOM-AFTER-RESTORE-B: False (all equal; BOM state preserved through both mutations)
+- RESTORED-IDENTICAL: true after A and after B; needle counts after each restore 1, replacement counts 0
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` prints nothing after A and after B; `git diff --no-index --numstat` snapshot vs restored file exit 0 both times
+
+Restore B: `git checkout -- QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` exit 0. Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 25 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:41:26 to 20:41:46, test DLL 20:41:29 to 20:41:49. Restored run (`p5-t5-b-restored`): `Passed InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce [62 ms]`; `Passed InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing [3 ms]`; `Test Run Successful.`; `Total tests: 2`; `Passed: 2`; `Failed: 0 (omitted category)`; exit 0. Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) after restoration: prints nothing.
+
+## Prior halted run (2026-09-17T20-27; satisfies no clause of the rewritten task)
+
+The prior run applied mutation A alone under the earlier task text, which predicted the second test would fail on the notification assertion. It observed `Expected initializer.Invocations to be 2 because the loop must stop on the first successful attempt, but found 1.` for `InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing` and `Expected initializer.Invocations to be 3 because the host initializer must be attempted exactly the limit of three times, but found 1.` for `InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce` (`Total tests: 2`, `Failed: 2`, exit 1), halted because the second test failed on a different assertion than predicted, and restored the file byte-identically (`SHA256 9002A324317539335AA10A33360678662D7C8869B167CBC932DA2A9E19D2F84C` before and after, no BOM, `git diff --numstat HEAD` printing nothing; restored run `Total tests: 2`, `Passed: 2`, exit 0). No test, assertion or prediction was edited.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t6-ac-u3-deposit-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t6-ac-u3-deposit-mutation.md
new file mode 100644
index 000000000..dde090eae
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t6-ac-u3-deposit-mutation.md
@@ -0,0 +1,35 @@
+# [P5-T6] AC-U3 non-vacuity mutation: pop-out carry deposit removed from the EfcHomeController constructor
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-43
+- Command: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~QfcCollectionControllerIssue792PopOutTests.EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController` and `` = `p5-t6-mutation` / `p5-t6-restored`; restoration by `git checkout -- QuickFiler/Controllers/EfcHomeController.cs`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; consoles in the gitignored `coverage/p5-t6-mutation-build.log`, `coverage/p5-t6-mutation-scoped.log`, `coverage/p5-t6-restore-build.log`, `coverage/p5-t6-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t6-mutation/` and `coverage/test-results/p5-t6-restored/`
+- EXIT_CODE: 0
+- Output Summary: mutated run `Test Run Failed.`, `Total tests: 1`, `Failed: 1` (exit 1) on the pre-predicted captured-handler reference assertion (`but found `); restored run `Test Run Successful.`, `Total tests: 1`, `Passed: 1` (exit 0); file restored byte-identical (SHA-256 equal before mutation and after restoration), UTF-8 BOM present at HEAD and preserved through the edit and the restoration, `git diff --numstat HEAD -- QuickFiler/Controllers/EfcHomeController.cs` prints nothing.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Controllers/EfcHomeController.cs` lines 87-88 (re-derived before the edit; inside the constructor, after the `DataModelFactory` call at `:77-82` and before the `DataModel.Mail is not null` branch at `:90`) the two statements `DataModel.CarriedFolderHandler = carriedFolderHandler;` and `DataModel.CarriedMailHelper = carriedMailHelper;` are deleted. The file carries a UTF-8 BOM at HEAD.
+
+PREDICTED-FAILING-ASSERTION (written before the mutated run): `QfcCollectionControllerIssue792PopOutTests.EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController` fails on `capturedHandler.Should().BeSameAs(handler, "the carried handler must be on the data model at factory time")` (`QfcCollectionControllerIssue792PopOutTests.cs:202-204`): the form-controller factory (`:171-185`) is still invoked, so the preceding `formFactoryCalled.Should().BeTrue(...)` (`:199-201`) passes, but the factory reads `dataModel.CarriedFolderHandler` (`:182`) from a data model that was never deposited into, so `capturedHandler` is null and the reference assertion reports a null actual. FluentAssertions raises on the first failing assertion, so the `capturedHelper` (`:205-207`) and persisted-deposit (`:208-210`) assertions are not reached.
+
+Needle (the two lines plus their CRLF terminators) matched once before and zero after; 464 lines before, 462 after; `git diff --numstat HEAD` read `0 2`; the hunk was the deletion of lines 87-88 only. `BOM-BEFORE-MUTATION: True`, `BOM-AFTER-MUTATION: True`, `BOM-AFTER-RESTORE: True`.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 26 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:41:46 to 20:43:10, test DLL 20:41:49 to 20:43:12.
+
+OBSERVED (first `Error Message` line, verbatim): `Expected capturedHandler to refer to Mock.Object because the carried handler must be on the data model at factory time, but found .`
+
+Observed run: `Failed EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController [292 ms]`; `Test Run Failed.`; `Total tests: 1`; `Failed: 1`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true (captured-handler reference assertion at `:202-204`, actual null; the `formFactoryCalled` assertion passed).
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `20FC90DB68FB1CA5199311B2494AD1FB33EF43FEDDB2764BB72359BEF14D64DE` (equal to the gitignored snapshot `coverage/p5-t6-snapshot.cs`)
+- SHA256-AFTER-RESTORE: `20FC90DB68FB1CA5199311B2494AD1FB33EF43FEDDB2764BB72359BEF14D64DE`
+- RESTORED-IDENTICAL: true; BOM-AFTER-RESTORE: true; needle count after restore 1
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/EfcHomeController.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+- Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) after restoration: prints nothing
+
+Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 23 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:43:10 to 20:43:29, test DLL 20:43:12 to 20:43:32.
+
+Restored run: `Passed EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController [250 ms]`; `Test Run Successful.`; `Total tests: 1`; `Passed: 1`; `Failed: 0 (omitted category)`; exit 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t7-ac-u2-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t7-ac-u2-mutation.md
new file mode 100644
index 000000000..f8828e921
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t7-ac-u2-mutation.md
@@ -0,0 +1,35 @@
+# [P5-T7] AC-U2 non-vacuity mutation: stash discard removed from the router failure path
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-44
+- Command: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_LeavesNoStashForALaterInitialization` and `` = `p5-t7-mutation` / `p5-t7-restored`; restoration by `git checkout -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; consoles in the gitignored `coverage/p5-t7-mutation-build.log`, `coverage/p5-t7-mutation-scoped.log`, `coverage/p5-t7-restore-build.log`, `coverage/p5-t7-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t7-mutation/` and `coverage/test-results/p5-t7-restored/`
+- EXIT_CODE: 0
+- Output Summary: mutated run `Test Run Failed.`, `Total tests: 1`, `Failed: 1` (exit 1) on the pre-predicted `_navigated` count assertion (expected 1, found 2: banner then the replayed stale stash); restored run `Test Run Successful.`, `Total tests: 1`, `Passed: 1` (exit 0); file restored byte-identical (SHA-256 equal before mutation and after restoration), UTF-8 BOM present at HEAD and preserved through the edit and the restoration, `git diff --numstat HEAD -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` prints nothing.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` line 354 (re-derived before the edit; inside `NotifyInitializationFailed` at lines 346-375, immediately after `bool hadPendingDocument = _pendingDocument != null;` at `:353`) the statement `_pendingDocument = null;` is deleted. The edit is anchored on the `:353` line so the sibling `_pendingDocument = null;` inside `NotifyCoreInitialized` (`:325`) is untouched. The file carries a UTF-8 BOM at HEAD.
+
+PREDICTED-FAILING-ASSERTION (written before the mutated run): `BreadcrumbBridgeRouterIssue792Tests.NotifyInitializationFailed_LeavesNoStashForALaterInitialization` fails on `_navigated.Should().HaveCount(1, "only the error banner may be navigated")` (`BreadcrumbBridgeRouterIssue792Tests.cs:156`): expected 1, actual 2. The bound document is stashed in the router while the host reports uninitialized (`:147`); the failure call navigates the banner directly through `_host.NavigateToString` (`BreadcrumbBridgeRouter.cs:368`, first navigation); under the mutation the stash survives, so the later `NotifyCoreInitialized` (`:153`, host now initialized) replays it (`BreadcrumbBridgeRouter.cs:322-326`, second navigation). FluentAssertions raises on the first failing assertion, so the content assertions at `:157-160` are not reached.
+
+Needle (the `:353` line plus `_pendingDocument = null;`, each with its CRLF terminator) matched once before and zero after; the `:353` anchor line is present once after the edit; 453 lines before, 452 after; `git diff --numstat HEAD` read `0 1`; the hunk was the deletion of line 354 only (`NotifyCoreInitialized` at `:320-329` untouched). `BOM-BEFORE-MUTATION: True`, `BOM-AFTER-MUTATION: True`, `BOM-AFTER-RESTORE: True`.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 25 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:43:29 to 20:44:43, test DLL 20:43:32 to 20:44:45.
+
+OBSERVED (first `Error Message` line, verbatim up to the item dump): `Expected _navigated to contain 1 item(s) because only the error banner may be navigated, but found 2: {"...` The two dumped documents are, in order, the banner document (its row reads `==== Folder list unavailable: breadcrumb initialization failed`) and the replayed stale folder document (its row carries the `Inbox` and `Alpha` segments), which is the stash that the restored code discards.
+
+Observed run: `Failed NotifyInitializationFailed_LeavesNoStashForALaterInitialization [401 ms]`; `Test Run Failed.`; `Total tests: 1`; `Failed: 1`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true (`_navigated` count at `:156`, expected 1, actual 2, the second navigation being the stale stash replayed by the later `NotifyCoreInitialized`).
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `B5EF211E5A37889A2DBF8B50CB6099A21E6DF2C1CEDEE52BDC2A822DEB786F2B` (equal to the gitignored snapshot `coverage/p5-t7-snapshot.cs`, and equal to the [P5-T4] pre-mutation hash of the same file)
+- SHA256-AFTER-RESTORE: `B5EF211E5A37889A2DBF8B50CB6099A21E6DF2C1CEDEE52BDC2A822DEB786F2B`
+- RESTORED-IDENTICAL: true; BOM-AFTER-RESTORE: true; needle count after restore 1
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+- Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) after restoration: prints nothing
+
+Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 21 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:44:43 to 20:45:02, test DLL 20:44:45 to 20:45:05.
+
+Restored run: `Passed NotifyInitializationFailed_LeavesNoStashForALaterInitialization [303 ms]`; `Test Run Successful.`; `Total tests: 1`; `Passed: 1`; `Failed: 0 (omitted category)`; exit 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t8-ac-u3-adoption-mutation.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t8-ac-u3-adoption-mutation.md
new file mode 100644
index 000000000..ec347f3df
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t8-ac-u3-adoption-mutation.md
@@ -0,0 +1,42 @@
+# [P5-T8] AC-U3 non-vacuity mutation: carried-predictor adoption always refused
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-45
+- Command: CMD-OUTLOOK (`OUTLOOK-CLOSED: true` before each build), then for the mutated tree and again for the restored tree: CMD-BUILD-PLAIN (`msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`), CMD-VSTEST, CMD-SCOPED-RUN with `` = `FullyQualifiedName~EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts|FullyQualifiedName~EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry` and `` = `p5-t8-mutation` / `p5-t8-restored`; restoration by `git checkout -- QuickFiler/Controllers/EfcDataModel.Carry.cs`; all run from `coverage/plan792-helper.ps1` with the item worktree as the working directory; consoles in the gitignored `coverage/p5-t8-mutation-build.log`, `coverage/p5-t8-mutation-scoped.log`, `coverage/p5-t8-restore-build.log`, `coverage/p5-t8-restored-scoped.log`; TRX under the gitignored `coverage/test-results/p5-t8-mutation/` and `coverage/test-results/p5-t8-restored/`
+- EXIT_CODE: 0
+- Output Summary: mutated run `Test Run Failed.`, `Total tests: 2`, `Failed: 2` (exit 1): the pure adoption test on the pre-predicted boolean (`adopts to be True ... but found False`) and the `InitFolderHandlerAsync` test on the pre-predicted unguarded construction path exception (`System.NullReferenceException` from `FolderPredictor.cs:39` via `EfcDataModel.Carry.cs:62`); restored run `Test Run Successful.`, `Total tests: 2`, `Passed: 2` (exit 0); file restored byte-identical (SHA-256 equal before mutation and after restoration), no BOM at HEAD and none introduced, `git diff --numstat HEAD -- QuickFiler/Controllers/EfcDataModel.Carry.cs` prints nothing.
+
+## Mutation (temporary; restored)
+
+MUTATION: in `QuickFiler/Controllers/EfcDataModel.Carry.cs` line 34 (re-derived before the edit; inside `TryAdoptCarriedFolderHandler` at lines 25-39, in the adopting branch `adopted = predictor; return true;` at `:33-34`) `return true;` becomes `return false;`, so the method always returns false (the `:38` branch already returns false). The `out` assignment at `:33` is left in place so the change is confined to the boolean.
+
+PREDICTED-FAILING-ASSERTION (written before the mutated run):
+
+- `EfcDataModelIssue792CarryTests.TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts` fails on `adopts.Should().BeTrue("a concrete predictor with no explicit list must be adopted")` (`EfcDataModelIssue792CarryTests.cs:60`): the `OBSERVED:` line contains `adopts to be true` and `but found False`. The `adopted.Should().BeSameAs(carried)` assertion at `:61` is not reached.
+- `EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry` fails on the unguarded construction path's exception rather than on an assertion: with adoption refused, `InitFolderHandlerAsync` (`EfcDataModel.Carry.cs:41-91`) falls into the null-list branch, `scoringInput` is null (the uninitialized model has neither `MailInfo` nor `CarriedMailHelper`), and `new FolderPredictor(Globals)` (`:62`) runs with a null `Globals`, so `FolderPredictor.cs:39` (`_olApp = AppGlobals.Ol.App;`) throws `NullReferenceException` inside `Task.Run`, which the `await` at `:135` of the test rethrows before `model.FolderHelper.Should().BeSameAs(carried)` (`:138`) is reached. The `OBSERVED:` line therefore names `System.NullReferenceException`. Had construction succeeded instead, the failure would land on the `:138` `BeSameAs` assertion (a fresh predictor is not the carried instance); the plan accepts either outcome, and this artifact records which one occurred.
+- `Total tests: 2`, `Failed: 2`, `Test Run Failed.`, exit 1.
+
+Needle (`adopted = predictor;` plus `return true;`, each with its CRLF terminator) matched once before and zero after; replacement present once; 100 lines before and after; `git diff --numstat HEAD` read `1 1`; the hunk was the single line 34 change. `BOM-BEFORE-MUTATION: False`, `BOM-AFTER-MUTATION: False`, `BOM-AFTER-RESTORE: False`.
+
+Mutated build: exit 0, `0 Warning(s)`, exact line `0 Error(s)`; 28 `CoreCompile:` lines (unanchored), 10 `csc.exe` lines (1 producing `QuickFiler.dll`, 1 producing `QuickFiler.Test.dll`); production DLL rewritten 20:45:02 to 20:46:28, test DLL 20:45:05 to 20:46:31.
+
+OBSERVED (first `Error Message` line of each failed test, verbatim):
+
+- `TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts`: `Expected adopts to be True because a concrete predictor with no explicit list must be adopted, but found False.`
+- `InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry`: `Test method QuickFiler.Controllers.Tests.EfcDataModelIssue792CarryTests.InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry threw exception:` followed by `System.NullReferenceException: Object reference not set to an instance of an object.` The stack trace in the gitignored `coverage/p5-t8-mutation-scoped.log` names `UtilitiesCS.FolderPredictor..ctor(IApplicationGlobals AppGlobals)` at `FolderPredictor.cs:line 39`, invoked from the `InitFolderHandlerAsync` lambda at `EfcDataModel.Carry.cs:line 62`, rethrown by the test's `await` at `EfcDataModelIssue792CarryTests.cs:line 135`.
+
+Observed run: `Failed TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts [147 ms]`; `Failed InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry [11 ms]`; `Test Run Failed.`; `Total tests: 2`; `Failed: 2`; exit 1.
+
+PREDICTION-MATCHES-OBSERVATION: true (the first on the boolean at `:60`; the second on the unguarded construction path's `NullReferenceException` from `FolderPredictor.cs:39` via `EfcDataModel.Carry.cs:62`, the exception outcome named as primary in the prediction above; the `:138` `BeSameAs` was not reached).
+
+## Restoration proof
+
+- SHA256-BEFORE-MUTATION: `C0E4085C52DEE82C074BE3EEC0375D7ADB6761E43AF75B90302A823C670B44DB` (equal to the gitignored snapshot `coverage/p5-t8-snapshot.cs`)
+- SHA256-AFTER-RESTORE: `C0E4085C52DEE82C074BE3EEC0375D7ADB6761E43AF75B90302A823C670B44DB`
+- RESTORED-IDENTICAL: true; BOM-AFTER-RESTORE: false (no BOM at HEAD, none introduced); needle count after restore 1, replacement count 0
+- RESTORED: `git diff --numstat HEAD -- QuickFiler/Controllers/EfcDataModel.Carry.cs` prints nothing; `git diff --no-index --numstat` snapshot vs restored file exit 0
+- Scoped porcelain (`git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'`) after restoration: prints nothing
+
+Restored build: exit 0, `0 Warning(s)`, `0 Error(s)`; 25 `CoreCompile:`, 10 `csc.exe` (1 + 1); production DLL 20:46:28 to 20:46:49, test DLL 20:46:31 to 20:46:51.
+
+Restored run: `Passed TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts [49 ms]`; `Passed InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry [1 ms]`; `Test Run Successful.`; `Total tests: 2`; `Passed: 2`; `Failed: 0 (omitted category)`; exit 0.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t9-commit.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t9-commit.md
new file mode 100644
index 000000000..6b9485fbd
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t9-commit.md
@@ -0,0 +1,44 @@
+# [P5-T9] Phase 5 commit: non-vacuity mutation evidence
+
+- Issue: #792
+- Timestamp: 2026-09-17T20-47
+- Command: `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` (tree-restored check), then `git add -- docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "test(792): non-vacuity mutation evidence"` (run with `git -C - ` on branch `bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`; the session's attribution trailer lines were supplied through a second `-m`, so the subject line is the plan's text verbatim), then `git show --name-only --format= HEAD`
+- EXIT_CODE: 0
+- Output Summary: `[bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792 9ac987a9] test(792): non-vacuity mutation evidence`; `10 files changed, 466 insertions(+), 10 deletions(-)`; 9 evidence files created and the plan file modified; scoped porcelain printed nothing before the commit; every committed path is under the feature folder.
+
+SOURCE-PORCELAIN: empty
+
+COMMIT-SHA-OBSERVED: 9ac987a969d1f4786d296fee25817c8e5dde9233
+
+PARENT-SHA: c2a55b23523636e9f4d47b169d95bf8b596085c9 (the [P4-T12] commit)
+
+## Paths in the commit (`git show --name-only --format= HEAD`, 10 paths, verbatim)
+
+```
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p4-t12-commit.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t1-ac-u4-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t2-ac-u6-site1-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t3-ac-u6-constant-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t4-ac-u7-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t5-ac-u1-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t6-ac-u3-deposit-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t7-ac-u2-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p5-t8-ac-u3-adoption-mutation.md
+docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-17T07-30.md
+```
+
+Every path starts with `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/`; no source, project, solution or configuration path is in the commit. The `p4-t12-commit.md` artifact is the Phase 4 residual left uncommitted by construction after [P4-T12], swept here as that commit swept the Phase 3 residual.
+
+## Acceptance observations
+
+- `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` printed nothing (all five Phase 5 source files, `EfcFormController.cs`, `WebView2BreadcrumbHost.cs`, `QfcItemController.ViewerSetup.cs`, `WebView2EnvironmentContract.cs`, `BreadcrumbBridgeRouter.cs`, `EfcFormController.Breadcrumb.cs`, `EfcHomeController.cs` and `EfcDataModel.Carry.cs`, were restored byte-identically per their task artifacts).
+- Commit exit code 0.
+- `git show --name-only --format= HEAD` lists feature-folder paths only (10 of 10).
+
+## Residual (recorded, not an acceptance clause)
+
+`git status --porcelain --untracked-files=all` immediately after the commit listed only `.claude/agent-memory/atomic-executor/MEMORY.md` (modified) and `.claude/agent-memory/atomic-executor/project_pwsh_param_name_case_collision_flattens_log_array.md` (untracked), both inherited from an earlier executor and outside the plan's add pathspecs; they were deliberately left uncommitted.
+
+This artifact and the [P5-T9] check-off in the plan file are written after the commit they describe, so they remain uncommitted feature-folder changes at the end of Phase 5 (convention 9 treats docs and evidence as expected-dirty). No source path is dirty. The next feature-folder commit will sweep them.
+
+Git printed ten `LF will be replaced by CRLF` warnings for Markdown files; this is the repository's autocrlf normalisation notice and does not affect the committed content.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/issue.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/issue.md
new file mode 100644
index 000000000..935506df7
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/issue.md
@@ -0,0 +1,114 @@
+# breadcrumb-webview2-init-fails-resource-not-in-correct-state (Issue #792)
+
+- Date captured: 2026-09-06
+- Author: Dan Moisan
+- Status: Promoted -> docs/features/active/breadcrumb-webview2-init-fails-resource-not-in-correct-state/ (Issue #792)
+
+> Automation note: Keep the section headings below unchanged; the promotion tooling maps each of them into the GitHub bug issue template.
+
+- Issue: #792
+- Issue URL: https://github.com/drmoisan/TaskMaster/issues/792
+- Last Updated: 2026-09-06
+- Work Mode: full-bug
+
+## Summary
+
+The breadcrumb `CoreWebView2` initialization fails intermittently with HRESULT 0x8007139F ("The group or resource is not in the correct state to perform the requested operation"), logged by both `WebView2BreadcrumbHost` and `EfcFormController`. The failure is logged and swallowed; the session continues with a breadcrumb host that never initialized, and a later `BreadcrumbUiDispatcher` dispatch fails in the same session. Because the #677 keyboard-lock mechanism is WebView2 focus retention, a half-initialized WebView2 is a plausible contributor to the sporadic keyboard lock, but that link is unconfirmed.
+
+## Environment
+
+- OS/version: Windows 11 Pro 10.0.26200
+- Python version: n/a (C# / .NET Framework 4.8 VSTO add-in)
+- Command/flags used: QuickFiler launched from the ribbon (High Confidence button); add-in loaded from `TaskMaster\bin\Debug` built 2026-09-06 08:51 from `7c8ac9ae`
+- Data source or fixture: live Outlook Inbox view
+
+## Steps to Reproduce
+
+1. Launch QuickFiler from the ribbon several times in one Outlook session.
+2. Inspect `TaskMaster\bin\Debug\logs\debug_
.log` for `Breadcrumb CoreWebView2 initialization failed`.
+3. Observe that the failure occurs on some launches (2 of 6 today: 08:55:22 and 10:06:51) and not others.
+
+Not reproducible on demand.
+
+## Expected Behavior
+
+WebView2 initialization either succeeds, or fails with a clear surfaced error and a defined fallback state that cannot retain keyboard focus. A failed initialization should be retried or the host disposed, not left half-constructed.
+
+## Actual Behavior
+
+Two ERROR lines per occurrence (`WebView2BreadcrumbHost - Breadcrumb CoreWebView2 initialization failed: ... (HRESULT: 0x8007139F)` and `EfcFormController - Breadcrumb WebView2 initialization failed: ...`), then normal operation continues. A `BreadcrumbUiDispatcher - Breadcrumb UI dispatch failed.` error followed at 09:01:56 in the same session.
+
+## Logs / Screenshots
+
+- [x] Attached minimal logs or screenshot
+- Snippet (`debug_2026-09-06.log`):
+
+```
+2026-09-06 08:55:22,227 [VSTA_Main] ERROR QuickFiler.Viewers.WebView2BreadcrumbHost - Breadcrumb CoreWebView2 initialization failed: ... (HRESULT: 0x8007139F)
+2026-09-06 08:55:22,286 [VSTA_Main] ERROR QuickFiler.Controllers.EfcFormController - Breadcrumb WebView2 initialization failed: ... (HRESULT: 0x8007139F)
+2026-09-06 09:01:56,237 [VSTA_Main] ERROR QuickFiler.Viewers.BreadcrumbUiDispatcher - Breadcrumb UI dispatch failed.
+2026-09-06 10:06:51,594 [VSTA_Main] ERROR QuickFiler.Viewers.WebView2BreadcrumbHost - Breadcrumb CoreWebView2 initialization failed: ... (HRESULT: 0x8007139F)
+2026-09-06 10:06:51,661 [VSTA_Main] ERROR QuickFiler.Controllers.EfcFormController - Breadcrumb WebView2 initialization failed: ... (HRESULT: 0x8007139F)
+```
+
+## Impact / Severity
+
+- [ ] Blocker
+- [x] High
+- [ ] Medium
+- [ ] Low
+
+High (raised 2026-09-06, see Update below; originally Medium): the breadcrumb folder selector is unavailable on affected launches, and the half-initialized control is a candidate contributor to the sporadic Outlook keyboard lock tracked under the sibling QuickFiler Cancel-teardown issue filed the same day.
+
+## Suspected Cause / Notes
+
+- 0x8007139F (`ERROR_INVALID_STATE`) from `CoreWebView2Environment`/`EnsureCoreWebView2Async` typically indicates the control was initialized while its handle or parent was not yet in a valid state, or a second initialization was attempted against a control already mid-initialization or disposed. Both `WebView2BreadcrumbHost` and `EfcFormController` log the same failure, suggesting the initialization is attempted from two paths.
+- Files to inspect: `QuickFiler/Viewers/WebView2BreadcrumbHost.cs`, `QuickFiler/Controllers/EfcFormController.cs` (breadcrumb initialization), `QuickFiler/Viewers/BreadcrumbUiDispatcher.cs`, and the pooled-viewer handler-retention history in `docs/features/potential/promoted/2026-08-07-webview2breadcrumbhost-handler-retention-pooled-viewer.md`.
+- Related: #677 (keyboard hook leak; WebView2 focus retention mechanism), the sibling potential entry `2026-09-06-quickfiler-high-confidence-cancel-teardown-and-deadline-defects.md`.
+
+## Proposed Fix / Validation Ideas
+
+- [ ] Unit coverage areas: initialization state machine of `WebView2BreadcrumbHost` (single initialization, guard against re-entry, disposed-host guard, failure leaves a defined non-focusable state).
+- [ ] Integration scenario to retest: repeated QuickFiler launches in one session; confirm no `0x8007139F` and that a failed initialization cannot retain focus.
+- [ ] Manual verification notes: live-Outlook log review across several launches.
+
+## Next Step
+
+- [x] Promote to GitHub issue (bug-report template)
+- [ ] Move to active fix folder / branch
+
+## Update 2026-09-06: reproduces on every Efc open via pop-out and Sort Email; severity raised to High
+
+Two user-visible symptoms reported today are this failure:
+
+1. **Pop-out from a QfcItem to an EfcItem shows an empty folder list.** No suggestions, no banners, and typing a search string does nothing.
+2. **Ribbon -> Sort Email opens an EfcViewer whose "Matched Folders:" section has no entries.** The label is a static WinForms label above the breadcrumb WebView2, which is why it survives while the list is blank.
+
+### Log evidence
+
+`TaskMaster\bin\Debug\logs\debug_2026-09-06.log` records the paired `WebView2BreadcrumbHost` / `EfcFormController` initialization failure with HRESULT 0x8007139F on every Efc open in the session: ten pop-out opens between 17:39:00 and 17:41:42, three at 19:04-19:06, and the Sort Email open at 19:56:36 (the `SortEmail_Click` stack at 19:56:36,171 is followed by the failure at 19:56:37,940). Today the failure is deterministic on the Efc entry points, not intermittent as originally recorded.
+
+```
+2026-09-06 19:56:37,940 [VSTA_Main] ERROR QuickFiler.Viewers.WebView2BreadcrumbHost - Breadcrumb CoreWebView2 initialization failed: The group or resource is not in the correct state to perform the requested operation. (Exception from HRESULT: 0x8007139F)
+2026-09-06 19:56:38,004 [VSTA_Main] ERROR QuickFiler.Controllers.EfcFormController - Breadcrumb WebView2 initialization failed: The group or resource is not in the correct state to perform the requested operation. (Exception from HRESULT: 0x8007139F)
+```
+
+### Why the list is blank rather than degraded
+
+- `BreadcrumbBridgeRouter.DeliverDocument` (`QuickFiler\Controllers\BreadcrumbBridgeRouter.Selection.cs:168-180`) stashes the rendered document in `_pendingDocument` when `_host.IsCoreInitialized` is false. `WebView2BreadcrumbHost` (`:330-342`) returns on `!e.IsSuccess` without ever raising `CoreInitialized`, so the pending document is never navigated. There is no fallback rendering and no retry.
+- `EfcFormController.InitializeBreadcrumbHostAsync` (`:1071-1081`) and `PopulateFolderCombobox` (`:1250-1271`) are fire-and-forget tasks with total catch blocks, so the failure is log-only.
+- `EfcFormController.BindBreadcrumbRowsAsync` (`:1115-1118`) reads `_globals.Ol.ArchiveRootPath` unguarded; `TryGetArchiveRoot` (`EfcDataModel.cs:280-297`) is not used on the bind path.
+
+### Additional latent defect on the pop-out path
+
+`QfcCollectionController.PopOutControlGroup` (`QuickFiler\Controllers\QfcCollectionController.cs:710-735`) hands only the raw `MailItem` and `_globals` to `new EfcHomeController(...)` via the synchronous constructor, so the Efc view rebuilds prediction from scratch with an unloaded `MailItemHelper` (`EfcDataModel.cs:48-81` vs `CreateAsync` `:89-142`). The in-QuickFiler carry pattern from #678 (`QfcItemController.FolderHandling.cs:68-83`, `_carriedFolderHandler`) is not applied to the pop-out. `EfcViewerQueue.BuildQueue` has no production call site, so `EfcViewer` is always constructed inline on the calling thread and captures `SynchronizationContext.Current` as-is (`EfcViewer.cs:23-30`); if the pop-out continuation lands off the UI thread, `UiThread.SynchronizationContextAwaiter` throws on the null context (`UiThread.cs:91-98`) inside the same swallowed tasks.
+
+### Additional acceptance criteria (settled with the maintainer 2026-09-06)
+
+- [ ] AC-U1: A failed `CoreWebView2` initialization is retried, and on final failure the Efc view shows a visible error state in the folder area instead of a blank list.
+- [ ] AC-U2: `_pendingDocument` is never silently dropped: it is delivered when initialization later succeeds or an error is surfaced.
+- [ ] AC-U3: The pop-out path carries the already-initialized folder predictor and loaded `MailItemHelper` from the QfcItem, following the #678 carry pattern, and constructs the `EfcViewer` on the UI thread.
+- [ ] AC-U4: `PopulateFolderCombobox` and `InitializeBreadcrumbHostAsync` report failures through `TryReportBoundaryFault` to the user, not log-only.
+- [ ] AC-U5: Manual verification on both entry points: pop-out from QuickFiler and ribbon Sort Email each show suggestion rows and respond to typed search.
+
+Severity: raised from Medium to High. Both Efc entry points are unusable for folder selection in the affected sessions.
diff --git a/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-12T13-21.md b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-12T13-21.md
new file mode 100644
index 000000000..66f5de8ca
--- /dev/null
+++ b/docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/plan.2026-09-12T13-21.md
@@ -0,0 +1,676 @@
+# 2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state (Plan)
+
+- **Issue:** #792
+- **Kind:** bug
+- **Work Mode:** full-bug
+- **Owner:** drmoisan
+- **Last Updated:** 2026-09-12T13-21
+- **Status:** Draft
+- **Version:** 1.3 (preflight revision round 3, prose-only, applied 2026-09-12 in place; see "Preflight round 3 revision record" below. Version 1.2 was preflight revision round 2 applied 2026-09-12 in place; every citation the round touched was re-derived against commit 2405a829d; see "Preflight round 2 revision record" below. Version 1.1 was the adversarial self-review pass, corrections 7 through 13 and the acceptance-condition repairs listed under "Self-review revision record")
+- **Acceptance-criteria source:** `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md`, section `## Acceptance Criteria`, AC-U1 through AC-U9. No other document supplies acceptance criteria for this item.
+- **Base anchor:** commit `2405a829d6afd3b12eb7c228d57158a97cb4e2ca`. Every anchored diff in this plan uses that SHA as its ref operand.
+- **Fixed artifact timestamp token:** `2026-09-12T13-21`. Every evidence artifact this plan names uses that token so its path is deterministic and checkable.
+
+## Task counts (mechanical)
+
+Counted as lines matching the task-line form `- [ ] [P#-T#]`.
+
+| Phase | Tasks |
+| --- | --- |
+| Phase 0 | 11 |
+| Phase 1 | 14 |
+| Phase 2 | 10 |
+| Phase 3 | 17 |
+| Phase 4 | 19 |
+| Phase 5 | 5 |
+| Phase 6 | 20 |
+| **Total** | **96** |
+
+## Fail-closed evidence rules
+
+**Evidence location.** Every evidence artifact resolves under `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence//` where `` is one of baseline, regression-testing, qa-gates, issue-updates, other. No artifacts directory is used for evidence. That directory does not yet exist in the tree and is created by P0-T1.
+
+**Evidence accounting.** Every evidence-producing task names its artifact path on the task line. A task is not complete without the artifact, and every command-step artifact carries `Timestamp:`, `Command:`, `EXIT_CODE:` and `Output Summary:`.
+
+**Projections only.** Per the maintainer decision on issue 671 of 2026-09-11, no test-result file and no raw coverage file is committed. No task in this plan passes a trx logger. The coverage runner writes raw Cobertura into the repository-ignored coverage directory named by its own default output parameter (the ignore rule is the coverage/* entry at line 144 of the root ignore file); the numeric figures are transcribed into the Markdown evidence artifacts and the raw file is left uncommitted.
+
+**Commit-record artifacts.** A task that both commits and records that commit in an artifact cannot satisfy an empty-porcelain clause unless the record is folded into the commit. Every such task (P0-T11, P5-T5, P6-T20) therefore commits, writes its record, stages the record with the same scoped pathspec and amends the commit it just made with `git -C . commit --amend --no-edit`. The amend touches only that task's own commit; no task amends a preceding task's commit.
+
+## Repository discipline this plan encodes
+
+**Bash allowlist.** Only `git`, `gh`, `pwsh`, `poetry run` and the three allowlisted scripts under the .claude lib directory are permitted, and every chained segment of a command line is checked independently. No task states a command of the form that changes directory and then chains a second command. Git is always invoked as `git -C .` from the worktree root. File inspection uses the Read, Grep and Glob tools, never cat, grep, sed, find or head.
+
+**No Python toolchain.** This repository has no scripts/dev_tools tree and no extensions tree. No task passes a coverage argument to a Python runner and no task references pytest.
+
+**C# toolchain order.** Format, then analyzer rebuild, then nullable rebuild, then test. Any failure or any file change restarts the loop at format. `dotnet tool restore` runs once before the first CSharpier invocation. No task adds the solution-wide nullable opt-in property, because no project in this repository carries a nullable element and CI deliberately omits it. No gate uses an incremental build target, because a warm incremental build skips compilation and the gate cannot fail.
+
+**Not SDK-style.** Both project files list every source file explicitly. Every added .cs file gets a bare self-closing Compile element with a backslash-separated project-relative path and no metadata. DependentUpon appears only on Designer and resx pairings in these project files and is never added to a hand-written partial part. Verified anchors, re-derived this pass: the production project file lists the existing partial parts of the breadcrumb router at its lines 291 through 293 and the existing data-model partial pair at its lines 289 and 290, each on its own line with no metadata.
+
+**Tests.** MSTest, Moq and FluentAssertions. No temporary files. No live Outlook. No Thread.Sleep, no Task.Delay and no wall-clock wait anywhere; the retry's delay is an injected delegate whose production default completes synchronously and which tests replace with a no-op. An MSTest Timeout attribute is a hang guard, not a wait, and is used only where the established pump-hosted tests already use one.
+
+**Test file location deviation, recorded explicitly.** The cross-language policy in the repository's general unit-test rule file under the .claude rules directory requires a mirrored tests directory tree. This repository does not use a top-level tests directory for C#: the established convention is a per-area folder inside the test project, for example the Controllers and Viewers folders of the QuickFiler test project. Matching the existing style takes precedence, so every test file this plan creates follows the tree convention QuickFiler.Test/ /Issue792Tests.cs. This deviation is deliberate and is recorded here so a reviewer does not read it as an oversight.
+
+**Test namespaces, re-derived this pass.** The test project mixes two namespace conventions and each new file follows the file it mirrors: the Viewers tests (WebView2BreadcrumbHostTests.cs line 13) use `QuickFiler.Test.Viewers`; the router queue tests (BreadcrumbBridgeRouterQueueTests.cs line 13) use `QuickFiler.Test.Controllers`; the form-controller, data-model, collection-controller and Efc item-controller tests use `QuickFiler.Controllers.Tests`; the Helper Classes tests (ViewerQueueStaticWrapperTests.cs line 9) use `QuickFiler.Test.HelperClasses`. Each task below names the namespace its file uses.
+
+**500-line ceiling.** Stated per file in the Write Set table below. The two files named by AC-U9 are over the ceiling before this change and remain over it after; their counts must strictly decrease and are recorded as pre-existing debt.
+
+**Staging scope.** Every staging span and every porcelain-status span in this plan carries an explicit pathspec limited to the QuickFiler production project directory, the QuickFiler test project directory, and this item's feature folder. No span in this plan reaches the potential-features directory, because this item's diff does not write there.
+
+**Search-literal defect, verified this run.** Git Bash rewrites a leading-slash argument into a Windows path before git sees it, so a git-side search for a literal beginning with a forward slash returns zero matches and exit 1 against a file that genuinely contains it. No acceptance condition in this plan searches for a literal beginning with a forward slash. Structural searches are stated as Grep tool invocations with an explicit pattern, an explicit path and an expected match count, which avoids shell quoting entirely.
+
+**Line-count instrument.** Every line count in this plan is the Grep tool run with the pattern `^` in count output mode against the single file. Verified this pass: that instrument returns 101 for `QuickFiler/Helper Classes/EfcViewerQueue.cs`, which is the value the Write Set table records.
+
+## Execution-phase notes to RECORD, not to act on
+
+1. The sandbox refuses `pwsh` under Agent worktree isolation, so the execution child for this item must be launched non-isolated.
+2. The `atomic-executor` agent definition grants no msbuild and no dotnet Bash permission. Every msbuild step, every `dotnet tool run csharpier` step and every coverage-runner step in this plan must therefore be executed by an agent that holds those permissions. The plan names that handoff rather than assuming the executor can build; see P6-T19.
+
+## Manual, human-executed steps
+
+**M1. Outlook must be closed before any rebuild.** Close Outlook through its own normal exit path. Never end the process. A killed process leaves the build output locked and MSBuild fails with a file-lock error or produces a stale assembly. This is a precondition of every msbuild task in this plan and is captured as its own task at P0-T3 and again at P6-T1.
+
+**M2. AC-U5 is a manual live-Outlook verification.** It is executed by a person against a live Outlook session following the runbook already written in the user story for this item. It is not an automated gate and no acceptance condition in this plan asserts a command exit code for it. Its evidence is a Markdown record carrying the operator, the timestamp, the observed outcome per entry point, and a pass or fail verdict. See P6-T9.
+
+## Corrections to the input documents, established against the tree this pass
+
+1. **The AC-U4 combobox half is already fully pinned, not merely incidentally true.** The research record and the spec's test strategy both state that `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` "today asserts only that the method logs once and does not fault". That is false. The method body at lines 300 through 328 of that file already installs a boundary sink counter at line 310 and asserts the count equals 1 at lines 321 through 327. Only the method **name** is stale. The work for that half is therefore a rename, not an assertion addition, and is planned as such at P3-T16. This correction is load-bearing: a plan that added a sink assertion there would have added a duplicate.
+2. **`QuickFiler.Test/Controllers/EfcFormControllerTests.cs` is 485 lines**, so it has 15 lines of headroom. A rename is line-neutral and is the only edit that fits without a split. The sibling part of the same partial class is 490 lines and is not edited by this change.
+3. **The host seam does not carry the initialization member.** The narrow breadcrumb host interface in the QuickFiler Viewers folder declares only navigate, post, the inbound event and the initialized flag; it has no initialization member. That interface is not in the binding Write Set, so the AC-U1 seam must not be an interface widening. It is an injectable initialization delegate on the form controller instead. See P3-T3.
+4. **The Efc item controller holds no core-initializer field.** Its environment creation calls the SDK factory directly. Routing it through the mockable seam therefore requires introducing the seam property in the new partial, which P1-T11 does.
+5. **All four other target types are already declared partial** (the collection controller, the home controller, the item controller and the data model). Only the Efc form controller is not; P2-T1 adds the modifier.
+6. **The breadcrumb document has no browsing-storage dependence** on the evidence available at authoring time: a case-insensitive search of the QuickFiler Resources breadcrumb HTML file and of the UtilitiesCS folder-breadcrumb renderer and document assets for the six storage tokens returns zero matches. P1-T1 re-establishes this as a recorded verification.
+7. **The Efc incognito constant is pinned by a test outside the Write Set.** QuickFiler.Test/Controllers/EfcItemControllerTests.cs lines 372 through 378 declare `IncognitoArgument_IsAsciiDoubleHyphenIncognitoWithTrailingSpace`, which reads the constant `EfcItemController.IncognitoArgument`. Deleting the constant, as the spec's proposed fix implies, would break the test project's compilation from a file this change may not edit. The constant is therefore moved into the new partial as a forwarding constant whose value is the contract's constant, not deleted. See P1-T11. This is also why the D1 fallback branch halts rather than inverting: an empty argument value would fail that pinned test.
+8. **The item-controller interface has two implementers outside the Write Set.** QuickFiler.Test/Helper Classes/QfcThemeHelperTests.cs line 337 declares a private fake implementing the interface, and QuickFiler/Legacy/QfcController.cs line 20 implements it (that legacy file is not listed in the production project file and is not compiled, but the test fake is). Adding a member to the interface would break the test build from a file this change may not edit. The pop-out carry therefore pattern-matches the item group's controller to the concrete `QfcItemController` type and reads an internal accessor declared there; the interface file is in the Write Set of neither document (preflight round 2 moved it from the spec's Write Set into its prose exclusion paragraph) and is not written by this plan. See P4-T1, P4-T2 and P4-T6.
+9. **Two target classes carry a class-level coverage exclusion.** `QuickFiler/Controllers/EfcItemController.cs` line 25 and `QuickFiler/Controllers/QfcCollectionController.cs` line 21 each carry a class-level exclude-from-code-coverage attribute. An attribute on one partial declaration applies to the whole type, so the two new partials this plan creates for those types produce no class element in the Cobertura document and no per-file rate can be demanded for them. P6-T7 records those two rows as unmeasurable by pre-existing exclusion and names the tests that stand as their evidence, rather than demanding a rate that cannot exist.
+10. **Two non-code occurrences would defeat the one-owner gate.** `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` line 60 is a commented-out alternative construction that still contains the options-constructor token, and `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` line 18 is a summary-comment line that names the shared folder literal. P1-T10 removes the commented-out line and P1-T9 rewords the summary line, so the P1-T13 gate counts only real sites.
+11. **The data model is constructible in a test without Outlook, and its token is settable only through the constructor.** `QuickFiler/Controllers/EfcDataModel.cs` lines 48 through 75: with a null mail the constructor calls a selection probe that catches every exception and returns null, so a loose globals mock and a null mail construct the model with no resolver. `Token` (line 164) has a protected setter assigned from the constructor argument (line 58). Passing an already-cancelled token makes every `Task.Run(..., Token)` in the moved folder-handler initialization return a cancelled task without running its delegate, which is what makes the construction path observable without Outlook. A carried predictor is constructible as `new FolderPredictor(globals.Object)` with a loose globals mock, the pattern already used at line 378 of QuickFiler.Test/Controllers/QfcItemController.FolderHandlingTests.Part2.cs. See P4-T9.
+12. **`UiThread.Dispatcher` throws when uninitialized, and the fixture's parked dispatcher never pumps.** UtilitiesCS/Threading/UiThread.cs lines 251 through 269 throw an invalid-operation exception when no dispatcher was captured. The test project's `UiThreadDispatcherFixture` (QuickFiler.Test/Controllers/QfcItemController.UiThreadDispatcherFixture.cs) exposes `Exchange` at line 55, `CompareExchange` at line 70 and `BeginTransactionAsync` at line 122 with a transaction type at line 220 carrying `Install` at line 242; its `EnsureDispatcher` at line 99 parks a dispatcher that never runs a frame (lines 145 through 147), so a blocking `Invoke` against it would never return. `QfcItemControllerTestSupport.StartRunningDispatcher` (QuickFiler.Test/Controllers/QfcItemController.TestSupport.cs line 251) starts a pumping STA dispatcher and `ShutdownDispatcher` (line 277) stops it. P4-T13 uses the transaction plus the running dispatcher, never the parked one. A dispatcher priority is not observable from inside the invoked action, so the spec's "forwards the priority" assertion is replaced by an assertion on the reset member, which is the second production site the change edits.
+13. **The two discard tests that pin an empty buffer or a silent discard already pass against the defect-preserving stub, and one form-controller test already passes against the single-attempt body.** P3-T11's fail-before enumeration names exactly which methods must fail and which pin preserved behaviour, instead of demanding that every method fail.
+
+## Design decisions settled here, so the executor does not decide them
+
+**D1. Options direction.** All three environment creations converge on the additional browser argument `--incognito ` owned by the new contract file. Fallback branch, stated explicitly: if P1-T1 finds any browsing-storage dependence in the breadcrumb document, execution halts at P1-T1 and reports remediation-required, because the pinned test named in correction 7 lives outside the Write Set and an inverted direction cannot be landed within this plan's file set. Correction 6 records that the tree at the base anchor takes the primary branch.
+
+**D2. AC-U1 seam shape.** The form controller gains an injectable initialization delegate and an injectable retry-delay delegate. The delegate default must not be written as a property initializer capturing the host field, because a field initializer cannot reference a non-static instance field and that spelling is a compile error. The default is supplied lazily from a backing field in the property getter instead.
+
+**D3. AC-U1 error-state delivery.** The failed host cannot render, so the error banner is composed and rendered by the router and then delivered by the same two-state mechanism the router already uses in its private document delivery member (QuickFiler/Controllers/BreadcrumbBridgeRouter.Selection.cs lines 168 through 180): navigated immediately when the host reports initialized, retained as the pending document otherwise so a later successful initialization delivers it. The user-visible surfacing in the never-initialized case is the existing modeless fault notice reached through the form controller's boundary reporter, which AC-U4 covers. The banner row uses the existing banner prefix constant `BannerPrefix` (value `====`, UtilitiesCS/OutlookObjects/Folder/BreadcrumbRowBuilder.cs line 19) and banner rows are already non-selectable, so the error row cannot be chosen as a folder. No new WinForms control is added.
+
+**D4. AC-U7 discard primitive.** The outbound queue gains a discard member that clears the buffer and returns the discarded count. The router's failure notification flushes the buffer when the host is initialized and discards it otherwise. Either way the pending count is zero afterwards.
+
+**D5. AC-U3 carry typing and carry read.** The carried folder handler is typed as the existing folder-search-handler interface, which lives in the UtilitiesCS root namespace that the edited QuickFiler files already import, so no new using directive is required. The data model's concrete predictor property is not retyped and the UtilitiesCS interface is not widened. Adoption happens only when no explicit folder list was supplied and the carried instance matches the concrete predictor type by pattern match. The carried mail-item helper is held in a private carry field on the new data-model partial and preferred over the resolver-derived value inside the folder-handler initialization; the resolver property is not retyped and its protected setter is not touched. On the producing side, per correction 8, the pop-out reads the mail-item helper through the interface member `ItemHelper` that already exists (QuickFiler/Interfaces/IQfcItemController.cs line 41) and reads the folder handler through a new internal accessor on the concrete `QfcItemController`, reached by pattern-matching the item group's `ItemController` (typed as the interface at QuickFiler/Controllers/QfcItemGroup.cs line 39) to the concrete type.
+
+**D6. AC-U3 pop-out decomposition.** The two pop-out members keep their current ordering: the carry is read before the group is removed, and the home controller is created after. The read and the creation are each extracted into their own internal member so both are unit-testable without WinForms, and a wiring-sensitive structural gate asserts that each extracted member name occurs exactly three times in the new partial, once as a declaration and once in each of the two pop-out members. Comments in that file must not repeat either member name, so the count stays a wiring count.
+
+**D7. AC-U8 versus AC-U9.** AC-U8's ceiling is verified for every file in the Write Set except the two files AC-U9 names as pre-existing debt. For those two the gate is that the post-change count is strictly lower than the Phase 0 baseline count, which is the only reading consistent with the spec's own out-of-scope statement that a full split of either is out of scope and their remaining size is debt this change neither introduces nor resolves.
+
+## Write Set and expected resulting line counts
+
+The source Write Set below lists the 31 paths of the `## Write Set` section of the spec, element for element; the spec and this table agree on those 31 written paths (the spec was brought into agreement in preflight round 2, when the item-controller interface was moved from its Write Set into its plain-prose exclusion paragraph per correction 8). Evidence artifacts and the spec file itself are additionally written by this plan and are listed after the table. One read-only control path is measured but not written and is stated after the table in plain text so the blast-radius extractor does not harvest it.
+
+| Path | Before | Expected after | Ceiling status |
+| --- | --- | --- | --- |
+| `QuickFiler/Viewers/WebView2EnvironmentContract.cs` | new | 40 to 100 | under |
+| `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` | 368 | 360 to 372 | under |
+| `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` | 467 | 458 to 472 | under |
+| `QuickFiler/Controllers/EfcItemController.cs` | 1121 | 1060 to 1085 | AC-U9 debt, must strictly decrease |
+| `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` | new | 55 to 110 | under |
+| `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` | 407 | 430 to 475 | under |
+| `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` | 67 | 76 to 95 | under |
+| `QuickFiler/Controllers/EfcFormController.cs` | 1321 | 250 to 290 | under |
+| `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` | new | 180 to 260 | under |
+| `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs` | new | 215 to 270 | under |
+| `QuickFiler/Controllers/EfcFormController.EventHandlers.cs` | new | 355 to 410 | under |
+| `QuickFiler/Controllers/EfcFormController.Actions.cs` | new | 160 to 210 | under |
+| `QuickFiler/Controllers/EfcFormController.Helpers.cs` | new | 205 to 260 | under |
+| `QuickFiler/Controllers/QfcCollectionController.cs` | 2329 | 2295 to 2315 | AC-U9 debt, must strictly decrease |
+| `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` | new | 80 to 150 | under |
+| `QuickFiler/Controllers/EfcHomeController.cs` | 447 | 452 to 480 | under |
+| `QuickFiler/Controllers/EfcDataModel.cs` | 499 | 460 to 470 | under |
+| `QuickFiler/Controllers/EfcDataModel.Carry.cs` | new | 70 to 140 | under |
+| `QuickFiler/Controllers/QfcItemController.cs` | 334 | 337 to 352 | under |
+| `QuickFiler/Helper Classes/EfcViewerQueue.cs` | 101 | 99 to 106 | under |
+| `QuickFiler/QuickFiler.csproj` | project file | plus 9 Compile elements | project file, not size-gated |
+| `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs` | new | 80 to 180 | under |
+| `QuickFiler.Test/Viewers/WebView2EnvironmentContractTests.cs` | new | 70 to 160 | under |
+| `QuickFiler.Test/Controllers/BreadcrumbBridgeRouterIssue792Tests.cs` | new | 140 to 270 | under |
+| `QuickFiler.Test/Controllers/BreadcrumbOutboundQueueIssue792Tests.cs` | new | 80 to 160 | under |
+| `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs` | new | 160 to 320 | under |
+| `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` | 485 | 485 | under, rename is line-neutral |
+| `QuickFiler.Test/Controllers/QfcCollectionControllerIssue792PopOutTests.cs` | new | 120 to 250 | under |
+| `QuickFiler.Test/Controllers/EfcDataModelIssue792CarryTests.cs` | new | 120 to 260 | under |
+| `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs` | new | 70 to 160 | under |
+| `QuickFiler.Test/QuickFiler.Test.csproj` | project file | plus 8 Compile elements | project file, not size-gated |
+
+Two of the paths above contain a space in the directory name, under Helper Classes in each project. Those are the real tracked paths and are reproduced exactly.
+
+Control row, plain text, NOT written (correction 8): QuickFiler/Interfaces/IQfcItemController.cs, 113 lines at the base anchor, expected 113 and unchanged after. It is not in the Write Set of either document. P0-T9 and P5-T2 measure it as one additional labelled control row so P4-T1 has a recorded baseline to compare against.
+
+Additionally written by this plan: `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/spec.md` (AC check-off marks only, in Phase 6) and the evidence artifacts named on the task lines below.
+
+## Files deliberately not modified
+
+Stated in prose with no backticks, because the blast-radius extractor has no notion of polarity and would harvest an excluded path as though it were written.
+
+The UtilitiesCS folder-search-handler interface and the folder predictor that implements it are not modified: the carry is typed as the existing interface and adopted by pattern match on the concrete predictor type, so neither needs widening and no change leaves the QuickFiler project. The QuickFiler item-controller interface in the Interfaces folder is not modified, and neither document lists it as written: two implementers outside the Write Set would fail to compile if a member were added, so the carry read pattern-matches the concrete item controller instead. The Efc item-controller test file in the test project's Controllers folder is not modified: its pinned constant test keeps compiling because the constant is forwarded rather than deleted. The narrow breadcrumb web-host interface in the QuickFiler Viewers folder is not modified: the AC-U1 seam is an injectable delegate on the form controller, not an interface member. The core-initializer interface in the QuickFiler Viewers folder is not modified: the Efc item controller adopts it as a consumer only. The breadcrumb UI dispatcher is not modified: research assessed its boundary check as self-consistent and a sibling item explicitly scoped it out. The breadcrumb row builder, the breadcrumb HTML renderer and the breadcrumb document assets in UtilitiesCS are not modified: the error state reuses the existing banner-prefix convention and the existing rendering path. The breadcrumb HTML resource under the QuickFiler Resources folder is not modified: it is read in P1-T1 and nothing else. The router's Selection and Arrows partial parts are not modified: the failure notification is added to the main router file next to the success notification. The item viewer files owned by a sibling item are not modified. The sibling part of the form-controller test class is not modified. The collection-controller test support helper and the item-controller test support and dispatcher fixture files are not modified; they are consumed as-is.
+
+## Known contention
+
+Sibling issue 645 edits the same collection-controller file at three date and time formatting call sites, which are disjoint from the pop-out members this item moves, and it also edits the QuickFiler production project file. A merge on the project file's item-group ordering is expected and accepted. New Compile elements are appended adjacent to their existing neighbours as bare self-closing elements with no metadata, which minimises the conflict surface. Sibling issue 781 is scoped to the item viewer files this item does not write; the overlap is conceptual only and this item adopts the owner-thread-identity idiom that sibling ratified rather than inventing a third convention.
+
+## Self-review revision record (2026-09-12, version 1.1)
+
+Applied in place during the adversarial self-review pass. Each entry names the defect and the repair so a later reader does not re-derive it.
+
+1. P1-T11 deleted a constant pinned by a test outside the Write Set; now forwarded (correction 7).
+2. P4-T1 widened an interface with two out-of-Write-Set implementers; now a read-only non-widening verification, with the accessor moved to the concrete type (correction 8).
+3. P6-T7 demanded a 0.90 rate for two files that cannot have a class element (correction 9); rows re-specified per file, with the exempt member and the pre-existing moved lambdas named by the planner rather than chosen by the executor.
+4. P1-T13's "exactly 1" gates were defeated by a commented-out construction and a summary-comment folder name (correction 10); both occurrences are now removed by P1-T10 and P1-T9 and the gate is stated as "zero outside the contract file".
+5. P2-T7's pattern also matched the parent's own Compile entry (six hits, not five); pattern narrowed to the five new names.
+6. P0-T9 and P5-T3 said ten new files; the Write Set creates seventeen.
+7. P2-T8's sum window (1400 to 1500) was below the arithmetic: 1316 retained source lines plus five file headers of roughly 10 to 14 lines each lands near 1370 to 1390; window is now 1360 to 1460.
+8. Several lower bounds on new-file line counts were above the arithmetic of the moved spans plus a header; loosened.
+9. P3-T11 demanded that all fifteen Phase 3 tests fail before the fix; two discard tests and one form-controller test pass against the stubs (correction 13); enumeration corrected. P4-T15 likewise.
+10. P3-T14's `TryReportBoundaryFault` floor of 2 was already met by the two moved call sites (pre-split lines 1127 and 1270); floor raised to 3.
+11. P1-T4's directory-existence test was environment-dependent; replaced by a rooted-path assertion. A forwarding-constant test was added so the Efc site's argument agreement is asserted by a test, not only by a structural gate.
+12. P4-T13 relied on an uninitialized dispatcher and an unobservable priority (correction 12); re-specified over the running-dispatcher transaction.
+13. P0-T11, P5-T5 and the final commit task (P6-T19 in version 1.1, P6-T20 since round 2) wrote their commit record after committing and then demanded empty porcelain; the amend step was added.
+14. P6-T6 demanded exit 0 and zero failures unconditionally; the coverage runner asserts a 0.80 floor and exits non-zero below it, and a pre-existing failing test would make the clause unsatisfiable; both are now baseline-relative, and P0-T8 records the failing-test names the comparison needs.
+15. P5-T1 and P6-T2 formatted two whole directories, which would sweep pre-existing drift outside the Write Set into the diff and break the "exactly the written paths" clause; both now format the explicit Write Set file list, and P6-T3 is baseline-relative.
+16. Test namespaces were stated as `QuickFiler.Viewers.Tests` and `QuickFiler.Controllers.Tests` uniformly; corrected per file to the mirrored sibling's namespace.
+17. P4-T11's fifth test was a cleanup assertion, not a test; replaced by a non-concrete-controller case.
+18. The D1 fallback inverted the argument direction downstream; it now halts, because the pinned test outside the Write Set cannot absorb an inverted value.
+
+## Preflight round 2 revision record (2026-09-12, version 1.2)
+
+Applied in place from the executor's round-2 delta plus one orchestrator item. Every tree fact each entry relies on was re-derived against the base anchor in this pass.
+
+1. P0-T4 assumed a bootstrapped worktree; the worktree holds no repo-local SDK directory and no packages directory, and the PackageReference-only restore is a no-op against packages.config projects. Now runs the repo-local SDK installer, the tool restore and a packages.config-aware restore, and gates on observed installs rather than on exit codes alone.
+2. P4-T1's bare accessor-token gate was already false at the base anchor because the pre-existing member `LoadFolderHandlerAsync` at interface line 77 contains the token; the gate now searches the typed declaration and pins the pre-existing member's count.
+3. P6-T7's Breadcrumb rule gated moved members that no unit test can reach; the gate is now over the members this change writes, and every moved member is listed as information with its reason.
+4. P6-T10 through P6-T18 appended evidence citations to acceptance-criterion lines, which the acceptance-criteria-tracking skill forbids; the only spec edit is now the marker flip, and citations go to an ac-status-summary artifact under evidence/issue-updates.
+5. The final commit wrote evidence after itself; the handoff record is now P6-T19 and the final commit is P6-T20, with captures taken before the artifact write.
+6. Four excluded paths were backticked (an Efc item-controller test file, the UiThread file, the router Selection part, and the coverage ignore glob); backticks removed.
+7. P1-T6's second test asserted against the empty string, which the SDK's no-argument constructor does not produce (it leaves the property null); the test now asserts not-null-or-empty.
+8. P1-T8 lacked the rebuild precondition that P3-T11 and P4-T15 carry; added.
+9. P0-T11's listing clause omitted the five requirement documents untracked at the base anchor; the clause is now exact.
+10. P3-T3 did not state how the single attempt reaches the injected delegate, and its match floor counted a lower-camel backing field that a case-sensitive pattern does not match; wiring stated, floor lowered to 2.
+11. P4-T9's second test did not state its fail-before mechanism; stated.
+12. P2-T10 demanded an exact passed-count equality that pre-existing flaky or newly passing tests could break; now a floor.
+13. P6-T7's repository-rate clause had no formula; now stated over `lines-covered` and `lines-valid` with the 0.80 floor.
+14. P6-T7's exclusion rows asserted no class element exists, which a compiler-generated closure type could falsify; now records whether one exists and gates no rate on it.
+15. P6-T20's projections-only Grep had no concrete target; now the record artifact, whose prose must not carry either literal.
+16. P1-T13's hit decomposition was wrong (count right); corrected to the two live sites plus the two commented-out lines, with the target-typed ViewerSetup site noted as a non-match.
+17. P4-T11 and P4-T13 mutate process-wide statics under a class-parallel runsettings; both classes now carry `[DoNotParallelize]`, and P4-T13's timeout constant is stated as a value.
+18. Orchestrator item: spec.md's `## Write Set` listed 32 paths including the interface this plan does not write; the spec now lists 31, the interface sits in its prose exclusion paragraph, the spec's summary and function-impact sentences no longer name the interface as written, and this plan's table and count statements agree on 31.
+
+## Preflight round 3 revision record (2026-09-12, version 1.3)
+
+Prose-only. The executor confirmed every round-2 delta landed and re-verified every tree citation, task count and gate; the sole remaining findings were prose residuals of the 32-to-31 Write Set reduction. No task identifier, task count, phase heading, count statement, gate value or command changed in this round.
+
+1. Spec regression-test list said seven new test files; the write set names eight. Corrected.
+2. Spec backward-compatibility paragraph still described one interface change adding a read-only member; replaced with the non-widening statement (internal get-only property on the concrete item controller, reached by pattern match).
+3. Spec compatibility note still said "the added interface member"; now "the added internal accessor on the concrete item controller".
+4. Spec pop-out data-flow sentence still said both carried values are read through the interface; now states the mail item helper comes through the existing interface member and the folder handler through the internal accessor on the concrete type, null when the group's controller is not the concrete type.
+5. Correction 8 still said the interface file is listed in the spec's Write Set; now states it is in the Write Set of neither document.
+6. The files-not-modified paragraph still said "although the spec lists it"; now "neither document lists it as written".
+7. The spec CITATION locator said Write Set 308-341; now 308-344 with the 31 paths at 310-340 and the exclusion paragraph at 344.
+8. P6-T7's Breadcrumb row is advisory by design: every P3-T9 test substitutes both delegates, so the two lazy-default getter expressions are excluded from the gated span and recorded as information with their hit counts.
+
+---
+
+### Phase 0 — Baseline Capture and Policy Reads
+
+- [ ] [P0-T1] Read the repository policy documents in the mandated order and record the read in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/phase0-instructions-read.2026-09-12T13-21.md`, creating the evidence directory tree as part of this task.
+ - Read, in this order and in full, using the Read tool: CLAUDE.md at the repository root; then .claude/rules/general-code-change.md; then .claude/rules/general-unit-test.md; then .claude/rules/csharp.md; then .claude/rules/quality-tiers.md; then .claude/rules/tonality.md; then .claude/rules/plan-acceptance-gates.md. All seven exist at the base anchor.
+ - Acceptance: the artifact exists and contains a `Timestamp:` field, a `Policy Order:` field listing those seven paths in that order, and a `Files Read:` list whose entries are exactly those seven paths.
+
+- [ ] [P0-T2] Capture the base anchor and confirm it, recording the result in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/base-anchor.2026-09-12T13-21.md`.
+ - Run `git -C . rev-parse HEAD`.
+ - Acceptance: the artifact records `Command:`, `EXIT_CODE: 0` and an `Output Summary:` whose recorded SHA is exactly `2405a829d6afd3b12eb7c228d57158a97cb4e2ca`. If the recorded SHA differs, stop and report a base-anchor mismatch rather than continuing, because every anchored diff in this plan names that SHA as its ref operand.
+
+- [ ] [P0-T3] MANUAL HUMAN STEP. Close Outlook through its normal exit path before any msbuild task in this phase runs, and record the confirmation in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/outlook-closed-precondition.2026-09-12T13-21.md`.
+ - Runbook: use Outlook's own File then Exit path, or the window close button, and wait until the process is gone from the task list of its own accord. Do not end the process from the task manager and do not use any process-kill command. A killed process leaves the debug build output locked, and MSBuild then fails with a file-lock error or silently links a stale assembly.
+ - Acceptance: the artifact records the operator name, the ISO-8601 local timestamp of the confirmed exit, and the sentence that Outlook was closed through its normal exit path and was not killed. This task has no exit code and no automated gate.
+
+- [ ] [P0-T4] Bootstrap the toolchain in this worktree and record the result in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/toolchain-bootstrap.2026-09-12T13-21.md`.
+ - This worktree holds no repo-local SDK directory and no packages directory at the base anchor (verified this pass with the Glob tool: no dotnet executable under the repo-local SDK directory and no entry under a packages directory). global.json pins SDK 8.0.205 with the latestFeature roll-forward and search paths of the repo-local SDK directory then the host, so `dotnet tool restore` exits non-zero with global.json's own error message unless a compatible SDK is present. `msbuild TaskMaster.sln /t:Restore` handles PackageReference only; against this repository's packages.config projects it exits 0, prints that none of the projects contain packages to restore, and installs nothing.
+ - Run, in this order, from the worktree root under PowerShell 7: scripts/vscode/Install-RepoDotNetSdk.ps1 (skip only when the repo-local SDK executable already exists, and record which branch was taken; the installer itself prints that the SDK is already installed and returns when its own marker directory, the sdk-slash-version directory under the install directory, exists at its lines 56 through 61); then `dotnet tool restore`; then `msbuild TaskMaster.sln /t:Restore /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:RestorePackagesConfig=true`.
+ - Acceptance: the artifact records all three commands, an `EXIT_CODE:` for each, and an `Output Summary:` that states the CSharpier version the manifest pinned as reported by the tool restore output, the number of packages the restore installed as printed by the restore output, and the Glob tool observations that the repo-local SDK executable exists and that the packages directory contains at least one package directory. Every exit code must be 0, and a restore that prints the nothing-to-do line or installs zero packages stops the phase. Both writes land on ignored or restore-output paths only (the root ignore file's dot-dotnet wildcard directory entry at its line 350 covers the SDK directory, and its bracket-class packages entry at line 191 covers the packages directory), so neither widens any anchored-diff footprint.
+
+- [ ] [P0-T5] Capture the CSharpier baseline into `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/format-check.2026-09-12T13-21.md`.
+ - Run `dotnet tool run csharpier check .`. This is the read-only verify form; the write-mode form is not used in Phase 0, because a formatter that repairs pre-existing drift before the baseline is taken turns the baseline into a blanket waiver.
+ - Acceptance: the artifact records `Command:`, `EXIT_CODE:` and an `Output Summary:` carrying the count of files CSharpier reported as needing formatting and the repository-relative path of every such file under a `Reported set:` heading, or the literal statement that it reported none. The exit code is recorded as observed and is not asserted to be 0, because a solution-wide pre-existing drift is a property of the tree rather than of this change. P6-T3 compares against the `Reported set:` heading.
+
+- [ ] [P0-T6] Capture the analyzer-build baseline into `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/analyzer-build.2026-09-12T13-21.md`.
+ - Precondition: P0-T3 is complete. Run `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true`.
+ - Acceptance: the artifact records `Command:`, `EXIT_CODE:` and an `Output Summary:` carrying the warning count and the error count exactly as the build summary reports them, plus the deduplicated set of diagnostic identifiers observed. Record the counts as the two figures printed on the summary lines; do not infer them. The exit code is recorded as observed and is not asserted to be 0.
+
+- [ ] [P0-T7] Capture the nullable-build baseline into `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/nullable-build.2026-09-12T13-21.md`.
+ - Precondition: P0-T3 is complete. Run `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true`. Do not add the solution-wide nullable opt-in property.
+ - Acceptance: the artifact records `Command:`, `EXIT_CODE:` and an `Output Summary:` carrying the error count from the build summary and the deduplicated set of diagnostic identifiers observed. The exit code is recorded as observed and is not asserted to be 0.
+
+- [ ] [P0-T8] Capture the test and coverage baseline into `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/test-coverage.2026-09-12T13-21.md`.
+ - Precondition: P0-T3 is complete. Run the repository coverage runner at scripts/vscode/Invoke-MSTestWithCoverage.ps1 under PowerShell 7 with an explicit search root of the current directory and the Debug configuration. The runner already appends the isolation switch, the CLI runsettings and the live-Outlook test-category exclusion (its line 76), discovers assemblies relative to the search root so an agent worktree is not self-excluded (its line 301), post-processes the document so class elements are merged by source file name, and writes the processed Cobertura to its default output path under the repository-ignored coverage directory. Do not pass a trx logger. The runner asserts a 0.80 repository line-rate floor after writing the document and exits non-zero below it, so the document exists even when the exit code is non-zero.
+ - Acceptance: the artifact records `Command:`, `EXIT_CODE:` as observed, and an `Output Summary:` carrying five numeric figures read with the Read tool from the root element of the runner's Cobertura output: `lines-valid`, `lines-covered`, `line-rate`, `branches-valid` and `branch-rate`; the total, passed, failed and skipped test counts; and, under a `Failed set:` heading, the fully qualified name of every failed test, or the literal `none`. The figures are read from the XML attributes rather than from console text, so the acceptance does not depend on what the runner prints. The raw Cobertura file is left uncommitted. If the run does not complete, the phase stops and the item is reported as remediation-required with the runner's last output quoted; the runner is not edited, because it is outside the Write Set.
+
+- [ ] [P0-T9] Capture the baseline line count of every one of the 31 Write Set paths, plus the one control path, into `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/write-set-line-counts.2026-09-12T13-21.md`.
+ - Measure each existing file with the Grep tool using the pattern `^` in count output mode against that single file. Record one row per Write Set path. For the seventeen paths that do not yet exist, record the literal value `absent`. Then record one additional row, labelled `control (not written)`, for the item-controller interface named in the control-row paragraph under the Write Set table.
+ - Acceptance: the artifact contains exactly 31 Write Set rows plus exactly one control row, 32 rows in all; the Write Set rows for the existing production files record 368 for the breadcrumb host, 467 for the item-controller viewer-setup part, 1121 for the Efc item controller, 407 for the router, 67 for the outbound queue, 1321 for the Efc form controller, 2329 for the collection controller, 447 for the home controller, 499 for the data model, 334 for the QuickFiler item controller and 101 for the Efc viewer queue; the row for `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` records 485; exactly seventeen rows record `absent`; the control row records 113. AC-U8 and AC-U9 are judged against this artifact, and P4-T1 reads the control row.
+
+- [ ] [P0-T10] Capture the baseline Compile-item inventory of `QuickFiler/QuickFiler.csproj` and `QuickFiler.Test/QuickFiler.Test.csproj` into `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/compile-item-inventory.2026-09-12T13-21.md`.
+ - Measure with the Grep tool using the pattern ` action\(\)` against this file returns 0 matches, and the Grep tool run with the pattern `UiThread\.Dispatcher\.Invoke\(action, priority\)` against this file returns exactly 2 matches; that pattern does not match the two existing asynchronous-invoke sites at lines 20 and 67, because the token after `Invoke` there is `Async`. The file's measured line count is between 99 and 106.
+
+- [ ] [P4-T19] Rebuild, run the three Phase 4 test classes green, and commit, recording the run in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/regression-testing/p4-pass-after.2026-09-12T13-21.md`.
+ - Precondition: P0-T3 is complete. Rebuild with the analyzer command, then run vstest filtered to the three Phase 4 class names.
+ - Acceptance: the artifact records `Command:`, `EXIT_CODE: 0` and an `Output Summary:` stating that all twelve Phase 4 test methods passed and zero failed. Then run `git -C . add -- QuickFiler QuickFiler.Test docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` and `git -C . commit -m "#792 Phase 4 pop-out carry and dispatcher viewer construction"`; afterwards `git -C . status --porcelain --untracked-files=all -- QuickFiler QuickFiler.Test docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` prints no lines.
+
+### Phase 5 — AC-U8 Ceiling and Compile-item Parity, AC-U9 Debt Record
+
+- [ ] [P5-T1] Run the formatter over the written .cs files so the ceiling audit measures formatted files, and record the observation in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/p5-scoped-format.2026-09-12T13-21.md`.
+ - Run `dotnet tool run csharpier format` followed by the twenty production .cs paths of the Write Set table (every production row except the project file), then run it a second time followed by the nine test .cs paths of the Write Set table; quote the two paths under Helper Classes because they contain a space. Do not pass a directory: a directory-scoped pass would also rewrite pre-existing drift in files outside the Write Set and break the exactly-the-written-paths clause of P6-T20.
+ - Acceptance: this is a write-mode command whose exit code is 0 both when it changed nothing and when it repaired drift, so the exit code alone is not the gate. The artifact records both commands, both exit codes, the processed-file counts the tool printed, the output of `git -C . status --porcelain --untracked-files=all -- QuickFiler QuickFiler.Test` captured immediately before and immediately after the two commands, and the result of `dotnet tool run csharpier check` run afterwards over the same twenty-nine paths. The gate passes when both format exit codes are 0, the check exit code is 0 and it reports no file needing formatting, and every path in the after-capture is one of the Write Set paths.
+
+- [ ] [P5-T2] AC-U8 ceiling audit. Measure every one of the 31 Write Set paths, plus the one control path, after formatting and record the result in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/ac-u8-line-counts.2026-09-12T13-21.md`.
+ - Measure with the Grep tool using the pattern `^` in count output mode, the same instrument P0-T9 used, so the before and after figures are comparable. Record the control row for the item-controller interface with the same `control (not written)` label P0-T9 used.
+ - Acceptance: the artifact contains 31 Write Set rows plus one control row, 32 rows in all, each carrying the path, the Phase 0 baseline value from the P0-T9 artifact and the measured post-change value. Every Write Set row except the two AC-U9 debt rows records a post-change value of at most 500. The two project-file rows are recorded but are not size-gated. The control row records 113, unchanged. The row for `QuickFiler/Controllers/EfcItemController.cs` records a value strictly less than 1121 and the row for `QuickFiler/Controllers/QfcCollectionController.cs` records a value strictly less than 2329. Any row over 500 that is not one of those two fails this gate.
+
+- [ ] [P5-T3] AC-U8 Compile-item parity. Compare the added and removed .cs files against the Compile element edits and record the result in `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/qa-gates/ac-u8-compile-parity.2026-09-12T13-21.md`.
+ - Run `git -C . add -- QuickFiler QuickFiler.Test`, then `git -C . diff --name-status --cached 2405a829d6afd3b12eb7c228d57158a97cb4e2ca -- QuickFiler QuickFiler.Test`. The staging span is what makes the name-listing diff able to see the seventeen files this change created. Then measure the post-change Compile element count in each project file with the Grep tool using the pattern ``. Every line citation below was re-derived against that tree in this pass.
+- **Task Count:** 93 (P0 16, P1 4, P2 15, P3 8, P4 12, P5 9, P6 6, P7 18, P8 5), counted mechanically over `^- \[ \] \[P\d+-T\d+\]`.
+
+## Inputs
+
+- Requirements: `$FEATURE/spec.md` (nine criteria AC-U1 through AC-U9, lines 306-314).
+- Manual runbook: `$FEATURE/user-story.md` (AC-U5 runbook, lines 52-86).
+- Research (current): `$FEATURE/research/2026-09-17T11-20-breadcrumb-webview2-init-research.md`. The older `2026-09-12T10-30-...` record is superseded and was not relied on.
+- `$FEATURE` abbreviates the repository-relative path `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792`. Every evidence path in this plan is `$FEATURE/evidence//...` with kind in {baseline, regression-testing, qa-gates, other}; no `artifacts/` evidence location is used anywhere.
+
+## Premise verification (all re-derived against the item worktree, ``, in this pass)
+
+| Premise from the brief | Measured |
+|---|---|
+| `QuickFiler/Viewers/WebView2BreadcrumbHost.cs:250` constructs options with no arguments | Confirmed: `var options = new CoreWebView2EnvironmentOptions();` |
+| `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:61` dead comment, `:62` live target-typed `new("--incognito ")` | Confirmed |
+| `QuickFiler/Controllers/EfcItemController.cs:177` `IncognitoArgument`, `:188-190` construction, `:195-199` direct `CoreWebView2Environment.CreateAsync` | Confirmed |
+| `BreadcrumbBridgeRouter.Selection.cs:168-180` stash; `BreadcrumbBridgeRouter.cs:320-329` sole drain calling `_outboundQueue.OnInitializationCompleted()` at `:328`; `BreadcrumbOutboundQueue.cs:59-65` FIFO drain | Confirmed |
+| Sole `CoreInitialized` subscription `EfcFormController.cs:1064`; host returns at `:341` without raising; `InitializeAsync` `:239-270` has no retry | Confirmed |
+| `TryReportBoundaryFault` defined `:150-168`, eight call sites 556, 573, 591, 653, 668, 1015, 1127, 1270 | Confirmed by grep |
+| `InitializeBreadcrumbHostAsync` `:1072-1082`, log-only at `:1080` | Confirmed |
+| Line totals: EfcFormController.cs 1321, EfcItemController.cs 1122, QfcCollectionController.cs 2333, ViewerSetup 479, EfcFormControllerTests.cs 485, EfcDataModel.cs 499, EfcHomeController.cs 447 | Confirmed by tail reads |
+| Designer `CreationProperties` inert; `EfcViewer.FolderListBox` declares none | Not re-verified beyond the research record; no plan task depends on it |
+
+Two corrections to the brief, neither a premise failure:
+
+1. The brief names six not-yet-existing write-set entries. The write set actually creates seventeen `.cs` files (nine production, eight test), every one of which needs a Compile item. All seventeen are wired in this plan (see AC-U8 parity, [P6-T3]).
+2. The existing test `EfcFormControllerTests.PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault` (`QuickFiler.Test/Controllers/EfcFormControllerTests.cs:299-328`) already asserts the boundary-sink call count through a substituted `BoundaryErrorSink`; it does not assert the user-facing surface. The strengthened test therefore pins `UserFaultNotifier` (the user surface behind the default sink), and its discriminating mutation is dropping the notifier call inside `DefaultBoundaryErrorSink`, which the existing test cannot detect.
+
+## Design decisions (fixed; do not relitigate during execution)
+
+- **D1 One owner.** New `QuickFiler/Viewers/WebView2EnvironmentContract.cs` (`internal static class`) owns `AdditionalBrowserArguments = "--incognito "`, `UserDataFolderName = "WindowsFormsWebView2"`, `ResolveUserDataFolder()` (a `Path.Combine` over `LocalApplicationData`; creates nothing on disk) and `CreateOptions()`. All three sites read from it. Direction is settled by the research record (question 1 closed); no audit task exists.
+- **D2 Site 3 through the seam.** `EfcItemController.InitializeWebViewAsync` and `IncognitoArgument` move to `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs`. The moved method gains an `internal IWebViewCoreInitializer WebViewInitializer` property (lazy default `new WebView2CoreInitializer()`) and awaits both seam calls instead of the `ContinueWith` chain, so a failure now reaches `InitializeWebViewGuardedAsync` (`EfcItemController.WebViewFaultBoundary.cs:25-42`). `IncognitoArgument` stays declared (the #463 test `EfcItemControllerTests.cs:371-396` pins it) as an alias `= WebView2EnvironmentContract.AdditionalBrowserArguments`.
+- **D3 One defect, one trigger.** The retry and the failure notification live on the awaited path in `EfcFormController.InitializeBreadcrumbHostAsync` (made `internal`), never in the host's `[ExcludeFromCodeCoverage]` SDK handler. Fixed attempt count `BreadcrumbInitializationAttemptLimit = 3`, no wall-clock delay, `OperationCanceledException` is non-fault and stops the loop. Seam: `internal Func BreadcrumbHostInitializer { get; set; }`; null selects the production `_breadcrumbHost.InitializeAsync(_formViewer.UiSyncContext)`. No new host event is added: the spec's "wires the new failure notification" sentence is delivered by a direct call after the loop, because a host-side event would live in the structurally untestable handler.
+- **D4 Visible error state.** A document navigated into a WebView2 whose core never initialized is not visible: `WebView2.NavigateToString` requires a live core (host remark at `WebView2BreadcrumbHost.cs:171-172`). The visible carrier is therefore the existing folder-area label `EfcViewer.label2` (internal field, `EfcViewer.Designer.cs:4248`, text `"Matched Folders:"` at `:239`), whose text becomes `FolderAreaInitializationFailedText` on final failure. No new WinForms control and no Designer edit. The router still renders the banner document (spec decision 2) and hands it to the host; the host gains the same pre-initialization log-and-drop guard on `NavigateToString` that `PostMessageJson` already has (`WebView2BreadcrumbHost.cs:196-208`), so the failure path throws nothing. This refines spec "Settled scope decision 2" without changing any AC text; the orchestrator is asked to acknowledge it (reported in the handoff).
+- **D5 Router failure entry point.** `BreadcrumbBridgeRouter.NotifyInitializationFailed(Exception)` is a sibling of `NotifyCoreInitialized`, which is unchanged. It discards `_pendingDocument` explicitly, calls `BreadcrumbOutboundQueue.DiscardPending()` (new, returns the discarded count), replaces `_rows` with one banner row `InitializationFailedBannerText`, clears the selection (raising `SelectedFolderPathChanged` only when it changes), navigates the rendered error document through the host, and logs one error line with both discard facts. Discard, not drain: the host cannot post to a core that does not exist.
+- **D6 Pop-out carry.** New partial `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` receives the two `PopOut*` members. `ReadPopOutCarry(QfcItemGroup)` (pure, static) reads the handler through the new `QfcItemController.FolderHandler` internal accessor by pattern match on the concrete type, and the helper through `IQfcItemController.ItemHelper`; it runs BEFORE `RemoveSpecificControlGroup(Async)` because `QfcItemController.Cleanup` nulls both `_folderHandler` (`ViewerSetup.cs:444`) and `ItemHelper` (`:455`). Construction goes through `PopOutHomeControllerFactory` (named default `CreatePopOutHomeController`). `EfcHomeController` constructors (`EfcHomeController.cs:47-52` and `:54-95`) gain trailing optional `IFolderSearchHandler carriedFolderHandler = null, MailItemHelper carriedMailHelper = null` and deposit both on `DataModel` between `DataModelFactory` (`:66`) and `FormControllerWithDataFactory` (`:85`), because the production factory calls `Initialize()`, which fires `PopulateFolderCombobox` and therefore `InitFolderHandlerAsync`.
+- **D7 Adoption.** `QuickFiler/Controllers/EfcDataModel.Carry.cs` receives `InitFolderHandlerAsync` (moved from `EfcDataModel.cs:188-221`), `CarriedFolderHandler`, `CarriedMailHelper`, and the pure decision `TryAdoptCarriedFolderHandler(object folderList, IFolderSearchHandler carried, out FolderPredictor adopted)`: true only when `folderList is null` and `carried is FolderPredictor`. When adopted, `FolderHelper = adopted` and the carry is released. Otherwise the existing body runs, with `MailInfo ?? CarriedMailHelper` as the scoring input in the null-list branch (identical to today whenever no helper was carried), and the carry is released at the end of that branch. The explicit-list branch is untouched.
+- **D8 UI-thread construction.** `EfcViewerQueue.ProductionBlockingPriorityScheduler` default (line 25) and its reset (line 68) change from the inline lambda to the named method `InvokeOnUiDispatcher(Action, DispatcherPriority)`, expression-bodied over `UiThread.Dispatcher.Invoke(action, priority)` so it carries exactly one sequence point, mirroring `ItemViewerQueue.cs:26-27`. `UiThread.Dispatcher` throws `InvalidOperationException` when `Init` has not run (`UtilitiesCS/Threading/UiThread.cs:264-282`), so no test invokes the default; tests assert delegate identity by `.Method.Name` against the literal `InvokeOnUiDispatcher` (a named method group, not a lambda). This half is verifiable only as a scheduler-delegate assertion, as the spec states.
+- **D9 Six-way split.** `EfcFormController.cs` (1321) becomes `internal partial class` and is split by its existing regions: retained `EfcFormController.cs` = lines 1-264 (usings, constructors, private properties, the sink members); `EfcFormController.SetupAndProperties.cs` = 266-479; `EfcFormController.EventHandlers.cs` = 481-834; `EfcFormController.Actions.cs` = 836-990; `EfcFormController.Breadcrumb.cs` = 1044-1129 (`ConfigureBreadcrumbControl`, `InitializeBreadcrumbHostAsync`, `BindFolderRows`, `BindSourceFolderRows`, `BindBreadcrumbRowsAsync`); `EfcFormController.Helpers.cs` = 992-1043 plus 1131-1289 plus 1291-1319. Each new part carries the retained file's full using block (lines 1-22). The split is a pure move proven by the conservation gate in [P2-T1], then behaviour lands only in `EfcFormController.Breadcrumb.cs` ([P4-T7]).
+- **D10 Coverage scope and floors.** Baseline and final coverage are measured over `QuickFiler.Test.dll` only, via `scripts/vscode/Invoke-MSTestWithCoverage.ps1 -SearchRoot QuickFiler.Test`. Reason: the only production project in the write set is `QuickFiler`; the only projects referencing it are `TaskMaster` (`TaskMaster/TaskMaster.csproj:501`) and `QuickFiler.Test` (`QuickFiler.Test/QuickFiler.Test.csproj:481`); and four `UtilitiesCS.Test` shell-icon classes hang `vstest` on this workstation (environmental, recorded in the maintainer's memory 2026-09-04). `TaskMaster.Test.dll` is run as a plain regression sweep with the hang and LiveOutlook exclusions. The repository-wide floor stated by `CLAUDE.md` (UT2, `>= 80%`), `.claude/rules/csharp.md` (`>= 80%`), `.claude/rules/general-unit-test.md` (`>= 85%` line, `>= 75%` branch) and `.claude/rules/quality-tiers.md` is therefore NOT measured repository-wide by this plan; the document-level `line-rate` of the single-assembly run is recorded as `QUICKFILER-SCOPED-DOCUMENT-LINE-RATE: ` and is compared to no floor; every coverage artifact also carries the line `REPO-WIDE-FLOOR: NOT MEASURED (single test assembly; see D10)`; the tokens `BASELINE_FLOOR`, `FINAL_FLOOR`, `MET` and `NOT MET` appear in no artifact. A multi-assembly run is not available through the runner: its `/TestCaseFilter` is hard-coded (`Invoke-MSTestWithCoverage.ps1:91`), it exposes no filter parameter (`:1-13`), and `-SearchRoot .` sweeps every `*.Test.dll` (`:330-337`) including the four `UtilitiesCS.Test` shell-icon classes; the runner is outside the write set. The operative hard gates are: per-file `>= 90%` for the wholly new instrumented production file `WebView2EnvironmentContract.cs`; `>= 90%` over the new executable lines of the instrumented relocated parts (`EfcFormController.Breadcrumb.cs`, `EfcDataModel.Carry.cs`); changed-line no-regression on every instrumented edited file; and type-level covered-count no-regression across the split parts. `EfcItemController` (`EfcItemController.cs:26`) and `QfcCollectionController` (`QfcCollectionController.cs:22`) carry class-level `[ExcludeFromCodeCoverage]`, so their new partials have no Cobertura rows and are recorded under `Uninstrumented, not comparable`; `QfcItemController.InitializeWebViewAsync` is method-level exempt (`ViewerSetup.cs:48`).
+- **D11 Manual gates.** AC-U5 is human-executed per the runbook and is never automated, never a `[TestMethod]`, never counted toward any figure. Outlook must be CLOSED through its own exit, never killed, before every `msbuild` invocation in this plan; every build task begins with the `CMD-OUTLOOK` check and HALTS for a human if `OUTLOOK` is running. No task calls `Stop-Process`.
+- **D12 Evidence.** Per the maintainer decision recorded in spec decision 6, no `.trx` and no `.cobertura.xml` is written under the feature folder; raw tool output goes to the gitignored `coverage/` tree (`.gitignore:144`) and only Markdown projections are committed. Every evidence artifact carries `Timestamp:`, `Command:`, `EXIT_CODE:`, `Output Summary:`.
+- **D13 Diff bases.** Every diff, merge base and footprint gate is anchored to `BASE-SHA` = `git merge-base HEAD origin/main` captured after `git fetch origin` in [P0-T7], re-read by every consuming task from that artifact. Bare local `main` is never used.
+- **D14 Test parallelism.** `scripts/vscode/TaskMaster.cli.runsettings` stays byte-identical (`Workers=0`, `ClassLevel`). No new `[DoNotParallelize]`, no sleeps, no retries. New test classes touch no shared static except reads of `EfcViewerQueue` delegates and no writes; `ResetProductionCoreDefaultsForTesting()` is called by no new test because `ViewerQueueStaticWrapperTests.cs:254` substitutes the same delegate and restores it at `:18`; the only writer of those statics is that pre-existing `[DoNotParallelize]` class. `UserFaultNotifier` is `AsyncLocal` (`EfcFormController.cs:170-185`); tests set it on their own flow and restore in `finally`.
+
+## Conventions binding every task
+
+1. **Working directory.** Every command runs from ``, the item worktree root, with that directory current; `` is substituted at run time and is never written into any artifact. Repository-relative paths below are relative to it.
+2. **No shell state survives between tasks.** Every fenced block re-binds what it uses. `$BaseSha` is always derived by `Select-String -CaseSensitive -Pattern '^BASE-SHA: ([0-9a-f]{40})$'` and `$SpecRefSha` by `'^SPEC-REF-SHA: ([0-9a-f]{40})$'` over `$FEATURE/evidence/baseline/p0-t7-git-base.md` (CMD-BASE binds both); a missing match is a HALT.
+3. **Line counts** use `(Get-Content -LiteralPath ).Count` (total lines). Never `Measure-Object -Line`, never non-blank counts. The 500-line ceiling applies to `.cs` files only; `.csproj` files are exempt (`.csharpierignore:9-14`).
+4. **Formatter observation.** `dotnet tool run csharpier format .` prints `Formatted N files in` whether or not it rewrote anything; the rewritten count is defined as the number of write-set `.cs` files whose SHA-256 differs before and after. `dotnet tool run csharpier check .` prints `Checked N files in` and exits 0 on a clean tree.
+5. **Green vstest output** prints `Test Run Successful.`, `Total tests: N`, `Passed: N`; it prints no `Failed:` or `Skipped:` line, which is transcribed as `Failed: 0 (omitted category)`.
+6. **Scoped test runs never compile.** Every scoped run is preceded by `CMD-BUILD-PLAIN` in the same task. A run that discovers zero tests is a FAILURE of that task.
+7. **No `EXIT_CODE: SKIPPED`.** No task authorizes a skip branch. Human checkpoints ([P0-T2], [P7-T1], [P8-T1], [P8-T2]) HALT and wait; they do not skip.
+8. **Backslashes.** No doubled backslash appears in this plan. Path comparisons normalise with `.Replace('\', '/')` first. Any helper snippet longer than one statement is written to the single gitignored helper path `coverage/plan792-helper.ps1` (rewritten in place; not a deliverable, registered in no project, asserted by no gate) and run with `pwsh -NoProfile -WorkingDirectory -File coverage/plan792-helper.ps1`. The helper's opening branch assertion is the worktree proof; `(Get-Location).Path` is never written to an artifact, and every path the helper prints is repository-relative.
+9. **Git gates** are scoped: `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` for clean-source gates; docs, evidence and `.claude/agent-memory/**` are expected to be dirty and never enumerated as tolerated files.
+10. **Mutation tasks** (Phase 5) run only after the Phase 4 commit, so `git checkout -- ` restores the implemented state.
+11. **Halt rule.** Any acceptance clause that fails HALTS the task with a `BLOCKED:` report; the executor never edits `spec.md` criteria text and never widens the write set.
+
+## Named literals the plan creates (quoted here so a later search is not judged vacuous)
+
+Production identifiers: `WebView2EnvironmentContract`, `AdditionalBrowserArguments`, `UserDataFolderName`, `ResolveUserDataFolder`, `CreateOptions`, `WebViewInitializer`, `NotifyInitializationFailed`, `InitializationFailedBannerText`, `DiscardPending`, `BreadcrumbHostInitializer`, `BreadcrumbInitializationAttemptLimit`, `FolderAreaInitializationFailedText`, `ShowFolderAreaError`, `InitializeBreadcrumbHostOnceAsync`, `CarriedFolderHandler`, `CarriedMailHelper`, `TryAdoptCarriedFolderHandler`, `ReleaseCarry`, `FolderHandler`, `ReadPopOutCarry`, `PopOutHomeControllerFactory`, `CreatePopOutHomeController`, `InvokeOnUiDispatcher`.
+
+Production string literals: `"--incognito "`, `"WindowsFormsWebView2"`, `"Matched Folders: unavailable (breadcrumb initialization failed)"`, `" Folder list unavailable: breadcrumb initialization failed"` (appended to `BreadcrumbRowBuilder.BannerPrefix`), `"NavigateToString called before CoreWebView2 initialization; document dropped."`, `"Breadcrumb initialization canceled."`, and the fault message shape `Breadcrumb WebView2 initialization failed after 3 attempts:` (interpolated from the const, asserted by the token `after 3 attempts`).
+
+Test method names (one per line so each is a single-line token):
+`InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam`
+`NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing`
+`PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink`
+`InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser`
+`ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke`
+`AdditionalBrowserArguments_IsAsciiDoubleHyphenIncognitoWithTrailingSpace`
+`ResolveUserDataFolder_CombinesLocalApplicationDataWithTheSharedLeafName`
+`CreateOptions_CarriesTheSharedArgumentsOnAFreshInstance`
+`EfcItemController_InitializeWebViewAsync_PassesTheContractValuesThroughTheSeam`
+`NotifyInitializationFailed_ClearsThePendingDocumentAndNavigatesTheErrorBanner`
+`NotifyInitializationFailed_LeavesNoStashForALaterInitialization`
+`NotifyInitializationFailed_WithNullFailure_Throws`
+`NotifyCoreInitialized_AfterAnEarlierStash_StillNavigatesIt`
+`DiscardPending_ReturnsTheDiscardedCountAndLeavesZeroPending`
+`DiscardPending_OnAnEmptyQueue_ReturnsZero`
+`NotifyInitializationFailed_DiscardsTheOutboundQueueWithoutPosting`
+`InitializeBreadcrumbHostAsync_RetriesUpToTheAttemptLimitThenReportsOnce`
+`InitializeBreadcrumbHostAsync_SucceedsOnALaterAttempt_ReportsNothing`
+`InitializeBreadcrumbHostAsync_WhenCanceled_DoesNotRetryOrReport`
+`InitializeBreadcrumbHostAsync_OnFinalFailure_ShowsTheErrorTextInTheFolderAreaLabel`
+`InitializeBreadcrumbHostAsync_OnFinalFailure_NotifiesTheRouter`
+`TryAdoptCarriedFolderHandler_WithNullListAndConcretePredictor_Adopts`
+`TryAdoptCarriedFolderHandler_WithNullCarry_DoesNotAdopt`
+`TryAdoptCarriedFolderHandler_WithNonPredictorHandler_DoesNotAdopt`
+`TryAdoptCarriedFolderHandler_WithExplicitListAndPredictor_DoesNotAdopt`
+`InitFolderHandlerAsync_WithCarriedPredictor_AdoptsItAndReleasesTheCarry`
+`InitFolderHandlerAsync_WithNonPredictorCarry_RunsTheExistingPathAndReleasesTheCarry`
+`ReadPopOutCarry_WithConcreteItemController_ReturnsHandlerAndHelper`
+`ReadPopOutCarry_WithInterfaceOnlyController_ReturnsNullHandlerAndTheHelper`
+`ReadPopOutCarry_WithNullController_ReturnsNulls`
+`PopOutHomeControllerFactory_DefaultIsTheNamedProductionFactory`
+`EfcHomeController_DepositsTheCarryOnTheDataModelBeforeConstructingTheFormController`
+
+Test class names: `WebView2BreadcrumbHostIssue792Tests`, `WebView2EnvironmentContractTests`, `BreadcrumbBridgeRouterIssue792Tests`, `BreadcrumbOutboundQueueIssue792Tests`, `EfcFormControllerIssue792Tests`, `EfcDataModelIssue792CarryTests`, `QfcCollectionControllerIssue792PopOutTests`, `EfcViewerQueueIssue792Tests`.
+
+## Command reference (paste verbatim into each task that names it)
+
+CMD-OUTLOOK (human checkpoint inside every build task):
+
+```powershell
+$outlook = Get-Process -Name OUTLOOK -ErrorAction SilentlyContinue
+if ($outlook) { Write-Output 'HALT: Outlook is running. Close Outlook through File > Exit (never end the process), then re-run this task.'; exit 2 }
+Write-Output 'OUTLOOK-CLOSED: true'
+```
+
+CMD-BASE (binds `$BaseSha` and `$SpecRefSha`):
+
+```powershell
+$m = Select-String -LiteralPath 'docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t7-git-base.md' -CaseSensitive -Pattern '^BASE-SHA: ([0-9a-f]{40})$'
+if (-not $m) { throw 'BASE-SHA line missing' }
+$BaseSha = $m.Matches[0].Groups[1].Value
+$s = Select-String -LiteralPath 'docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/evidence/baseline/p0-t7-git-base.md' -CaseSensitive -Pattern '^SPEC-REF-SHA: ([0-9a-f]{40})$'
+if (-not $s) { throw 'SPEC-REF-SHA line missing' }
+$SpecRefSha = $s.Matches[0].Groups[1].Value
+```
+
+CMD-VSTEST (binds `$vstest`; vswhere is not on PATH):
+
+```powershell
+$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio/Installer/vswhere.exe'
+$vstest = & $vswhere -latest -products * -find 'Common7/IDE/Extensions/TestPlatform/vstest.console.exe' | Select-Object -First 1
+if (-not $vstest) { throw 'vstest.console.exe not found' }
+```
+
+CMD-BUILD-PLAIN (produces test assemblies; not a gate): `msbuild TaskMaster.sln /t:Build /m /p:Configuration=Debug "/p:Platform=Any CPU"`
+
+CMD-BUILD-ANALYZE (gate): `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=true`
+
+CMD-BUILD-NULLABLE (gate): `msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=true` (no `/p:Nullable=enable`, ever)
+
+CMD-SCOPED-RUN (QuickFiler.Test only; `` is spelled out by each task; TRX goes to the gitignored `coverage/test-results/` directory):
+
+```powershell
+& $vstest QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:" "/ResultsDirectory:coverage/test-results/" "/Logger:trx;LogFileName=.trx"
+```
+
+CMD-COVERAGE (QuickFiler.Test scope; raw output gitignored):
+
+```powershell
+pwsh -NoProfile -WorkingDirectory -File scripts/vscode/Invoke-MSTestWithCoverage.ps1 -SearchRoot QuickFiler.Test -Configuration Debug -CoverageOutput coverage/.cobertura.xml
+```
+
+The script accepts only `-SearchRoot`, `-Configuration`, `-CoverageOutput` and `-NoExecute` (`Invoke-MSTestWithCoverage.ps1:1-13`); the TRX of every stage is the runner default `coverage/test-results/mstest-coverage-run.trx` and is overwritten by the next stage, so each stage transcribes its console `Total tests:` and `Passed:` lines before the next stage runs. The runner also writes `coverage/.jacoco.xml` and `coverage/test-results/mstest-coverage-run.summary.txt` (both gitignored). The processed document is retained only because its parent directory is exactly `coverage/` (`Invoke-MSTestWithCoverage.Projection.ps1:148-163`); it is never redirected into a subdirectory. `` is the item worktree root, substituted at run time and never written into an artifact. The runner writes the post-processed document at its line 384 BEFORE the 80 percent assertion at line 386 throws, so a non-zero exit caused solely by the message `is below the required 80% threshold` still leaves a processed document (it contains the literal ``) and the task continues. Any other non-zero exit is a HALT. On success the runner prints `Done. Coverage artifact:`.
+
+CMD-SWEEP (TaskMaster.Test regression sweep, no coverage):
+
+```powershell
+& $vstest TaskMaster.Test/bin/Debug/TaskMaster.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolation "/TestCaseFilter:TestCategory!=LiveOutlook" "/Blame:CollectHangDump;TestTimeout=4min;HangDumpType=None" "/ResultsDirectory:coverage/test-results/" "/Logger:trx;LogFileName=.trx"
+```
+
+CMD-AC-U6-GATE (structural parity; run unchanged in [P0-T14] expecting FAIL and in [P6-T1] expecting PASS; write it once to `coverage/plan792-helper.ps1` and invoke as `pwsh -NoProfile -WorkingDirectory -File coverage/plan792-helper.ps1`; the opening branch assertion is the worktree proof and `(Get-Location).Path` is never written to an artifact):
+
+```powershell
+$branch = git rev-parse --abbrev-ref HEAD
+if ($branch -ne 'bug/breadcrumb-webview2-init-fails-resource-not-in-correct-state-792') { throw "wrong worktree: $branch" }
+$root = (Get-Location).Path
+function Rel([string]$p) { return $p.Substring($root.Length).TrimStart('\', '/').Replace('\', '/') }
+$files = git ls-files -- ':(glob)QuickFiler/**/*.cs' | Where-Object { $_ -notmatch '\.Designer\.cs$' }
+$hits = foreach ($f in $files) { Select-String -LiteralPath $f -Pattern 'CoreWebView2EnvironmentOptions' | Where-Object { $_.Line -notmatch '^\s*//' } }
+$constructions = @($hits | Where-Object { $_.Line -match 'new\s+CoreWebView2EnvironmentOptions\s*\(' -or $_.Line -match 'CoreWebView2EnvironmentOptions\s+\w+\s*=\s*new\s*\(' })
+$createAsync = @(foreach ($f in $files) { Select-String -LiteralPath $f -Pattern 'CoreWebView2Environment\.CreateAsync\(' | Where-Object { $_.Line -notmatch '^\s*//' -and $_.Path.Replace('\', '/') -notmatch '(^|/)WebView2CoreInitializer\.cs$' } })
+$seamCallers = @(foreach ($f in $files) { Select-String -LiteralPath $f -Pattern '\.CreateEnvironmentAsync\(' | Where-Object { $_.Line -notmatch '^\s*//' } })
+$contractReaders = @(foreach ($f in $files) { Select-String -LiteralPath $f -Pattern 'WebView2EnvironmentContract\.CreateOptions\(' | Where-Object { $_.Line -notmatch '^\s*//' } })
+Write-Output "PRIMARY-CONSTRUCTION-COUNT: $($constructions.Count)"
+$constructions | ForEach-Object { Write-Output "PRIMARY-SITE: $(Rel $_.Path):$($_.LineNumber)" }
+Write-Output "CREATEASYNC-OUTSIDE-ADAPTER: $($createAsync.Count)"
+$createAsync | ForEach-Object { Write-Output "CREATEASYNC-SITE: $(Rel $_.Path):$($_.LineNumber)" }
+Write-Output "SEAM-CALLER-COUNT: $($seamCallers.Count)"
+$seamCallers | ForEach-Object { Write-Output "SEAM-CALLER: $(Rel $_.Path):$($_.LineNumber)" }
+Write-Output "CONTRACT-READER-COUNT: $($contractReaders.Count)"
+$contractReaders | ForEach-Object { Write-Output "CONTRACT-READER: $(Rel $_.Path):$($_.LineNumber)" }
+$pass = ($constructions.Count -eq 1) -and ($constructions[0].Path.Replace('\', '/') -match '(^|/)QuickFiler/Viewers/WebView2EnvironmentContract\.cs$') -and ($createAsync.Count -eq 0) -and ($seamCallers.Count -eq 3) -and ($contractReaders.Count -eq 3)
+Write-Output "AC-U6-STRUCTURAL: $(if ($pass) { 'PASS' } else { 'FAIL' })"
+```
+
+Expected on the unfixed tree: `PRIMARY-CONSTRUCTION-COUNT: 3` (host 250, ViewerSetup 62, EfcItemController 188), `CREATEASYNC-OUTSIDE-ADAPTER: 1` (EfcItemController 195), `SEAM-CALLER-COUNT: 2` (host 265, ViewerSetup 71), `CONTRACT-READER-COUNT: 0`, `AC-U6-STRUCTURAL: FAIL`. Expected on the fixed tree: 1 (the contract file), 0, 3, 3, PASS. The dead comment lines `ViewerSetup.cs:61`, `EfcItemController.cs:187` and `ViewerSetup.cs:124` are excluded by the `^\s*//` filter, which is what defeats the file-granularity trap recorded in the research record.
+
+## Write set and scope lock
+
+Production (QuickFiler.csproj): `Viewers/WebView2EnvironmentContract.cs` (new), `Viewers/WebView2BreadcrumbHost.cs`, `Controllers/QfcItemController.ViewerSetup.cs`, `Controllers/EfcItemController.cs`, `Controllers/EfcItemController.WebViewEnvironment.cs` (new), `Controllers/BreadcrumbBridgeRouter.cs`, `Controllers/BreadcrumbOutboundQueue.cs`, `Controllers/EfcFormController.cs`, `Controllers/EfcFormController.Breadcrumb.cs` (new), `Controllers/EfcFormController.SetupAndProperties.cs` (new), `Controllers/EfcFormController.EventHandlers.cs` (new), `Controllers/EfcFormController.Actions.cs` (new), `Controllers/EfcFormController.Helpers.cs` (new), `Controllers/QfcCollectionController.cs`, `Controllers/QfcCollectionController.PopOut.cs` (new), `Controllers/EfcHomeController.cs`, `Controllers/EfcDataModel.cs`, `Controllers/EfcDataModel.Carry.cs` (new), `Controllers/QfcItemController.cs`, `Helper Classes/EfcViewerQueue.cs`, `QuickFiler/QuickFiler.csproj`.
+
+Tests (QuickFiler.Test.csproj): `Viewers/WebView2BreadcrumbHostIssue792Tests.cs`, `Viewers/WebView2EnvironmentContractTests.cs`, `Controllers/BreadcrumbBridgeRouterIssue792Tests.cs`, `Controllers/BreadcrumbOutboundQueueIssue792Tests.cs`, `Controllers/EfcFormControllerIssue792Tests.cs`, `Controllers/QfcCollectionControllerIssue792PopOutTests.cs`, `Controllers/EfcDataModelIssue792CarryTests.cs`, `Helper Classes/EfcViewerQueueIssue792Tests.cs` (all new), `Controllers/EfcFormControllerTests.cs` (listed by the spec; this plan makes NO edit to it because its 15-line headroom cannot hold the strengthened test, which lives in `EfcFormControllerIssue792Tests.cs` instead; recorded as a zero-diff observation in [P6-T3]), `QuickFiler.Test/QuickFiler.Test.csproj`.
+
+Scope lock: no other `.cs`, `.csproj`, `.config`, `.runsettings` or policy file changes. Compile items are bare self-closing ` ` elements with no metadata, inserted adjacent to the neighbours named in each creating task.
+
+Files with class-level `[ExcludeFromCodeCoverage]` touched by this plan: `EfcItemController` (`EfcItemController.cs:26`), `QfcCollectionController` (`QfcCollectionController.cs:22`). Their partials are uninstrumented.
+
+## Constraint blocks (propagated verbatim; every child prompt must carry all five)
+
+[BLOCK: OBSERVED-FAILING CRITERIA — propagate verbatim]
+Every acceptance criterion used as a gate must be OBSERVED FAILING on the unfixed tree before it is accepted, and the plan must include running it against the unfixed tree to demonstrate that. A criterion never seen failing is unproven. Two failure modes: one that cannot be satisfied at all, and one satisfied with no fix present — the second is more dangerous because it reports success. Prove non-vacuity by mutation where practical, with each mutation failing on its pre-predicted assertion.
+[END BLOCK]
+
+[BLOCK: TEST PARALLELISM — propagate verbatim]
+Tests must ALWAYS run in parallel. `scripts/vscode/TaskMaster.cli.runsettings` with Workers=0 and Scope=ClassLevel is correct and must remain byte-identical. Never fix a parallel-execution failure with Workers=1, removing Parallelize, [DoNotParallelize], dropping /Settings:, retries, timing tolerance, or sleeps. If a test needs a distinct thread, create and join a dedicated Thread so the property is controlled, not assumed — see issue #900 for the working pattern.
+[END BLOCK]
+
+[BLOCK: DIFF BASES — propagate verbatim]
+Anchor every diff base, merge base and change-footprint gate to `origin/main` after a fetch, never to bare local `main`. Only the pulling checkout advances local `main`, so it is almost always stale and any gate anchored to it is unsatisfiable by construction. Three-dot does not rescue it: when the pinned ref is an ancestor of HEAD, `merge-base(PINNED,HEAD)` IS the pinned SHA. Run both forms and compare.
+[END BLOCK]
+
+[BLOCK: SCOPE AND COMMIT — propagate verbatim]
+Commit your work to the item worktree branch before ending. Never write to another item's canonical state — if a hook can only be satisfied by modifying a file another item owns, STOP AND REPORT. Do not write to `.claude/agent-memory` in a session worktree you do not own; note that `Set-Location` does not update .NET's `CurrentDirectory`, so `System.IO` calls with relative paths can escape the worktree.
+[END BLOCK]
+
+[BLOCK: BASH DISCIPLINE — propagate verbatim]
+Settings allow only `git *`, `pwsh *`, `poetry run *` and three lib scripts; every chained segment must match, so `cd X && ...`, grep, sed and cat via Bash will prompt. Use `git -C` and the Read/Grep/Glob tools. Gated-command hooks scan the WHOLE command string, so prose merely naming a gated tool inside a commit message or a `-b` body trips the block — write text to a file and use `-F body=@file`. Never chain a state write with a gated command.
+[END BLOCK]
+
+## Observed-failing map (which run demonstrates each gate failing on the unfixed tree)
+
+| AC | Observed failing at | Non-vacuity mutation |
+|---|---|---|
+| AC-U1 | [P3-T7] (retry, label, router tests) | [P5-T5] attempt limit |
+| AC-U2 | [P3-T7] (pending-cleared tests) | [P5-T7] pending not cleared |
+| AC-U3 | [P3-T7] (adoption, carry read); UI-thread half at [P1-T4] | [P5-T6] deposit removed, [P5-T8] adoption disabled |
+| AC-U4 | `InitializeBreadcrumbHostAsync` half at [P1-T4]; `PopulateFolderCombobox` half CANNOT be observed failing (already satisfied at `EfcFormController.cs:1270`), dossier at [P0-T15] | [P5-T1] notifier dropped |
+| AC-U5 | manual; not a gate | none |
+| AC-U6 | [P0-T14] structural gate FAIL; [P1-T4] site-1 seam test | [P5-T2] site-1 regression and site-2 regression (structural), [P5-T3] constant |
+| AC-U7 | [P3-T7] (queue tests) | [P5-T4] discard skipped |
+| AC-U8 | [P0-T8] records the seventeen new paths ABSENT and the pre-change counts (the gate's FAIL state) | measured, not mutated |
+| AC-U9 | documentary; measured before/after in [P6-T2] | none |
+
+### Phase 0 — Policy Reads, Toolchain Bootstrap, and Baselines
+
+- [x] [P0-T1] Read the policy files in the `policy-compliance-order` sequence — `CLAUDE.md`, `.claude/rules/general-code-change.md`, `.claude/rules/general-unit-test.md`, `.claude/rules/csharp.md`, `.claude/rules/quality-tiers.md`, `.claude/rules/tonality.md`, `.claude/rules/plan-acceptance-gates.md` — then read `$FEATURE/spec.md`, `$FEATURE/user-story.md` and `$FEATURE/research/2026-09-17T11-20-breadcrumb-webview2-init-research.md`, and write `$FEATURE/evidence/baseline/phase0-instructions-read.md`.
+ - Acceptance: the artifact contains `Timestamp:`, `Policy Order:` listing the seven policy files in the order above, an explicit `Files Read:` list naming all ten files, and the line `Work Mode: full-bug` copied from `issue.md` line 12. The executor records that `spec.md` lines 306-314 hold exactly nine `- [ ] AC-U` checkbox lines (mechanical count: `Select-String -LiteralPath $FEATURE/spec.md -Pattern '^- \[ \] AC-U[1-9]:'` returns 9 matches).
+- [x] [P0-T2] Human checkpoint before any build: confirm Outlook is closed through its own exit and record `$FEATURE/evidence/other/p0-t2-outlook-closed.md`.
+ - Command: CMD-OUTLOOK.
+ - Acceptance: output contains `OUTLOOK-CLOSED: true`; artifact carries `Timestamp:`, `Command:`, `EXIT_CODE: 0`, `Output Summary:` and the sentence that Outlook was closed by a person through its normal exit and no process was ended. If the command printed `HALT:`, the task waits for the human and is re-run; `EXIT_CODE: 2` is never a pass.
+- [x] [P0-T3] Bootstrap the repo-local .NET SDK with `pwsh -NoProfile -File scripts/vscode/Install-RepoDotNetSdk.ps1` and record `$FEATURE/evidence/baseline/p0-t3-sdk.md`.
+ - Acceptance: `dotnet --version` run from `` prints a version beginning `8.0.` (not the `global.json` `errorMessage`); the artifact records `DOTNET-VERSION: ` and `SDK-UNDER-REPO-LOCAL-DIR: true|false` computed from the `--list-sdks` output (true when at least one line's path segment ends `.dotnet-sdk/sdk` after `.Replace('\', '/')`), which is not transcribed because it carries the account name; `SDK-UNDER-REPO-LOCAL-DIR: false` is a HALT. `.dotnet-sdk/` is gitignored (`.gitignore:350`), so the tree stays clean.
+- [x] [P0-T4] Restore the manifest tool with `dotnet tool restore` (manifest is the repository-root `dotnet-tools.json`) and record `$FEATURE/evidence/baseline/p0-t4-tool-restore.md`.
+ - Acceptance: `EXIT_CODE: 0`; `dotnet tool list` prints a row whose first column is `csharpier` and second column is `1.2.6`; both outputs are in `Output Summary:`.
+- [x] [P0-T5] Restore NuGet packages for the solution with `pwsh -NoProfile -File scripts/vscode/Invoke-Restore.ps1` (msbuild `/t:Restore /p:RestorePackagesConfig=true`) and record `$FEATURE/evidence/baseline/p0-t5-nuget-restore.md`.
+ - Acceptance: `EXIT_CODE: 0`; `Test-Path packages/Moq.4.20.72` or, if that exact folder does not exist, `(Get-ChildItem packages -Directory -Filter 'Moq.*').Count -ge 1` is true (the executor records which form held); every `` path in `QuickFiler/QuickFiler.csproj` and `QuickFiler.Test/QuickFiler.Test.csproj` resolves under `Test-Path` when joined to the declaring project's directory (record `ANALYZER-PATHS-RESOLVED: of `); a mismatch is a HALT (environment defect, not a plan defect).
+- [x] [P0-T6] Ensure the `dotnet-coverage` global tool exists (`if (-not (Get-Command dotnet-coverage -ErrorAction SilentlyContinue)) { dotnet tool install --global dotnet-coverage }`) and record `$FEATURE/evidence/baseline/p0-t6-dotnet-coverage.md`.
+ - Acceptance: `Get-Command dotnet-coverage` succeeds; the artifact records only `DOTNET-COVERAGE-PRESENT: true` and the tool's `--version` output, never the resolved path (it contains the account name).
+- [x] [P0-T7] Capture the git base: `git fetch origin`, then record `$FEATURE/evidence/baseline/p0-t7-git-base.md`.
+ - Commands: `git rev-parse HEAD`; `git rev-parse origin/main`; `git merge-base HEAD origin/main`; `git merge-base --is-ancestor origin/main HEAD; $LASTEXITCODE`; `git status --porcelain --untracked-files=all`; `git diff --name-status (git merge-base HEAD origin/main) HEAD`.
+ - Acceptance: the artifact contains exactly one line `BASE-SHA: <40 hex>` whose value equals the merge-base output; a line `ORIGIN-MAIN-IS-ANCESTOR: true|false` with the explicit note that when true the merge base IS the `origin/main` SHA (both forms compared, per the DIFF BASES block); `HEAD-OBSERVED:` (observation only, never an expectation); a line `SPEC-REF-SHA: <40 hex>` equal to the `git rev-parse HEAD` output, with the note that the feature folder does not exist at `BASE-SHA`, so criterion-text immutability is checked against `SPEC-REF-SHA`; the verbatim porcelain output; and the type assertion `PORCELAIN-SOURCE-PATHS: 0` computed as the count of porcelain lines whose path ends `.cs`, `.csproj`, `.sln` or `packages.config`. A non-zero source-path count is a HALT. The name-status list is recorded verbatim under a heading `BASE-TO-HEAD-NAME-STATUS` for later scope gates.
+- [x] [P0-T8] Record the baseline line counts of every write-set `.cs` file and the absence of the seventeen new files in `$FEATURE/evidence/baseline/p0-t8-line-counts.md` (instrument: `(Get-Content -LiteralPath ).Count`).
+ - Acceptance: the artifact lists one row per existing write-set `.cs` path (eleven production, one test) with its count, and the following expected values hold exactly: `QuickFiler/Controllers/EfcFormController.cs` 1321, `QuickFiler/Controllers/EfcItemController.cs` 1122, `QuickFiler/Controllers/QfcCollectionController.cs` 2333, `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs` 479, `QuickFiler/Controllers/EfcDataModel.cs` 499, `QuickFiler/Controllers/EfcHomeController.cs` 447, `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` 407, `QuickFiler/Viewers/WebView2BreadcrumbHost.cs` 368, `QuickFiler/Controllers/QfcItemController.cs` 334, `QuickFiler/Helper Classes/EfcViewerQueue.cs` 101, `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` 67, `QuickFiler.Test/Controllers/EfcFormControllerTests.cs` 485. A different value for any of these twelve is a HALT (stale checkout). Each of the seventeen new paths named in the Write set section is recorded with `ABSENT: true` (`Test-Path` false); any present is a HALT. The line `OVER-CEILING-BEFORE: 3` names the three files above 500.
+- [x] [P0-T9] Formatter baseline (read-only): `dotnet tool run csharpier check .`; record `$FEATURE/evidence/baseline/p0-t9-csharpier-check.md`.
+ - Acceptance: `EXIT_CODE:` recorded (0 or 1); the `Checked N files in` line recorded verbatim; the set of files the check reports as unformatted recorded verbatim under `BASELINE-DRIFT-SET` (empty when exit 0). The line `DRIFT-IN-WRITE-SET: ` counts drift paths that are write-set members; a non-zero value is recorded, not a halt, and binds [P7-T2].
+- [x] [P0-T10] Analyzer baseline: CMD-OUTLOOK then CMD-BUILD-ANALYZE; record `$FEATURE/evidence/baseline/p0-t10-analyzers.md`.
+ - Acceptance: `OUTLOOK-CLOSED: true` first; `EXIT_CODE: 0`; `Output Summary:` carries the msbuild summary lines matching `Warning\(s\)` and `Error\(s\)` verbatim with `0 Error(s)` asserted by an exact-line match (`^\s+0 Error\(s\)$`, so `10 Error(s)` cannot satisfy it).
+- [x] [P0-T11] Nullable baseline: CMD-OUTLOOK then CMD-BUILD-NULLABLE; record `$FEATURE/evidence/baseline/p0-t11-nullable.md`.
+ - Acceptance: as [P0-T10] (`EXIT_CODE: 0`, exact `0 Error(s)` line).
+- [x] [P0-T12] Coverage baseline over `QuickFiler.Test/bin/Debug/QuickFiler.Test.dll` via CMD-COVERAGE with `` = `p0-baseline`; record `$FEATURE/evidence/baseline/p0-t12-coverage-baseline.md`.
+ - Acceptance: the processed document `coverage/p0-baseline.cobertura.xml` exists and contains the literal ``; `EXIT_CODE:` recorded; when the runner exits non-zero and this run's console carries `is below the required 80% threshold` and its `Failed:` category is omitted, the artifact declares `ExpectedExitCode: 1`; when the runner exits 0 no `ExpectedExitCode` field is written; any other cause is a HALT (the expectation is keyed off this run, never off any other run). The artifact records numerically: root `line-rate`, `branch-rate`, `lines-covered`, `lines-valid`, `branches-covered`, `branches-valid`; the same six for the `package` element named `QuickFiler`; `Total tests:` and `Passed:` transcribed from the console before any later stage overwrites the runner-default TRX; `QUICKFILER-SCOPED-DOCUMENT-LINE-RATE: ` and `REPO-WIDE-FLOOR: NOT MEASURED (single test assembly; see D10)`. Per-file rows (max-hits merge over both `./lines/line` and `./methods/method/lines/line` axes of every `class` whose `filename`, after `.Replace('\', '/')`, matches `(^|/)QuickFiler/$`) for each of: `Viewers/WebView2BreadcrumbHost.cs`, `Controllers/BreadcrumbBridgeRouter.cs`, `Controllers/BreadcrumbBridgeRouter.Selection.cs`, `Controllers/BreadcrumbOutboundQueue.cs`, `Controllers/EfcFormController.cs`, `Controllers/EfcHomeController.cs`, `Controllers/EfcDataModel.cs`, `Controllers/QfcItemController.cs`, `Controllers/QfcItemController.ViewerSetup.cs`, `Helper Classes/EfcViewerQueue.cs` — each row is `covered/valid` plus the full per-line `number:hits` map; and under `Uninstrumented files` the rows `Controllers/EfcItemController.cs` and `Controllers/QfcCollectionController.cs` with `CLASS-ELEMENTS: 0` and the citation of their class-level attribute. A `CLASS-ELEMENTS: 0` result for any of the ten instrumented files is a HALT. The raw XML is not copied under the feature folder.
+- [x] [P0-T13] Regression-sweep baseline over `TaskMaster.Test/bin/Debug/TaskMaster.Test.dll` via CMD-VSTEST then CMD-SWEEP with `` = `p0-t13`; record `$FEATURE/evidence/baseline/p0-t13-taskmaster-sweep.md`.
+ - Acceptance: console `Total tests:` and `Passed:` transcribed (with the omitted-category convention); `BASELINE_FAILURE_SET:` lists every failed fully-qualified test name verbatim or `none`; `EXIT_CODE:` recorded (non-zero only when the failure set is non-empty). A hang (no summary within the Blame timeout) is a HALT naming the in-progress tests from the Blame output.
+- [x] [P0-T14] Run CMD-AC-U6-GATE against the unfixed tree (write the block to `coverage/plan792-helper.ps1`, run it as `pwsh -NoProfile -WorkingDirectory -File coverage/plan792-helper.ps1`; its branch assertion is the worktree proof) and record `$FEATURE/evidence/regression-testing/p0-t14-ac-u6-structural-fail-before.md`.
+ - Acceptance: output lines are exactly `PRIMARY-CONSTRUCTION-COUNT: 3`, three `PRIMARY-SITE:` lines naming `QuickFiler/Controllers/EfcItemController.cs:188`, `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:62`, `QuickFiler/Viewers/WebView2BreadcrumbHost.cs:250`, `CREATEASYNC-OUTSIDE-ADAPTER: 1` followed by one `CREATEASYNC-SITE:` line naming `QuickFiler/Controllers/EfcItemController.cs:195`, `SEAM-CALLER-COUNT: 2` followed by two `SEAM-CALLER:` lines naming `QuickFiler/Controllers/QfcItemController.ViewerSetup.cs:71` and `QuickFiler/Viewers/WebView2BreadcrumbHost.cs:265` (the three `PRIMARY-SITE:` and two `SEAM-CALLER:` lines appear in `git ls-files` order), `CONTRACT-READER-COUNT: 0` (followed by no `CONTRACT-READER:` line), and `AC-U6-STRUCTURAL: FAIL`. The artifact records `OBSERVED-FAILING: AC-U6 structural gate` and the sentence that the dead comment lines 61 (ViewerSetup) and 187 (EfcItemController) were excluded by the comment filter. Any other output is a HALT.
+- [x] [P0-T15] Record the AC-U4 pass-before observation for the `PopulateFolderCombobox` half: CMD-VSTEST, CMD-BUILD-PLAIN (after CMD-OUTLOOK), then CMD-SCOPED-RUN with `` = `FullyQualifiedName~EfcFormControllerTests.PopulateFolderCombobox_WhenDataModelFaults_LogsOnceAndDoesNotFault` and `` = `p0-t15`; write `$FEATURE/evidence/regression-testing/fail-before-exception.p0-t15.md`.
+ - Acceptance: `Total tests: 1`, `Passed: 1`; the dossier carries `WhyFailingRunImpossible:` stating that `TryReportBoundaryFault(ex.Message, ex)` already exists at `QuickFiler/Controllers/EfcFormController.cs:1270`, so this half of AC-U4 cannot be observed failing and its work is the strengthened user-surface test whose non-vacuity is proven by mutation in [P5-T1]; plus `SearchScope:`, `SearchPatterns:`, `SearchResult:` fields.
+- [x] [P0-T16] Commit the Phase 0 artifacts: `git add -- docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792` then `git commit -m "chore(792): phase 0 baselines and plan"`; record `$FEATURE/evidence/baseline/p0-t16-commit.md`.
+ - Acceptance: `EXIT_CODE: 0`; `git show --name-only --format= HEAD` lists only paths under `docs/features/active/2026-09-06-breadcrumb-webview2-init-fails-resource-not-in-correct-state-792/`; `git status --porcelain -- '*.cs' '*.csproj' '*.sln' 'packages.config'` prints nothing; the commit SHA is recorded as an observation.
+
+### Phase 1 — Compile-Clean Regression Tests Observed Failing
+
+These tests reference only members that exist on the unfixed tree, so they compile today and fail at assertion time. Every test class is `[TestClass] public sealed class`, MSTest + Moq + FluentAssertions, Arrange-Act-Assert, no temp files, no sleeps, no `[DoNotParallelize]`.
+
+- [x] [P1-T1] Create `QuickFiler.Test/Viewers/WebView2BreadcrumbHostIssue792Tests.cs` (class `WebView2BreadcrumbHostIssue792Tests`) with two tests, and add ` ` to `QuickFiler.Test/QuickFiler.Test.csproj` immediately after the existing `Viewers\WebView2BreadcrumbHostTests.cs` item (line 218).
+ - Test 1 `InitializeAsync_PassesTheSharedFolderAndIncognitoArgumentToTheSeam`: on a `WinFormsPumpHost` (pattern of `WebView2BreadcrumbHostTests.InitializeAsync_InstallsUiDispatcherFromUiSyncContext`, lines 258-293) construct a `WebView2` and a host over a `Mock` whose `CreateEnvironmentAsync` setup uses `.Callback` to capture both arguments and returns `Task.FromResult(null)`, and whose `EnsureCoreWebView2Async` returns `Task.CompletedTask`; act `await subject.InitializeAsync(pump.SyncContext)`; assert the captured folder equals `Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "WindowsFormsWebView2")` and the captured `options.AdditionalBrowserArguments` equals the literal `"--incognito "`. Pre-fix the second assertion fails (the parameterless options carry null).
+ - Test 2 `NavigateToString_BeforeCoreInitialization_WithNoDispatcher_DropsTheDocumentWithoutThrowing`: construct the host with the internal three-argument constructor and a null dispatcher (never call `InitializeAsync`), act `subject.NavigateToString("")` from the MSTest thread, assert it does not throw and `subject.IsCoreInitialized` is false. Pre-fix the forward reaches `WebView2.NavigateToString` on a control with no core and throws `InvalidOperationException`.
+ - Acceptance: file exists; contains both method names on single lines; the csproj item exists exactly once and is a bare self-closing element adjacent to line 218's item; file line count is at most 200.
+- [x] [P1-T2] Create `QuickFiler.Test/Controllers/EfcFormControllerIssue792Tests.cs` (class `EfcFormControllerIssue792Tests`, namespace `QuickFiler.Controllers.Tests`) with private helpers `CreateMinimalController()` (private no-arg constructor via reflection, as `EfcFormControllerTests.cs:24-34`), `SetPrivateField(object, string, object)` (`BindingFlags.Instance | BindingFlags.NonPublic`), and a `CaptureUserFaults(List)` helper that sets `EfcFormController.UserFaultNotifier` for the current async flow and returns an `IDisposable` restoring the previous value; add two tests; add ` ` to `QuickFiler.Test/QuickFiler.Test.csproj` immediately after the `Controllers\EfcFormControllerTests.Part2.cs` item (line 127).
+ - Test 1 `PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink`: minimal controller, `_formViewer` set to `FormatterServices.GetUninitializedObject(typeof(EfcViewer))`, `BoundaryErrorSink` left at its default, notifier captured; act `await controller.PopulateFolderCombobox()`; assert no throw and the captured list has exactly one entry. This is the strengthened AC-U4 test for the already-satisfied half; it PASSES before the fix and is mutation-proven in [P5-T1].
+ - Test 2 `InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser`: minimal controller (`_breadcrumbHost`, `_router`, `_formViewer` all null), notifier captured; act by invoking the method through `typeof(EfcFormController).GetMethod("InitializeBreadcrumbHostAsync", BindingFlags.Instance | BindingFlags.NonPublic)` and awaiting the returned `Task`; assert no throw and the captured list has exactly one entry whose text contains the token `after 3 attempts`. Pre-fix the null host raises `NullReferenceException`, which the old catch logs only, so the list stays empty.
+ - Acceptance: file exists with both method names on single lines; csproj item present exactly once adjacent to line 127's item; line count at most 260 (Phase 3 appends five more tests; the final ceiling is checked in [P7-T3]).
+- [x] [P1-T3] Create `QuickFiler.Test/Helper Classes/EfcViewerQueueIssue792Tests.cs` (class `EfcViewerQueueIssue792Tests`, namespace `QuickFiler.Test.HelperClasses`) with one identity test, and add ` ` to `QuickFiler.Test/QuickFiler.Test.csproj` immediately after the `Helper Classes\ViewerQueueStaticWrapperTests.cs` item (line 230).
+ - The test `ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke`: read `EfcViewerQueue.ProductionBlockingPriorityScheduler` (no mutation, no write to any static), assert `.Method.Name` equals the literal `"InvokeOnUiDispatcher"` and `.Target` is null. The test does not invoke the delegate (D8) and does not call `ResetProductionCoreDefaultsForTesting()`, because that write belongs to the `[DoNotParallelize]` class `ViewerQueueStaticWrapperTests` (substitutes at `:254`, restores at `:18`). Pre-fix it fails because the default is a lambda whose compiler-generated name is not `InvokeOnUiDispatcher`.
+ - Acceptance: file exists with the method name on a single line; csproj item present exactly once adjacent to line 230's item; the file contains no `DoNotParallelize` token and no `ResetProductionCoreDefaultsForTesting` token; line count at most 120.
+- [x] [P1-T4] [expect-fail] Build and run the Phase 1 classes: CMD-OUTLOOK, CMD-BUILD-PLAIN, CMD-VSTEST, then CMD-SCOPED-RUN with `` = `FullyQualifiedName~WebView2BreadcrumbHostIssue792Tests|FullyQualifiedName~EfcFormControllerIssue792Tests|FullyQualifiedName~EfcViewerQueueIssue792Tests` and `` = `p1-t4`; record `$FEATURE/evidence/regression-testing/p1-t4-fail-before.md`.
+ - Acceptance: build `EXIT_CODE: 0` with `0 Error(s)` (exact line); the run reports `Total tests: 5`, `Passed: 1`, `Failed: 4`; the artifact lists per test `FAIL-BEFORE: | ` for exactly these four: the two host tests, `InitializeBreadcrumbHostAsync_WhenHostIsNull_ReportsThroughTheBoundarySinkToTheUser`, and `ProductionBlockingPriorityScheduler_DefaultIsTheNamedUiDispatcherInvoke`; and `PASS-BEFORE-CONTROL: EfcFormControllerIssue792Tests.PopulateFolderCombobox_WhenDataModelFaults_NotifiesTheUserThroughTheDefaultSink`. Any other split is a HALT. `EXIT_CODE:` records vstest's non-zero exit with `ExpectedExitCode: 1`.
+
+### Phase 2 — Pure Moves, Declaration-Only Seams, and Project Wiring
+
+No behaviour changes in this phase. Every move is verified by a conservation gate: the multiset of non-structural lines (after trimming, dropping blank lines, `using` lines, `namespace` lines, brace-only lines and lines containing `partial class ` or `class `) across the resulting files equals that of the original file at `BASE-SHA`. The gate is:
+
+```powershell
+$filter = { param($lines) $lines | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' -and $_ -notmatch '^using ' -and $_ -notmatch '^namespace ' -and $_ -notmatch '^[{}]$' -and $_ -notmatch 'class \b' } | Sort-Object }
+$before = & $filter (git show "${BaseSha}:")
+$after = & $filter (Get-Content -LiteralPath , , ...)
+$diff = @(Compare-Object $before $after)
+Write-Output "CONSERVATION-DIFF-COUNT: $($diff.Count)"
+```
+
+`` is the moved type's simple name; each task states its own operands. `CONSERVATION-DIFF-COUNT: 0` is the pass condition.
+
+- [x] [P2-T1] Split `QuickFiler/Controllers/EfcFormController.cs` into six partial parts per D9 (retained `EfcFormController.cs` lines 1-264 plus closing braces, and new `QuickFiler/Controllers/EfcFormController.SetupAndProperties.cs`, `EfcFormController.EventHandlers.cs`, `EfcFormController.Actions.cs`, `EfcFormController.Breadcrumb.cs`, `EfcFormController.Helpers.cs` with the line ranges stated in D9, each opened by the retained file's using block lines 1-22, a blank line, `namespace QuickFiler.Controllers`, `{`, `internal partial class EfcFormController`, `{`), change line 26 to `internal partial class EfcFormController : IFilerFormController`, and add five bare Compile items to `QuickFiler/QuickFiler.csproj` immediately after the `Controllers\EfcFormController.cs` item (line 296) in the order Actions, Breadcrumb, EventHandlers, Helpers, SetupAndProperties.
+ - Acceptance: the conservation gate over the six files with `` = `EfcFormController` prints `CONSERVATION-DIFF-COUNT: 0`; every one of the six files is at most 400 lines (`(Get-Content -LiteralPath).Count`); `Select-String -Pattern 'partial class EfcFormController' -LiteralPath` each part returns exactly 1 match and the retained file's match also contains `: IFilerFormController`; `git diff --numstat $BaseSha -- QuickFiler/QuickFiler.csproj` reports 5 insertions and 0 deletions at this point; `Select-String -Pattern 'EfcFormController\.(Actions|Breadcrumb|EventHandlers|Helpers|SetupAndProperties)\.cs' -LiteralPath QuickFiler/QuickFiler.csproj` returns 5 matches, each on a line that, after `.Replace('\', '/')`, matches `^\s* $`. The `#region`/`#endregion` lines travel with their members; `ConfigureBreadcrumbControl` through `BindBreadcrumbRowsAsync` (original 1044-1129) sit in `Breadcrumb.cs` and `ToggleExpansionStyle` (original 1291-1319) sits in `Helpers.cs`. Compilation is proven by [P2-T13], not here.
+- [x] [P2-T2] Create `QuickFiler/Viewers/WebView2EnvironmentContract.cs` per D1 (`#nullable enable`; usings `System`, `System.IO`, `Microsoft.Web.WebView2.Core`; `namespace QuickFiler.Viewers` (the namespace of `WebView2BreadcrumbHost.cs:12`); `internal static class WebView2EnvironmentContract` with `internal const string AdditionalBrowserArguments = "--incognito ";`, `internal const string UserDataFolderName = "WindowsFormsWebView2";`, `internal static string ResolveUserDataFolder()` returning `Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), UserDataFolderName)`, and `internal static CoreWebView2EnvironmentOptions CreateOptions()` returning `new CoreWebView2EnvironmentOptions(AdditionalBrowserArguments)`; XML docs stating the shared-browser-process rule and HRESULT 0x8007139F), and add ` ` to `QuickFiler/QuickFiler.csproj` immediately after the `Viewers\WebView2BreadcrumbHost.cs` item (line 426).
+ - Acceptance: file exists, at most 60 lines; `Select-String -SimpleMatch 'internal const string AdditionalBrowserArguments = "--incognito ";'` returns 1; `Select-String -SimpleMatch 'UserDataFolderName = "WindowsFormsWebView2"'` returns 1; the csproj item exists exactly once, bare and adjacent. The type has no consumers yet; [P0-T14]'s gate would now count this file's construction (3 sites become 4), which is expected and not re-run here.
+- [x] [P2-T3] Create `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` (`internal partial class EfcItemController`, usings `System`, `System.IO`, `System.Threading.Tasks`, `Microsoft.Web.WebView2.Core`, `QuickFiler.Viewers`) by moving `IncognitoArgument` with its doc block (`EfcItemController.cs:168-177`) and `InitializeWebViewAsync` (`:179-212`) verbatim out of `EfcItemController.cs`, and add ` ` to `QuickFiler/QuickFiler.csproj` immediately after the `Controllers\EfcItemController.WebViewFaultBoundary.cs` item (line 304).
+ - Acceptance: conservation gate over `EfcItemController.cs` plus the new file with `` = `EfcItemController` prints `CONSERVATION-DIFF-COUNT: 0`; `EfcItemController.cs` count equals 1122 minus 46 = 1076 or 1077 (the executor records the exact value; a difference outside that pair is a HALT); the new file is at most 80 lines; csproj item present once, bare, adjacent. The `#region Item Setup and Disposal Methods` marker stays in `EfcItemController.cs`.
+- [x] [P2-T4] Create `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` (`public partial class QfcCollectionController`, usings `System`, `System.Threading.Tasks`, `Microsoft.Office.Interop.Outlook`, `QuickFiler.Interfaces`, `UtilitiesCS`) by moving `PopOutControlGroup` (`QfcCollectionController.cs:714-724`) and `PopOutControlGroupAsync` (`:726-739`) verbatim, and add ` ` to `QuickFiler/QuickFiler.csproj` immediately after the `Controllers\QfcCollectionController.CarrierLoad.cs` item (line 315).
+ - Acceptance: conservation gate (`` = `QfcCollectionController`) prints `CONSERVATION-DIFF-COUNT: 0`; `QfcCollectionController.cs` count is 2306 or 2307 (record exact); csproj item present once, bare, adjacent. The class-level `[ExcludeFromCodeCoverage]` at `QfcCollectionController.cs:22` is untouched and, being type-level, covers the new part.
+- [x] [P2-T5] Create `QuickFiler/Controllers/EfcDataModel.Carry.cs` (`internal partial class EfcDataModel`, usings `System.Threading.Tasks`, `UtilitiesCS`) by moving `InitFolderHandlerAsync` (`EfcDataModel.cs:188-221`) verbatim, and add ` ` to `QuickFiler/QuickFiler.csproj` immediately after the `Controllers\EfcDataModel.FilingStem.cs` item (line 290).
+ - Acceptance: conservation gate (`` = `EfcDataModel`) prints `CONSERVATION-DIFF-COUNT: 0`; `EfcDataModel.cs` count is 464 or 465 (record exact); csproj item present once, bare, adjacent.
+- [x] [P2-T6] Declare the router and queue seams without behaviour in `QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` and `QuickFiler/Controllers/BreadcrumbOutboundQueue.cs`: in the router, after `NotifyCoreInitialized` (line 329), add `internal const string InitializationFailedBannerText = BreadcrumbRowBuilder.BannerPrefix + " Folder list unavailable: breadcrumb initialization failed";` and `public void NotifyInitializationFailed(Exception failure)` whose only statement is `if (failure == null) { throw new ArgumentNullException(nameof(failure)); }`; in the queue, after `OnInitializationCompleted` (line 65), add `public int DiscardPending()` whose only statement is `return 0;`. Each carries a one-line `/// ` ending with `Body lands in Phase 4 (#792).`.
+ - Acceptance: `Select-String -SimpleMatch 'public void NotifyInitializationFailed(Exception failure)' -LiteralPath QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` returns 1; `Select-String -SimpleMatch 'public int DiscardPending()' -LiteralPath QuickFiler/Controllers/BreadcrumbOutboundQueue.cs` returns 1; `Select-String -SimpleMatch ' Folder list unavailable: breadcrumb initialization failed' -LiteralPath QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` returns 1; `NotifyCoreInitialized` body (`:320-329`) is byte-identical to `BASE-SHA` (`git diff $BaseSha -- QuickFiler/Controllers/BreadcrumbBridgeRouter.cs` shows no removed lines: `git diff --numstat` deletions column is 0).
+- [x] [P2-T7] Declare the form-controller seams in `QuickFiler/Controllers/EfcFormController.Breadcrumb.cs`: add `internal const int BreadcrumbInitializationAttemptLimit = 3;`, `internal const string FolderAreaInitializationFailedText = "Matched Folders: unavailable (breadcrumb initialization failed)";`, `internal Func BreadcrumbHostInitializer { get; set; }` (each with a one-line summary), and change `private async Task InitializeBreadcrumbHostAsync()` to `internal async Task InitializeBreadcrumbHostAsync()` leaving its body unchanged.
+ - Acceptance: `Select-String -SimpleMatch 'internal async Task InitializeBreadcrumbHostAsync()' -LiteralPath QuickFiler/Controllers/EfcFormController.Breadcrumb.cs` returns 1 and `private async Task InitializeBreadcrumbHostAsync()` returns 0 across `QuickFiler/Controllers/EfcFormController*.cs`; `Select-String -SimpleMatch 'internal Func BreadcrumbHostInitializer { get; set; }'` returns 1; `Select-String -SimpleMatch 'BreadcrumbInitializationAttemptLimit = 3;'` returns 1; `Select-String -SimpleMatch '"Matched Folders: unavailable (breadcrumb initialization failed)"'` returns 1; the file is at most 160 lines.
+- [x] [P2-T8] Declare the site-3 seam in `QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs`: a private field `private IWebViewCoreInitializer _webViewInitializer;` and `internal IWebViewCoreInitializer WebViewInitializer { get => _webViewInitializer ??= new WebView2CoreInitializer(); set => _webViewInitializer = value; }` with a summary stating it is not yet consumed until Phase 4. `InitializeWebViewAsync` is unchanged in this task.
+ - Acceptance: `Select-String -SimpleMatch 'internal IWebViewCoreInitializer WebViewInitializer' -LiteralPath QuickFiler/Controllers/EfcItemController.WebViewEnvironment.cs` returns 1; `Select-String -SimpleMatch 'CoreWebView2Environment.CreateAsync(' -LiteralPath` the same file returns 1 (still the direct SDK call; routed in [P4-T3]).
+- [x] [P2-T9] Declare the carry seams in `QuickFiler/Controllers/EfcDataModel.Carry.cs`: `internal IFolderSearchHandler CarriedFolderHandler { get; set; }`, `internal MailItemHelper CarriedMailHelper { get; set; }`, and `internal static bool TryAdoptCarriedFolderHandler(object folderList, IFolderSearchHandler carried, out FolderPredictor adopted)` whose body is `adopted = null; return false;` (summary ending `Decision lands in Phase 4 (#792).`). `InitFolderHandlerAsync` is unchanged in this task.
+ - Acceptance: each of the three signatures is found exactly once by `Select-String -SimpleMatch` in that file; `Select-String -SimpleMatch 'TryAdoptCarriedFolderHandler(' -LiteralPath` the file returns exactly 1 (declaration only, no call yet); file at most 90 lines.
+- [x] [P2-T10] Add the read-only accessor `internal IFolderSearchHandler FolderHandler => _folderHandler;` to `QuickFiler/Controllers/QfcItemController.cs` directly after the `TopFolderScore` member (line 265, with a two-line summary), and declare in `QuickFiler/Controllers/QfcCollectionController.PopOut.cs` the seam members `private Func