The SDK-free builder embeds resources, under the SDK's own names

mw-plugin-test build-project compiles a .csproj with no dotnet SDK, no NuGet restore and no platform checkout, against the assemblies of a MeshWeaver image. Until now it refused <EmbeddedResource> outright, and that refusal was the single biggest coverage gap: of the 54 non-test projects in MeshWeaver.Plugins/src, 19 failed on nothing else — most of them on one line, <EmbeddedResource Include="Data\**\*.md">.

The refusal was not timidity. A wrong manifest-resource name is the quietest defect this builder could ship. The assembly compiles, the emit is verified, the DLL loads — and Assembly.GetManifestResourceStream(name) returns null at run time, in some other process, weeks later. Nothing goes red anywhere in between. Core's own MeshWeaver.Messaging.Hub.csproj already carries a comment describing that exact outcome for its strings.*.json: "the build succeeds, the main assembly carries ZERO manifest resources, every lookup falls through to the key-fallback path, and the UI renders raw chat.new tokens."

So the rules were measured, not remembered. Each one was established by building a probe project with the real .NET SDK and reading the manifest-resource table back out of the emitted PE. They are not guessable:

What it refuses, and why that is the feature

Where a rule could not be matched exactly, the construct is refused by name, with its own --accept token — because a plausible-looking wrong name is worse than no build:

The number, and how to read it

Over the same 54 projects and the same pinned portal image: 9 green before, 10 after — and 19 resource refusals down to 0.

That looks like a poor return until you notice what a refusal does. It stops the load, so it masks every gap behind it. Those 19 projects were not "19 projects away from green"; they were 19 projects about which nothing further was known. Closing the gap turned one green and revealed the real blocker for the other eighteen — ten want SDK source generators, three want Razor, three want an additional library, one wants protoc. The previous sweep counted 3 source-generator failures; the true figure was 14.

In a builder designed to refuse rather than guess, a failure ranking is a ranking of FIRST refusals. Removing the top entry does not add its count to the green column. It redistributes it — and that is the honest way to read every such table, including the next one.

Reconnecting…
The connection to the server was interrupted. Trying to restore it…
Trying again…
The connection could not be restored. Reloading the page…
The server was updated. Reloading the page to pick up the latest version.