@phase2 @acms @scope_chain_resolver Feature: Pluggable scope chain resolution extension API As a CleverAgents developer I want a pluggable scope chain resolver registry with prioritized resolvers So that the ACMS context assembly pipeline can resolve scope references via registered extensions # --------------------------------------------------------------------------- # ScopeResolutionContext # --------------------------------------------------------------------------- @scope_resolution_context Scenario: Create ScopeResolutionContext with required scope only When I create a ScopeResolutionContext with scope "issue:123" Then the ScopeResolutionContext scope should be "issue:123" And the ScopeResolutionContext metadata should be empty And the ScopeResolutionContext resolved_fragments should be empty @scope_resolution_context Scenario: Create ScopeResolutionContext with all fields populated When I create a full ScopeResolutionContext with scope "pr:456" and metadata key "repo" value "core" and resolved_fragment "frag1" Then the ScopeResolutionContext scope should be "pr:456" And the ScopeResolutionContext metadata key "repo" should be "core" And the ScopeResolutionContext resolved_fragments should contain "frag1" # --------------------------------------------------------------------------- # ScopeResolverRegistry — resolution # --------------------------------------------------------------------------- @scope_resolver_registry Scenario: Empty registry resolves to empty list Given a fresh ScopeResolverRegistry When I resolve scope "issue:999" with the registry Then the resolution result should be empty @scope_resolver_registry Scenario: Register a resolver and resolve a matching scope Given a fresh ScopeResolverRegistry When I register a resolver named "test" with priority 0 that returns "frag_A" for scope "issue:1" And I resolve scope "issue:1" with the registry Then the resolution result should contain "frag_A" @scope_resolver_registry Scenario: Higher priority resolver wins over lower priority resolver Given a fresh ScopeResolverRegistry When I register a resolver named "low" with priority 1 that returns "low_frag" for scope "item:1" And I register a resolver named "high" with priority 10 that returns "high_frag" for scope "item:1" And I resolve scope "item:1" with the registry Then the resolution result should contain "high_frag" And the resolution result should not contain "low_frag" @scope_resolver_registry Scenario: First matching resolver wins and stops iteration Given a fresh ScopeResolverRegistry When I register a resolver named "alpha" with priority 5 that returns "alpha_frag" for scope "x:1" And I register a resolver named "beta" with priority 3 that returns "beta_frag" for scope "x:1" And I resolve scope "x:1" with the registry Then the resolution result should contain "alpha_frag" And the resolution result should not contain "beta_frag" @scope_resolver_registry Scenario: Resolve returns empty when no resolver matches the scope Given a fresh ScopeResolverRegistry When I register a null resolver named "no_match" with priority 0 And I resolve scope "unknown:1" with the registry Then the resolution result should be empty # --------------------------------------------------------------------------- # ScopeResolverRegistry — register / unregister # --------------------------------------------------------------------------- @scope_resolver_registry @register Scenario: Register a resolver with explicit priority stores it correctly Given a fresh ScopeResolverRegistry When I register a null resolver named "myresolver" with priority 42 Then the registry should contain a resolver named "myresolver" And the resolver named "myresolver" should have priority 42 @scope_resolver_registry @unregister Scenario: Unregister removes an existing resolver Given a fresh ScopeResolverRegistry When I register a null resolver named "to_remove" with priority 0 And I unregister the resolver named "to_remove" Then the registry should not contain a resolver named "to_remove" @scope_resolver_registry @unregister Scenario: Unregister non-existent resolver is a safe no-op Given a fresh ScopeResolverRegistry When I unregister the resolver named "does_not_exist" Then the registry should not contain a resolver named "does_not_exist" # --------------------------------------------------------------------------- # ScopeResolverRegistry — introspection # --------------------------------------------------------------------------- @scope_resolver_registry @introspection Scenario: get_resolvers returns all registered resolvers Given a fresh ScopeResolverRegistry When I register a null resolver named "r1" with priority 1 And I register a null resolver named "r2" with priority 2 Then get_resolvers should return 2 entries And get_resolvers should include key "r1" And get_resolvers should include key "r2" @scope_resolver_registry @introspection Scenario: list_resolvers returns entries sorted by priority descending Given a fresh ScopeResolverRegistry When I register a null resolver named "low_pri" with priority 1 And I register a null resolver named "high_pri" with priority 9 And I register a null resolver named "mid_pri" with priority 5 Then list_resolvers should return 3 entries in priority order | name | priority | | high_pri | 9 | | mid_pri | 5 | | low_pri | 1 | # --------------------------------------------------------------------------- # ScopeResolverRegistry — _discover_resolvers coverage paths # --------------------------------------------------------------------------- @scope_resolver_registry @discover Scenario: Discovery silently ignores entry point load failures Given a ScopeResolverRegistry with a failing entry point Then the scope resolver registry should be empty @scope_resolver_registry @discover Scenario: Discovery silently ignores outer entry_points exception Given a ScopeResolverRegistry where entry_points raises an exception Then the scope resolver registry should be empty @scope_resolver_registry @discover Scenario: Discovery uses dict-style fallback for older importlib_metadata API Given a ScopeResolverRegistry with dict-style entry points returning no scope resolvers Then the scope resolver registry should be empty