Reproduce and close the [EnvironmentName]/[IfEnvironment] gap - #223
Merged
Merged
Conversation
The second trial's D-B-10: [EnvironmentName("X")] on a test method
against a registration gated [IfEnvironment("X")], and the gated
registration never applies. The mechanism the finding described - the
environment registered under IHardenedEnvironment alone - was already
fixed, but every test of that fix drives the setup pipeline by hand.
Through the real xunit v3 entry point the finding reproduces: the
runner applies modules before the service-setup pass, so every
[IfEnvironment] condition is decided against the process default before
the test's environment is registered.
The ordering lives in DependencyModules, and 1.3.0 ships its fix:
IModuleEnvironmentProvider, consulted by the runner before it loads any
module. HardenedTestEntryPointAttribute implements it from the same
attribute walk it already uses, and SetupServiceCollection reuses the
seeded instance so the environment a module condition read and the one
a service resolves are one object. The repro runs as an integration
test in the WebApp SUT, against the application's own generated module,
with the gate's absence under the default environment as the control.
Hardened.SourceGeneration.Testing's branch baseline moves 87.2 to 86.6,
from the CI run's own summary: GeneratorReferences walks the dependency
graph with load-and-dedup branch arms, and 1.3.0's assemblies no longer
exercise an arm 1.2.2's did. Only that entry moves; the run cleared
every other floor.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ipjohnson
force-pushed
the
environment-name-repro
branch
from
September 1, 2026 22:12
8c6422e to
4bf0903
Compare
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.
F14 from the Forty-Four Fixes queue (D-B-10), the last entry, following the plan's repro-first instruction.
The finding REPRODUCED.
[EnvironmentName("X")]on a test method against a registration gated[IfEnvironment("X")], driven through the real xunit v3 entry point, never saw the gated registration. The mechanism the report described - the environment registered underIHardenedEnvironmentalone - was already fixed at the tag, but every test of that fix drives the setup pipeline by hand. The real runner applies modules before the service-setup pass, so every[IfEnvironment]condition was decided against the process default before the test's environment existed.The ordering lives in DependencyModules, and 1.3.0 ships its fix (ipjohnson/DependencyModules#54):
IModuleEnvironmentProvider, consulted by both runners before any module loads. This PR is the Hardened side:DependencyModulesVersionbumps to 1.3.0.HardenedTestEntryPointAttributeimplements the new interface from the same attribute walk it already uses, andSetupServiceCollectionreuses the seeded instance, so the environment a module condition read and the one a service resolves are one object.[IfEnvironment]-gated[SingletonService]resolves under the test's declared environment - with the gate's absence under the default environment as the control. Both fail against 1.2.2 and pass against 1.3.0.Hardened.Shared.Testingpublic API approval gains the interface and its one member.Validated with the full suite against the published 1.3.0 packages in an isolated package cache: clean build, 31 test projects green.
🤖 Generated with Claude Code