Converge the WebView2 environment contract and stop the breadcrumb host stranding its buffers on failure - #910
Merged
drmoisan merged 13 commits intoSep 18, 2026
Conversation
…w2-init-fails-resource-not-in-correct-state-792
Re-measured the issue 792 diagnosis against the merged tree and corrected six staleness defects in spec.md that dated from its authoring 229 commits ago. Research: adds a refreshed diagnosis artifact recording the three environment sites, the single-trigger defect shape, and closing both open questions. Both are answered: the breadcrumb document depends on no persisted browsing storage, so the three sites converge on the incognito argument rather than dropping it; and Designer-set creation properties are inert because the failing control declares none. Records the commit-level provenance for the en-dash correction that first made the arguments diverge, and the AC-U6 vacuity trap in which a text search for the construction syntax matches a commented-out dead line and so passes on the unfixed tree. Spec: updates two line counts that drifted when issues 742 and 743 merged, in both places they appear; corrects the root-cause citations that were off by one for the same reason, one of which pointed at that dead comment; adds issue 726 context noting the Efc item path is already fault-guarded but its sink has no user-visible path; records that the shared-contract disclaimer covers the error sink only and not the incognito constant, so AC-U6 reverses no documented decision; rewrites the contention and risk sections now that both siblings have merged; and points the research link at the current record. No implementation. Planning only. Acceptance criteria unchanged, all nine still open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
Adds a 93-task, nine-phase atomic plan replacing the stale plan written 229 commits ago. Planning only; no implementation is executed by this commit. The plan cleared three preflight rounds, which surfaced 23 defects, eight of them blocking. Notable classes: a regression test that passed on the unfixed tree; two structural gates whose acceptance omitted output lines the gate always prints, so a correct run would have halted; a coverage command passing two parameters the runner does not declare; eight immutability gates anchored to a commit in which the feature folder does not exist; a test writing shared static state that an existing serial class also substitutes; and three coverage sub-gates demanding a ratio their own tests could not reach. Both forks the earlier spec left open are closed before execution. The breadcrumb document depends on no persisted browsing storage, so the three environment sites converge on the incognito argument rather than dropping it. Designer-set creation properties are inert because the control that fails declares none, so no verification task is needed. Structural gates are proven non-vacuous by observation rather than by reading: the AC-U6 gate was executed read-only against the unfixed tree and recorded a failing result. The criterion whose behaviour is already satisfied is proven by mutation instead, and is not presented as observed-failing. The manual live-Outlook verification is marked human-executed throughout and is never described as an automated gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
The spec mandated a prerequisite audit that the preflight-cleared plan does not contain, because the research record had already answered it. The spec is the authoritative acceptance source, so a reviewer would have read the plan as non-compliant. This closes the fork in all four places the spec carried it: the scope list, settled decision 1, the assumptions, and the open-risk entry. The evidence is independent of the en-dash correction that first made the arguments diverge. That history establishes when the divergence began and that converging preserves the earlier privacy fix rather than undoing it, but it cannot answer the storage question, because the breadcrumb host has never run under incognito. What answers it is that the document uses no browser storage at all: every stylesheet and script is a compile-time constant emitted inline, a scoped search of the three generating files returns zero matches across thirteen storage and external-resource terms, and the only host-communication surface is the WebView2 message bridge, which incognito does not restrict. All display state is re-pushed from managed code on each initialization. The zero-match result was checked with a positive control so that a mistyped search could not masquerade as an absence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
… seams Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
…e fix Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
…retry, explicit discard, pop-out carry Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BRrLF9BAQWhvmtt9BeaoHs
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Converge the WebView2 environment contract and stop the breadcrumb host stranding its buffers on failure
Summary
InitializeBreadcrumbHostAsyncfailures through the form controller's boundary fault reporter so they reach the user rather than only the log.Why
The breadcrumb folder selector is the primary folder-selection surface on the Efc view, and it was presenting an empty list with no error.
The root cause is that three production sites construct
CoreWebView2EnvironmentOptionsindependently while sharing one user-data folder. Two supplied--incognitoand one supplied no arguments at all. A shared user-data folder requires agreeing options across every WebView running in that browser process, so the odd site out fails initialization.The divergence is a regression with a precise origin. Before 2026-08-27 the two preview sites carried a U+2013 EN DASH in their argument literal, which Chromium silently discarded as an unrecognised token, so their effective option set was empty and matched the breadcrumb host's empty set. Correcting that literal to ASCII made the arguments real switches for the first time and created the conflict. The breadcrumb host was never touched by that correction.
On the failure path the damage compounded. The router stashes a pending document and the outbound queue buffers messages, and both are drained by a single method reachable only through the host's
CoreInitializedevent. That event is raised only on the success path, so a failed initialization left both buffers stranded with no retry, no error document and no user-visible signal. This is one defect with one trigger, not two independent ones.What Changed
Core fix
QuickFiler/Viewers/WebView2EnvironmentContract.csowns the user-data folder and the additional browser arguments. Each literal now appears exactly once in the tree.IWebViewCoreInitializerseam instead of calling the SDK factory directly, which also makes it testable.EfcFormController.InitializeBreadcrumbHostAsyncgains a bounded retry and reports throughTryReportBoundaryFaulton final failure; the folder-area label carries the visible error state.BreadcrumbBridgeRoutergains an explicit failure notification that clears the pending document, navigates an error banner and discards the outbound queue.Structure
EfcFormController.csis split six ways along its existing region boundaries and is now 266 lines. The split is proven by a multiset conservation gate over non-blank lines.EfcItemControllerandQfcCollectionControllermove into new partials. Both parent files remain over the 500-line ceiling as pre-existing debt this change neither introduces nor resolves, recorded with before and after counts..csfiles each carry a matchingCompileitem in their owning non-SDK-style project file.Tests
Architecture / How It Fits Together
WebView2EnvironmentContractis the single owner of the environment inputs. The two preview controllers and the breadcrumb host each read it and hand the result toIWebViewCoreInitializer, which forwards to the SDK. Because every caller now supplies identical options for the shared user-data folder, no site can be the odd one out.On the failure path,
EfcFormController.InitializeBreadcrumbHostAsyncowns the retry loop and the reporting decision; the host's SDK event handler stays a thin, coverage-exempt notifier. When the retry is exhausted the controller sets the folder-area label and notifies the router, which clears its pending document, navigates a banner and discards the queue. The success path is unchanged.Verification
Completed
Checked 1658 files, exit 0, no write-set file rewritten./t:Rebuild:0 Warning(s),0 Error(s). Non-vacuity confirmed by 36 compiler invocations with zero skippedCoreCompiletargets./t:Rebuildwith warnings as errors:0 Warning(s),0 Error(s), same non-vacuity counters.QuickFiler.Test: 1468 of 1468 passed, run in parallel under the repository runsettings.TaskMaster.Testregression sweep: 452 of 452 passed, no new failures against the recorded baseline.Recommended
dotnet tool run csharpier check .msbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=truemsbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=truevstest.console.exe QuickFiler.Test/bin/Debug/QuickFiler.Test.dll /Settings:scripts/vscode/TaskMaster.cli.runsettings /InIsolationBackward Compatibility / Migration Notes
Risks and Mitigations
--incognitorather than dropping it keeps the preview panes from persisting browsing data. The panes navigate untrusted message HTML and share the user-data folder, so removing the argument would newly persist tracking-pixel cookies and cache. An audit of the three files that generate the breadcrumb document found no use of any browser storage API and no external resource reference, so the breadcrumb document is unaffected by the argument.Review Guide
Suggested order:
QuickFiler/Viewers/WebView2EnvironmentContract.cs— the new single owner, 53 lines.QuickFiler/Controllers/EfcFormController.Breadcrumb.cs— the retry loop, the reporting decision and the folder-area error state.QuickFiler/Controllers/BreadcrumbBridgeRouter.csandBreadcrumbOutboundQueue.cs— the failure notification and the explicit discard.EfcDataModel.Carry.csandQfcCollectionController.PopOut.cs.Mechanical and safe to skim: the five
EfcFormController.*split parts and the project-fileCompileitem additions. The split conserves every non-blank line of the original.Follow-ups
GitHub Auto-close