diff --git a/src/Host/Dev/Program.cs b/src/Host/Dev/Program.cs
index 1697ead4..44861375 100644
--- a/src/Host/Dev/Program.cs
+++ b/src/Host/Dev/Program.cs
@@ -13,7 +13,11 @@
//
// This host closes that gap and nothing more. It is deliberately the same handful of calls the
// distribution host makes, because that is its second job: if someone breaks AddCalloraHost or the
-// order these have to run in, this stops building rather than the next distribution finding out.
+// order these have to run in, it shows up here rather than in the next distribution.
+//
+// "Shows up here" used to say "stops building", which was only true of compile errors. A missing
+// registration compiles cleanly and fails at builder.Build() — and nothing in CI made that call.
+// TheCompositionBuildsTests now does, with the same calls in the same order; keep them in step.
//
// It is not a second product. No installer, no first-run provisioning, no packaging — those belong
// to a distribution, which owns its own configuration and lifecycle.
diff --git a/tests/Callora.Core.Tests/Application/Startup/TheCompositionBuildsTests.cs b/tests/Callora.Core.Tests/Application/Startup/TheCompositionBuildsTests.cs
new file mode 100644
index 00000000..47d4a423
--- /dev/null
+++ b/tests/Callora.Core.Tests/Application/Startup/TheCompositionBuildsTests.cs
@@ -0,0 +1,84 @@
+using Callora.Administration;
+using Callora.Core.Application.Plugins;
+using Callora.Core.Application.Security;
+using Callora.Core.Infrastructure.DependencyInjection;
+using Callora.Surface.Rendering;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace Callora.Core.Tests.Application.Startup;
+
+///
+/// Die Zusammenstellung des Hosts lässt sich bauen — mit Lifetime-Validierung.
+///
+///
+///
+/// Der Befund: src/Host/Dev/Program.cs trägt den Kommentar, es falle auf, „wenn jemand
+/// AddCalloraHost oder die Reihenfolge der Modulaufrufe bricht". Das stimmte nur für
+/// Compile-Fehler. Eine fehlende Registrierung übersetzt sauber und scheitert erst bei
+/// builder.Build() — und den Aufruf machte in der CI niemand. Ein Dienst, der im Testhost von
+/// Hand registriert wird und in der echten Komposition fehlt, kam damit grün durch die Suite und
+/// hätte den Start des Dev-Stacks abgeräumt.
+///
+///
+/// AddCalloraHost setzt ValidateScopes und ValidateOnBuild, deshalb sagt schon
+/// der Bau etwas: Er prüft jede registrierte Abhängigkeit auf Auflösbarkeit und auf einen
+/// von einem Singleton gefangenen Scoped-Dienst.
+///
+///
+/// Und genau da hört er auf — nachgemessen, nicht angenommen: Wird
+/// PluginSelfService aus der Zusammenstellung entfernt, baut der Host weiter. Ein Dienst, der
+/// nirgends registriert ist, wird auch nicht validiert, und ein [FromServices]-Parameter
+/// eines Controllers wird erst beim Aufruf aufgelöst. Deshalb der zweite Test, der die Dienste
+/// beim Namen nennt: Was nur über [FromServices] konsumiert wird, muss hier stehen, sonst
+/// deckt es niemand.
+///
+///
+/// Es wird nichts verbunden: Die Verbindungszeichenfolge muss nur gültig aussehen, denn ein
+/// DbContext öffnet beim Auflösen keine Verbindung.
+///
+///
+public sealed class TheCompositionBuildsTests
+{
+ [Fact]
+ public void TheHostComposesWithoutAMissingOrCaptiveRegistration()
+ {
+ using var app = BuildHost();
+
+ Assert.NotNull(app.Services);
+ }
+
+ ///
+ /// Die Dienste der Mandantenebene lösen aus der echten Zusammenstellung auf, nicht nur aus den
+ /// von Hand zusammengesetzten Testhosts.
+ ///
+ [Fact]
+ public void TheTenantLevelServicesResolveFromTheRealComposition()
+ {
+ using var app = BuildHost();
+ using var scope = app.Services.CreateScope();
+
+ Assert.NotNull(scope.ServiceProvider.GetRequiredService());
+ Assert.NotNull(scope.ServiceProvider.GetRequiredService());
+ Assert.NotNull(scope.ServiceProvider.GetRequiredService());
+ }
+
+ // Dieselben Aufrufe in derselben Reihenfolge wie src/Host/Dev/Program.cs. Weicht der Test davon
+ // ab, prüft er eine Zusammenstellung, die niemand ausliefert.
+ private static WebApplication BuildHost()
+ {
+ var builder = WebApplication.CreateBuilder();
+
+ // Dieselben Schlüssel, die docker-compose.yml setzt — der Abschnitt heißt BackendHost.
+ builder.Configuration["BackendHost:DatabaseConnectionString"] =
+ "Host=localhost;Database=callora-composition-test;Username=u;Password=p";
+ builder.Configuration["BackendHost:ApiKeys:0"] = "composition-test-key";
+
+ builder.AddCalloraHost();
+ builder.AddCalloraAdministration();
+ builder.Services.AddCalloraSurfaceRendering();
+
+ return builder.Build();
+ }
+}