Feature: Plugin Extension Points Registration
  The plugin infrastructure must register all 30 spec-defined extension
  points with typed Protocol interfaces in the PluginManager.

  Based on issue #939.

  # -----------------------------------------------------------------------
  # All 30 extension points are registered
  # -----------------------------------------------------------------------

  Scenario: All 30 extension points are registered via register_all_extension_points
    Given a fresh PluginManager for extension point registration
    When I register all spec-defined extension points
    Then exactly 30 extension points should be registered

  Scenario: Extension point definitions are available as a tuple
    When I retrieve the extension point definitions
    Then I should get exactly 30 extension point definitions
    And each definition should have a non-empty name
    And each definition should have a protocol_type
    And each definition should have a non-empty description

  # -----------------------------------------------------------------------
  # Extension point lookup by name
  # -----------------------------------------------------------------------

  Scenario: Extension point lookup by name returns the correct point
    Given a PluginManager with all extension points registered
    When I look up extension point "context.strategy"
    Then the looked-up extension point name should be "context.strategy"

  Scenario: Extension point lookup for pipeline component by name
    Given a PluginManager with all extension points registered
    When I look up extension point "context.pipeline_component.scorer"
    Then the looked-up extension point name should be "context.pipeline_component.scorer"

  Scenario: Extension point lookup for safety guardrail by name
    Given a PluginManager with all extension points registered
    When I look up extension point "safety.guardrail"
    Then the looked-up extension point name should be "safety.guardrail"

  Scenario: Lookup of non-existent extension point returns None
    Given a PluginManager with all extension points registered
    When I look up extension point "nonexistent.point"
    Then the looked-up extension point should be None

  # -----------------------------------------------------------------------
  # Extension point lookup by category
  # -----------------------------------------------------------------------

  Scenario: Extension points grouped by category have correct counts
    When I retrieve extension points grouped by category
    Then the "context" category should have 12 extension points
    And the "output" category should have 3 extension points
    And the "validation" category should have 2 extension points
    And the "tool" category should have 2 extension points
    And the "skill" category should have 2 extension points
    And the "resource" category should have 2 extension points
    And the "a2a" category should have 2 extension points
    And the "event" category should have 2 extension points
    And the "config" category should have 2 extension points
    And the "safety" category should have 1 extension points

  # -----------------------------------------------------------------------
  # Protocol type correctness
  # -----------------------------------------------------------------------

  Scenario: Context strategy extension point has correct protocol type
    Given a PluginManager with all extension points registered
    When I look up extension point "context.strategy"
    Then the protocol type name should be "ContextStrategyExtension"

  Scenario: Output renderer extension point has correct protocol type
    Given a PluginManager with all extension points registered
    When I look up extension point "output.renderer"
    Then the protocol type name should be "OutputRendererExtension"

  Scenario: Safety guardrail extension point has correct protocol type
    Given a PluginManager with all extension points registered
    When I look up extension point "safety.guardrail"
    Then the protocol type name should be "SafetyGuardrailExtension"

  # -----------------------------------------------------------------------
  # Plugin registration via entry points
  # -----------------------------------------------------------------------

  Scenario: Plugin registration via entry points discovers no plugins by default
    Given a fresh PluginManager for extension point registration
    When I discover extension point plugins from group "cleveragents.ext.test"
    Then the entry point discovered list should be empty

  # -----------------------------------------------------------------------
  # TOTAL_EXTENSION_POINTS constant
  # -----------------------------------------------------------------------

  Scenario: TOTAL_EXTENSION_POINTS constant equals 30
    Then the TOTAL_EXTENSION_POINTS constant should equal 30

  # -----------------------------------------------------------------------
  # Context extension points wired to ACMSPipeline
  # -----------------------------------------------------------------------

  Scenario: ACMSPipeline reports context extension points when plugin manager is wired
    Given a PluginManager with all extension points registered
    And an ACMSPipeline wired with the plugin manager
    Then the pipeline should report 12 context extension points

  Scenario: ACMSPipeline reports no context extension points when no plugin manager
    Given an ACMSPipeline without a plugin manager
    Then the pipeline should report 0 context extension points

  # -----------------------------------------------------------------------
  # All extension protocols are runtime-checkable
  # -----------------------------------------------------------------------

  Scenario: All extension protocol types are runtime-checkable
    When I retrieve all extension protocol types
    Then every protocol should be runtime-checkable

  # -----------------------------------------------------------------------
  # Idempotent registration
  # -----------------------------------------------------------------------

  Scenario: Registering extension points twice does not duplicate
    Given a fresh PluginManager for extension point registration
    When I register all spec-defined extension points
    And I register all spec-defined extension points again
    Then exactly 30 extension points should be registered

  # -----------------------------------------------------------------------
  # Extension point registry_key matches category
  # -----------------------------------------------------------------------

  Scenario: Each extension point registry_key matches its category
    When I retrieve the extension point definitions
    Then each definition registry_key should match its name category prefix

  # -----------------------------------------------------------------------
  # Protocol implementation conformance
  # -----------------------------------------------------------------------

  Scenario: A concrete context strategy satisfies ContextStrategyExtension
    Given a concrete ContextStrategyExtension implementation
    Then it should be recognized as a ContextStrategyExtension instance
    And calling its protocol methods should succeed

  Scenario: A concrete pipeline component satisfies ContextPipelineComponentExtension
    Given a concrete ContextPipelineComponentExtension implementation
    Then it should be recognized as a ContextPipelineComponentExtension instance
    And calling its pipeline component methods should succeed

  Scenario: A concrete storage backend satisfies ContextStorageBackendExtension
    Given a concrete ContextStorageBackendExtension implementation
    Then it should be recognized as a ContextStorageBackendExtension instance
    And calling its storage methods should succeed

  Scenario: A concrete output renderer satisfies OutputRendererExtension
    Given a concrete OutputRendererExtension implementation
    Then it should be recognized as an OutputRendererExtension instance
    And calling its renderer methods should succeed

  Scenario: A concrete output materializer satisfies OutputMaterializerExtension
    Given a concrete OutputMaterializerExtension implementation
    Then it should be recognized as an OutputMaterializerExtension instance

  Scenario: A concrete output format satisfies OutputFormatExtension
    Given a concrete OutputFormatExtension implementation
    Then it should be recognized as an OutputFormatExtension instance

  Scenario: A concrete validation runner satisfies ValidationRunnerExtension
    Given a concrete ValidationRunnerExtension implementation
    Then it should be recognized as a ValidationRunnerExtension instance

  Scenario: A concrete validation rule provider satisfies ValidationRuleProviderExtension
    Given a concrete ValidationRuleProviderExtension implementation
    Then it should be recognized as a ValidationRuleProviderExtension instance

  Scenario: A concrete tool provider satisfies ToolProviderExtension
    Given a concrete ToolProviderExtension implementation
    Then it should be recognized as a ToolProviderExtension instance

  Scenario: A concrete tool middleware satisfies ToolMiddlewareExtension
    Given a concrete ToolMiddlewareExtension implementation
    Then it should be recognized as a ToolMiddlewareExtension instance

  Scenario: A concrete skill provider satisfies SkillProviderExtension
    Given a concrete SkillProviderExtension implementation
    Then it should be recognized as a SkillProviderExtension instance

  Scenario: A concrete skill template satisfies SkillTemplateExtension
    Given a concrete SkillTemplateExtension implementation
    Then it should be recognized as a SkillTemplateExtension instance

  Scenario: A concrete resource resolver satisfies ResourceResolverExtension
    Given a concrete ResourceResolverExtension implementation
    Then it should be recognized as a ResourceResolverExtension instance

  Scenario: A concrete resource type handler satisfies ResourceTypeHandlerExtension
    Given a concrete ResourceTypeHandlerExtension implementation
    Then it should be recognized as a ResourceTypeHandlerExtension instance

  Scenario: A concrete A2A transport satisfies A2ATransportExtension
    Given a concrete A2ATransportExtension implementation
    Then it should be recognized as an A2ATransportExtension instance

  Scenario: A concrete A2A extension method satisfies A2AExtensionMethodExtension
    Given a concrete A2AExtensionMethodExtension implementation
    Then it should be recognized as an A2AExtensionMethodExtension instance

  Scenario: A concrete event handler satisfies EventHandlerExtension
    Given a concrete EventHandlerExtension implementation
    Then it should be recognized as an EventHandlerExtension instance

  Scenario: A concrete event filter satisfies EventFilterExtension
    Given a concrete EventFilterExtension implementation
    Then it should be recognized as an EventFilterExtension instance

  Scenario: A concrete config source satisfies ConfigSourceExtension
    Given a concrete ConfigSourceExtension implementation
    Then it should be recognized as a ConfigSourceExtension instance

  Scenario: A concrete config validator satisfies ConfigValidatorExtension
    Given a concrete ConfigValidatorExtension implementation
    Then it should be recognized as a ConfigValidatorExtension instance

  Scenario: A concrete safety guardrail satisfies SafetyGuardrailExtension
    Given a concrete SafetyGuardrailExtension implementation
    Then it should be recognized as a SafetyGuardrailExtension instance
    And calling its guardrail methods should succeed
