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 server was updated. Reloading the page to pick up the latest version.