@spec @clarification @layer_boundary @di_exception @ulid_scope @acms_pipeline @tui_components
Feature: Spec clarifications — layer boundary DI exception, ULID scope, TUI/ACMS gap-fill

  As a CleverAgents developer
  I want BDD coverage for the AUTO-ARCH-1 spec clarifications introduced in PR #10451
  So that the following architectural rules can be tested programmatically:
    - Application layer container.py is the sole permitted location for application-to-infrastructure concrete type references
    - Domain entity IDs must be ULIDs; ephemeral internal IDs need not be
    - ACMS pipeline per-stage protocol contracts include storage tier definitions and budget enforcement
    - TUI has 8+ component public interfaces with verifiable checks

  # ---------------------------------------------------------------------------
  # Layer boundary DI exception — container.py as sole permitted location
  # ---------------------------------------------------------------------------

  @di_exception @layer_boundary
  Scenario: Import analysis confirms container.py references infrastructure types
    Given the source directory is at "src/cleveragents"
    And I examine file "application/container.py"
    Then container.py should import from cleveragents.infrastructure (application-to-infrastructure concrete type references)

  @di_exception @layer_boundary
  Scenario: Non-container application files must not import infrastructure types directly
    Given the source directory is at "src/cleveragents"
    And I examine all files in "application/services/" for imports
    Then no file outside container.py should import from cleveragents.infrastructure with a concrete class
    And application modules may only depend on domain model interfaces

  @di_exception @layer_boundary
  Scenario: container.py is the designated DI exception per spec clarification
    Given the source directory is at "src/cleveragents"
    When I check that cleveragents/application/container.py imports infrastructure types
    Then "container.py" should be listed as the sole permitted location for application-to-infrastructure concrete references
    And ADR-003 (Dependency Injection Framework) section on layer boundaries should cite this exception

  @di_exception @layer_boundary
  Scenario: container.py imports from domain models and infrastructure simultaneously
    Given the file "src/cleveragents/application/container.py" is readable
    Then container.py should import domain types such as AIProviderInterface, AnalyzerRegistry, InMemoryGraphBackend, InMemoryTextBackend
    And container.py should import infrastructure types such as UnitOfWork, CheckpointRepository, SessionRepository, LLMTraceRepository

  # ---------------------------------------------------------------------------
  # ULID scope — domain entity IDs must be ULIDs; ephemeral internal IDs don't have to be
  # ---------------------------------------------------------------------------

  @ulid_scope @spec_clarification_10451
  Scenario: Domain entity Plan uses ULID for plan_id field
    When I verify the domain model for "Plan" at cleveragents.domain.models.core.plan
    Then the plan model should have a plan_id field typed as a ULID string (26 chars, Crockford alphabet)

  @ulid_scope @spec_clarification_10451
  Scenario: Decision entity uses ULID for decision_id
    When I verify the domain model for "Decision" at cleveragents.domain.models.core.decision
    Then the decision model should have a parent_plan_id field typed as a nullable ULID
    And the decision model should have a plan_id field typed as a ULID string

  @ulid_scope @spec_clarification_10451
  Scenario: Actor entity uses a namespaced identifier (not raw ULID)
    When I verify the domain model for "Actor" at cleveragents.domain.models.core.actor
    Then the actor model should use an actor_id field as its persistent identity format

  @ulid_scope @spec_clarification_10451
  Scenario: Child plans identified solely by ULID (no namespaced name) — spec clarification
    When I verify subplan identity rules in the specification
    Then child plans should use ULID identifiers only, not namespaced names
    And all operations on child plans reference them by plan ID (ULID)

  @ulid_scope @spec_clarification_10451
  Scenario: Ephemeral internal IDs are exempt from ULID requirement
    When I verify the ephemeral context fragment model
    Then ContextFragment should have a fragment_id field typed as any str (not mandated to be ULID)
    And the specification should clarify that domain entity identifiers must be ULIDs
    And ephemeral internal identifiers need not conform to ULID format

  @ulid_scope @spec_clarification_10451
  Scenario: Resource identifier uses ULID consistently
    When I verify the domain model for "Resource" at cleveragents.domain.models.core
    Then all resource identifiers should be ULIDs (resource_ulid field)

  # ---------------------------------------------------------------------------
  # ACMS pipeline per-stage protocol contracts with storage tier and budget enforcement
  # ---------------------------------------------------------------------------

  @acms_protocol @per_stage_contract
  Scenario: Phase 1 components define Pipeline Protocol interfaces
    Given the ACMS pipeline specification at docs/specification.md section "Context Assembly Pipeline"
    And I identify the Phase 1 — Strategy Orchestration components
    Then Phase 1 should have exactly three components: StrategySelector, BudgetAllocator, StrategyExecutor
    And each component must be defined as a @runtime_checkable Protocol

  @acms_protocol @per_stage_contract
  Scenario: Phase 2 (Fragment Fusion) protocol interfaces are specified
    Given the ACMS pipeline specification at docs/specification.md section "Context Assembly Pipeline"
    And I identify the Phase 2 — Fragment Fusion components
    Then Phase 2 should have exactly four components:
      | Component              | Protocol                          |
      | FragmentDeduplicator   | FragmentDeduplicatorProtocol      |
      | DetailDepthResolver    | DetailDepthResolverProtocol       |
      | FragmentScorer         | FragmentScorerProtocol            |
      | BudgetPacker           | BudgetPackerProtocol              |

  @acms_protocol @per_stage_contract
  Scenario: Phase 3 (Context Finalization) protocol interfaces are specified
    Given the ACMS pipeline specification at docs/specification.md section "Context Assembly Pipeline"
    And I identify the Phase 3 — Context Finalization components
    Then Phase 3 should have exactly two components: PreambleGenerator and SkeletonCompressor
    And each must be defined as a @runtime_checkable Protocol

  @acms_protocol @per_stage_contract
  Scenario: BudgetPacker enforces token budget limit (storage tier definition)
    Given the ACMS pipeline modules are available
    When I assemble with strategy "tiered" and budget 200 tokens from hot + warm tier fragments
    Then the payload total tokens should not exceed the specified budget of 200
    And BudgetPackerProtocol should guarantee total_tokens <= budget.max_tokens

  @acms_protocol @per_stage_contract
  Scenario: StrategyExecutor handles strategy failures gracefully with circuit breaking
    Given a pipeline with a custom coordinator that has a per-strategy cost cap
    When I coordinate with a budget of 100 tokens using the capped coordinator
    Then the coordination result should list strategies used without raising unhandled exceptions

  @acms_protocol @per_stage_contract
  Scenario: Fragment deduplication retains highest relevance score for duplicates
    Given fusion fragments with duplicates by URI and content
    When I fuse with a budget of 500 tokens
    Then the coordination fragment count should be less than or equal to total distinct resources
    And each unique resource_uri should appear at most once in the output

  @acms_protocol @per_stage_contract
  Scenario: SkeletonCompressor integrates with parent plan context hierarchy
    Given the ACMS pipeline specification describes skeleton compression for child plans
    When a child plan's ContextRequest is assembled via ACMSPipeline
    Then the payload should include skeleton_fragments derived from parent context

  # ---------------------------------------------------------------------------
  # TUI component public interfaces — 8+ components with verifiable checks
  # ---------------------------------------------------------------------------

  @tui_component @public_interface
  Scenario: TUI widgets module exports exactly the documented component classes
    Given the source directory is at "src/cleveragents"
    When I enumerate widgets exported from "tui/widgets/__init__.py"
    Then the following widget public interfaces should be present:
      | Component                     |
      | ActorSelectionOverlay         |
      | HelpPanelOverlay              |
      | PermissionQuestionWidget      |
      | PersonaBar                    |
      | PromptInput                   |
      | ReferencePickerOverlay        |
      | SlashCommandOverlay           |
      | ThoughtBlockWidget            |

  @tui_component @public_interface
  Scenario: All TUI widget classes are Textual-compatible with _StaticBase base
    Given the source directory is at "src/cleveragents"
    When I check each TUI widget file for its base class
    Then every widget in tui/widgets/ should derive from a Static base (Textual or Fallback)
    And this provides graceful degradation when Textual is not installed

  @tui_component @public_interface
  Scenario: PromptInput exposes mode-aware behavior (normal, command, shell, multi-line)
    When I verify the PromptInput class interface at cleveragents.tui.widgets.prompt
    Then PromptInput should support InputMode enum values for mode-dependent symbol rendering
    And PromptInput should emit a PromptSubmitted event on submission

  @tui_component @public_interface
  Scenario: PersonaBar provides content update API
    Given the TUI persona bar module is importable
    When I check PersonaBar's public methods
    Then PersonaBar should have a set_content method for updating display text

  @tui_component @public_interface
  Scenario: ReferencePickerOverlay exposes suggestion population API
    Given the TUI reference picker module is importable
    When I check ReferencePickerOverlay's public methods
    Then ReferencePickerOverlay should have a set_suggestions method accepting query and suggestion list

  @tui_component @public_interface
  Scenario: HelpPanelOverlay provides context-sensitive help rendering
    Given the source directory is at "src/cleveragents"
    Then HelpPanelOverlay should derive from a base Static widget class with _load_static_base

  @tui_component @public_interface
  Scenario: Throbber widget defined and documented in specification (8th+ component beyond widgets/)
    Given the TUI app module imports widgets
    When I verify throbber.py exists in tui/widgets/
    Then ThrobberWidget should be a valid widget class with update visibility and animation methods

  @tui_component @public_interface
  Scenario: TUI total public interface component count meets 8+ requirement
    When I count all classes exported from cleveragents.tui.widgets
    Then the total component count should be at least 8
    And the following minimum set must all be present:
      | Component              |
      | ActorSelectionOverlay  |
      | HelpPanelOverlay       |
      | PermissionQuestionWidget |
      | PersonaBar             |
      | PromptInput            |
      | ReferencePickerOverlay |
      | SlashCommandOverlay    |
      | ThoughtBlockWidget     |
      | ThrobberWidget         |
