@@ -288,6 +288,51 @@ public async Task Startup_clears_existing_policy_backends_when_replace_is_set()
288288 Assert . Equal ( BedrockGuardrailsPolicyBackend . BackendName , backend ) ;
289289 }
290290
291+ [ Fact ]
292+ public async Task DI_registration_runs_hosted_service_and_replaces_policy_backends ( )
293+ {
294+ // Full DI path: register through the public AddBedrockGovernance API and let the host run the
295+ // registered IHostedService, rather than newing up BedrockGovernanceStartup directly. This locks in
296+ // that the toolkit's kernel is fully populated at resolve time (construction-time policy loading, no
297+ // toolkit hosted service), so ClearPolicies runs against a complete PolicyEngine and can't be
298+ // silently re-populated by a later-ordered hosted service.
299+ var kernel = new GovernanceKernel ( ) ;
300+ kernel . PolicyEngine . LoadYaml (
301+ """
302+ apiVersion: governance.toolkit/v1
303+ name: baseline
304+ default_action: deny
305+ rules: []
306+ """ ) ;
307+ kernel . PolicyEngine . AddExternalBackend ( new StubExternalBackend ( "seeded-external" ) ) ;
308+
309+ var services = new ServiceCollection ( ) ;
310+ // Mirrors the toolkit's WithGovernance kernel registration.
311+ services . AddSingleton ( kernel ) ;
312+ services . AddBedrockGovernance ( o =>
313+ {
314+ o . EnablePolicy = true ;
315+ o . EnableAudit = false ;
316+ o . EnablePiiSanitization = false ;
317+ o . ReplacePolicyBackends = true ;
318+ o . Policy . GuardrailId = "gr" ;
319+ // Deterministic region so the Bedrock client constructs without ambient AWS config.
320+ o . Policy . Region = RegionEndpoint . USWest2 ;
321+ } ) ;
322+
323+ using var provider = services . BuildServiceProvider ( ) ;
324+
325+ // Run the hosted services exactly as the generic host would at startup.
326+ foreach ( var hosted in provider . GetServices < IHostedService > ( ) )
327+ {
328+ await hosted . StartAsync ( CancellationToken . None ) ;
329+ }
330+
331+ Assert . Empty ( kernel . PolicyEngine . ListPolicies ( ) ) ;
332+ var backend = Assert . Single ( kernel . PolicyEngine . ListExternalBackends ( ) ) ;
333+ Assert . Equal ( BedrockGuardrailsPolicyBackend . BackendName , backend ) ;
334+ }
335+
291336 // Minimal external backend for seeding the PolicyEngine; never evaluated in these wiring tests.
292337 private sealed class StubExternalBackend : global ::AgentGovernance . Policy . IExternalPolicyBackend
293338 {
0 commit comments