Feature: Consolidated Action
  Combined scenarios from: action_cli_additional_coverage, action_model, action_model_branch_coverage, action_schema

  # ============================================================
  # Originally from: action_cli_additional_coverage.feature
  # Feature: Action CLI additional coverage
  # ============================================================

  Scenario: Resolve lifecycle service from container settings
    Given a mocked container settings for action lifecycle
    When I resolve the action lifecycle service
    Then the lifecycle service should use container settings


  Scenario: Resolve lifecycle service twice yields new instances
    Given a mocked container settings for action lifecycle
    When I resolve the action lifecycle service twice
    Then the lifecycle service should use container settings
    And the lifecycle service instances should be distinct


  # ============================================================
  # Originally from: action_model.feature
  # Feature: Action Domain Model
  # ============================================================

  Scenario: Parse required string argument
    When I parse the action argument "name:string:required:User name"
    Then the argument name should be "name"
    And the argument type should be "string"
    And the argument should be required
    And the argument description should be "User name"


  Scenario: Parse optional integer argument
    When I parse the action argument "count:integer:optional:Number of items"
    Then the argument name should be "count"
    And the argument type should be "integer"
    And the argument should be optional


  Scenario: Parse argument without description
    When I parse the action argument "flag:boolean:required"
    Then the argument name should be "flag"
    And the argument type should be "boolean"
    And the argument description should be empty


  Scenario: Parse legacy short type names via _missing_
    When I parse the action argument "name:str:required:User name"
    Then the argument type should be "string"
    When I parse the action argument "count:int:optional:Count"
    Then the argument type should be "integer"
    When I parse the action argument "flag:bool:required:Flag"
    Then the argument type should be "boolean"


  Scenario: Invalid argument format raises error
    When I try to parse the action argument "invalid"
    Then an argument parse error should be raised


  Scenario: Invalid argument type raises error
    When I try to parse the action argument "name:badtype:required:desc"
    Then an argument parse error should be raised


  Scenario: Invalid argument requirement raises error
    When I try to parse the action argument "name:string:sometimes:desc"
    Then an argument parse error should be raised


  Scenario: Invalid argument name raises error
    When I try to create an action argument with invalid name "1invalid"
    Then a validation error should be raised
    And the error should mention "Argument name must be a valid Python identifier"


  Scenario: Invalid argument name with hyphen raises error
    When I try to create an action argument with invalid name "invalid-name"
    Then a validation error should be raised
    And the error should mention "Argument name must be a valid Python identifier"


  Scenario: Stringify action argument definition
    When I parse the action argument "limit:integer:required:Limit value"
    And I stringify the action argument
    Then the argument definition string should be "limit:integer:required:Limit value"


  Scenario: Stringify optional list argument definition
    When I parse the action argument "targets:list:optional:Targets to check"
    And I stringify the action argument
    Then the argument definition string should be "targets:list:optional:Targets to check"

    # Action Creation Tests


  Scenario: Create minimal action
    When I create an action with name "local/test-action" and definition of done "Tests pass"
    Then the action should be created
    And the action namespace should be "local"
    And the action name should be "test-action"
    And the action state should be "available"


  Scenario: Create action with arguments
    Given I have action arguments
      | name          | type    | requirement | description              |
      | coverage      | integer | required    | Target coverage percent  |
      | framework     | string  | optional    | Test framework to use    |
    When I create an action with these arguments
    Then the action should have 2 arguments
    And the action should have 1 required argument
    And the action should have 1 optional argument


  Scenario: Validate arguments - all required provided
    Given I have an action with required argument "target:integer:required:Target value"
    When I validate arguments with target 85
    Then the validation should pass


  Scenario: Validate arguments - missing required
    Given I have an action with required argument "target:integer:required:Target value"
    When I validate arguments without target
    Then the validation should fail with "Missing required argument: target"


  Scenario: Validate arguments - unknown argument
    Given I have an action with required argument "target:integer:required:Target value"
    When I validate arguments with target 85 and extra "foo"
    Then the validation should fail with "Unknown argument: extra"


  Scenario: Validate arguments - wrong type
    Given I have an action with required argument "target:integer:required:Target value"
    When I validate arguments with target as string "not-a-number"
    Then the validation should fail with "must be an integer"


  Scenario: Validate arguments - integer below minimum
    Given I have an action with bounded integer argument "priority" min 1 max 5
    When I validate arguments with "priority" set to 0
    Then the validation should fail with "Argument priority must be >= 1"


  Scenario: Validate arguments - integer above maximum
    Given I have an action with bounded integer argument "priority" min 1 max 5
    When I validate arguments with "priority" set to 6
    Then the validation should fail with "Argument priority must be <= 5"


  Scenario: Validate arguments - float expects numeric
    Given I have an action with argument "threshold" of type "float"
    When I validate arguments with "threshold" set to "high"
    Then the validation should fail with "Argument threshold must be a number"


  Scenario: Validate arguments - boolean expects boolean
    Given I have an action with argument "dry_run" of type "boolean"
    When I validate arguments with "dry_run" set to "yes"
    Then the validation should fail with "Argument dry_run must be a boolean"


  Scenario: Validate arguments - list expects list
    Given I have an action with argument "targets" of type "list"
    When I validate arguments with "targets" set to "api,cli"
    Then the validation should fail with "Argument targets must be a list"

    # Action State Tests


  Scenario: New action starts in available state
    When I create a new action
    Then the action state should be "available"


  Scenario: Action can be archived from available
    Given I have an available action
    When I set the action state to archived
    Then the action state should be "archived"

    # Actor Configuration Tests


  Scenario: Action requires strategy and execution actors
    When I try to create an action without strategy actor
    Then a validation error should be raised


  Scenario: Action can have optional review actor
    When I create an action with review actor "local/code-reviewer"
    Then the action should have a review actor


  Scenario: Action can have optional estimation actor
    When I create an action with estimation actor "local/cost-estimator"
    Then the action should have an estimation actor

    # Reusability Tests


  Scenario: Actions are reusable by default
    When I create a new action
    Then the action should be reusable


  Scenario: Action can be non-reusable
    When I create a non-reusable action
    Then the action should not be reusable

    # Read-only Tests


  Scenario: Actions are not read-only by default
    When I create a new action
    Then the action should not be read-only


  Scenario: Action can be marked read-only
    When I create a read-only action
    Then the action should be read-only

    # Invariants Sanitization Tests


  Scenario: Invariants are sanitized on creation
    When I create an action model with invariants "  no secrets  " and "" and "  no secrets" and "keep data safe"
    Then the action model invariants should be "no secrets" and "keep data safe"


  Scenario: Invariants None defaults to empty list
    When I create an action model with null invariants
    Then the action model invariants count should be 0

    # from_config Factory Tests


  Scenario: Create action from config dict
    When I create an action model from config with name "local/my-action" and description "Run tests" and dod "All tests green"
    Then the action should be created
    And the action name should be "my-action"
    And the action model description should be "Run tests"
    And the action state should be "available"


  Scenario: from_config with arguments
    When I create an action model from config with arguments
    Then the action should have 2 arguments
    And the action should have 1 required argument
    And the action should have 1 optional argument


  Scenario: from_config missing name raises error
    When I try to create an action model from config missing "name"
    Then an action model config error should be raised with "name"


  Scenario: from_config missing description raises error
    When I try to create an action model from config missing "description"
    Then an action model config error should be raised with "description"


  Scenario: from_config missing strategy_actor raises error
    When I try to create an action model from config missing "strategy_actor"
    Then an action model config error should be raised with "strategy_actor"


  Scenario: from_config missing execution_actor raises error
    When I try to create an action model from config missing "execution_actor"
    Then an action model config error should be raised with "execution_actor"


  Scenario: from_config missing definition_of_done raises error
    When I try to create an action model from config missing "definition_of_done"
    Then an action model config error should be raised with "definition_of_done"

    # as_cli_dict Tests


  Scenario: as_cli_dict returns stable dict
    When I create an action model and call as_cli_dict
    Then the action model cli dict should have key "name"
    And the action model cli dict should have key "description"
    And the action model cli dict should have key "state"
    And the action model cli dict should have key "strategy_actor"
    And the action model cli dict should have key "execution_actor"
    And the action model cli dict should have key "definition_of_done"
    And the action model cli dict should have key "reusable"
    And the action model cli dict should have key "read_only"
    And the action model cli dict should have key "created_at"


  Scenario: as_cli_dict includes optional actors when set
    When I create an action model with review actor and call as_cli_dict
    Then the action model cli dict should have key "review_actor"


  Scenario: as_cli_dict includes arguments when present
    When I create an action model with arguments and call as_cli_dict
    Then the action model cli dict should have key "arguments"
    And the action model cli dict arguments count should be 1

    # from_mapping Tests (ActionArgument)


  Scenario: ActionArgument from_mapping basic
    When I create an action argument from basic mapping "coverage" type "integer" required true
    Then the argument name should be "coverage"
    And the argument type should be "integer"
    And the argument should be required


  Scenario: ActionArgument from_mapping optional with default
    When I create an action argument from mapping with default "framework" type "string" required false default "pytest"
    Then the argument name should be "framework"
    And the argument should be optional
    And the action model argument default value should be "pytest"


  Scenario: ActionArgument from_mapping missing name raises error
    When I try to create an action argument from mapping missing name
    Then an action model argument mapping error should be raised with "name"


  Scenario: ActionArgument from_mapping missing type raises error
    When I try to create an action argument from mapping missing type
    Then an action model argument mapping error should be raised with "type"

    # coerce_value Tests


  Scenario: Coerce string value
    Given I have an action model string argument named "label"
    When I coerce action model value "hello" for the argument
    Then the coerced action model value should be string "hello"


  Scenario: Coerce integer value
    Given I have an action model integer argument named "count"
    When I coerce action model value "42" for the argument
    Then the coerced action model value should be integer 42


  Scenario: Coerce float value
    Given I have an action model float argument named "ratio"
    When I coerce action model value "3.14" for the argument
    Then the coerced action model value should be float 3.14


  Scenario: Coerce boolean true values
    Given I have an action model boolean argument named "flag"
    When I coerce action model value "true" for the argument
    Then the coerced action model value should be boolean true
    When I coerce action model value "yes" for the argument
    Then the coerced action model value should be boolean true
    When I coerce action model value "1" for the argument
    Then the coerced action model value should be boolean true


  Scenario: Coerce boolean false values
    Given I have an action model boolean argument named "flag"
    When I coerce action model value "false" for the argument
    Then the coerced action model value should be boolean false
    When I coerce action model value "no" for the argument
    Then the coerced action model value should be boolean false
    When I coerce action model value "0" for the argument
    Then the coerced action model value should be boolean false


  Scenario: Coerce invalid boolean raises error
    Given I have an action model boolean argument named "flag"
    When I try to coerce action model value "maybe" for the argument
    Then an action model coerce error should be raised


  Scenario: Coerce invalid integer raises error
    Given I have an action model integer argument named "count"
    When I try to coerce action model value "abc" for the argument
    Then an action model coerce error should be raised


  Scenario: Coerce list value
    Given I have an action model list argument named "items"
    When I coerce action model value "a, b, c" for the argument
    Then the coerced action model value should be list with 3 items

    # render_template Tests


  Scenario: Render template with arguments
    When I create an action model with description "Cover ${target}% for ${module}"
    And I render action model description with target "90" and module "api"
    Then the rendered action model description should be "Cover 90% for api"


  Scenario: Render template missing placeholder raises error
    When I create an action model with description "Cover ${target}% for ${module}"
    And I try to render action model description with only target "90"
    Then an action model template error should be raised


  Scenario: Render definition of done with arguments
    When I create an action model with dod template for module and target
    And I render action model dod with target "80" and module "core"
    Then the rendered action model dod should be "All tests in core pass with 80% coverage"

    # inputs_schema Validation Tests


  Scenario: inputs_schema accepts valid dict
    When I create an action model with inputs schema type "object" and required "name"
    Then the action should be created
    And the action model inputs schema should not be none


  Scenario: inputs_schema accepts None
    When I create an action model with null inputs schema
    Then the action should be created
    And the action model inputs schema should be none


  Scenario: inputs_schema rejects non-dict
    When I try to create an action model with inputs schema as string
    Then a validation error should be raised

    # automation_profile Validation Tests


  Scenario: automation_profile trims whitespace
    When I create an action model with automation profile "  fast  "
    Then the action model automation profile should be "fast"


  Scenario: automation_profile blank becomes None
    When I create an action model with automation profile "   "
    Then the action model automation profile should be none


  Scenario: automation_profile None stays None
    When I create an action model with null automation profile
    Then the action model automation profile should be none


  # ============================================================
  # Originally from: action_model_branch_coverage.feature
  # Feature: Action Model Branch Coverage
  # ============================================================

  Scenario: Validate arguments - valid float value passes validation
    Given I have an action with a float argument named "ratio"
    When I validate the action arguments with "ratio" as float 3.14
    Then the action argument validation should pass with no errors


  Scenario: Validate arguments - valid integer value for float argument passes
    Given I have an action with a float argument named "score"
    When I validate the action arguments with "score" as integer 42
    Then the action argument validation should pass with no errors


  Scenario: Validate arguments - valid boolean true passes validation
    Given I have an action with a boolean argument named "verbose"
    When I validate the action arguments with "verbose" as boolean true
    Then the action argument validation should pass with no errors


  Scenario: Validate arguments - valid boolean false passes validation
    Given I have an action with a boolean argument named "dry_run"
    When I validate the action arguments with "dry_run" as boolean false
    Then the action argument validation should pass with no errors


  Scenario: Validate arguments - valid list passes validation
    Given I have an action with a list argument named "targets"
    When I validate the action arguments with "targets" as list "api,cli,web"
    Then the action argument validation should pass with no errors


  Scenario: Validate arguments - empty list passes validation
    Given I have an action with a list argument named "items"
    When I validate the action arguments with "items" as an empty list
    Then the action argument validation should pass with no errors

    # Float type with min/max - the code currently does NOT check min/max for float,
    # so a float with min/max set should still pass (only int has min/max enforcement)


  Scenario: Validate arguments - float with min max bounds still passes
    Given I have an action with a bounded float argument "temperature" min 0.0 max 1.0
    When I validate the action arguments with "temperature" as float 0.5
    Then the action argument validation should pass with no errors

    # Multiple argument types in one action


  Scenario: Validate arguments - mixed types all valid
    Given I have an action with mixed argument types
      | name       | type  | requirement |
      | label      | str   | required    |
      | count      | int   | required    |
      | ratio      | float | required    |
      | enabled    | bool  | required    |
      | tags       | list  | optional    |
    When I validate the action with all mixed arguments provided correctly
    Then the action argument validation should pass with no errors

    # ActionArgument.parse for float and list types


  Scenario: Parse a float type action argument
    When I parse an action argument definition "ratio:float:required:Ratio value"
    Then the parsed argument name should be "ratio"
    And the parsed argument type should be "float"
    And the parsed argument should be required
    And the parsed argument description should be "Ratio value"


  Scenario: Parse a list type action argument
    When I parse an action argument definition "items:list:optional:List of items"
    Then the parsed argument name should be "items"
    And the parsed argument type should be "list"
    And the parsed argument should be optional
    And the parsed argument description should be "List of items"

    # Action metadata fields


  Scenario: Action with tags and created_by metadata
    When I create an action with tags "ci,testing,coverage" and created_by "user-123"
    Then the action should have 3 tags
    And the action created_by should be "user-123"


  Scenario: Action with description and long description
    When I create an action with description "Quick summary" and long description "This is a detailed description of the action and what it does."
    Then the action description should be "Quick summary"
    And the action long description should contain "detailed description"


  Scenario: Action with apply actor set
    When I create an action with apply_actor "local/merge-bot"
    Then the action apply_actor should be "local/merge-bot"

    # Validate assignment on ActionArgument model config


  Scenario: ActionArgument validates assignment on field change
    Given I have a parsed action argument from "count:int:required:A counter"
    When I change the action argument description to "Updated counter"
    Then the action argument description should now be "Updated counter"

    # Validate assignment on Action model config


  Scenario: Action validates assignment when state is changed
    Given I have a newly created action in available state
    When I change the action state to "archived"
    Then the action current state should be "archived"

    # String type passes through without type check (default/no-op path)


  Scenario: Validate arguments - string value needs no type enforcement
    Given I have an action with a string argument named "label"
    When I validate the action arguments with "label" as string "hello"
    Then the action argument validation should pass with no errors


  # ============================================================
  # Originally from: action_schema.feature
  # Feature: Action YAML schema validation
  # ============================================================

  Scenario: Load a minimal valid action YAML
    Given an action YAML string with only required fields
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config name should be "local/simple-action"
    And the action config strategy_actor should be "openai/gpt-4"
    And the action config execution_actor should be "openai/gpt-4"


  Scenario: Load a valid action YAML with all optional fields
    Given an action YAML string with all optional fields populated
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config reusable should be true
    And the action config read_only should be false
    And the action config state should be "available"
    And the action config estimation_actor should be "local/estimator"
    And the action config review_actor should be "local/reviewer"
    And the action config apply_actor should be "local/applier"
    And the action config invariant_actor should be "local/invariant-resolver"


  Scenario: Load the simple example YAML
    Given the action YAML file "examples/actions/simple.yaml"
    When I validate the action schema from file
    Then the action schema validation should succeed


  Scenario: Load the invariant-heavy example YAML
    Given the action YAML file "examples/actions/invariant-heavy.yaml"
    When I validate the action schema from file
    Then the action schema validation should succeed


  Scenario: Load the read-only example YAML
    Given the action YAML file "examples/actions/read-only.yaml"
    When I validate the action schema from file
    Then the action schema validation should succeed


  Scenario: Load the estimation-actor example YAML
    Given the action YAML file "examples/actions/estimation-actor.yaml"
    When I validate the action schema from file
    Then the action schema validation should succeed


  Scenario: Load the inputs-schema example YAML
    Given the action YAML file "examples/actions/inputs-schema.yaml"
    When I validate the action schema from file
    Then the action schema validation should succeed


  Scenario: Optional fields have correct defaults when omitted
    Given an action YAML string with only required fields
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config reusable should be true
    And the action config read_only should be false
    And the action config state should be "available"
    And the action config invariants list should be empty
    And the action config arguments list should be empty


  Scenario: Action with arguments validates correctly
    Given an action YAML string with typed arguments
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config should have 2 arguments
    And action argument 0 name should be "target_coverage"
    And action argument 0 type should be "integer"
    And action argument 1 name should be "test_command"
    And action argument 1 type should be "string"

    # ────────────────────────────────────────────────────────────
    # Invalid schema scenarios
    # ────────────────────────────────────────────────────────────


  Scenario: Missing name field produces a clear error
    Given an action YAML string missing the "name" field
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "name"


  Scenario: Missing strategy_actor produces a clear error
    Given an action YAML string missing the "strategy_actor" field
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "strategy_actor"


  Scenario: Missing execution_actor produces a clear error
    Given an action YAML string missing the "execution_actor" field
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "execution_actor"


  Scenario: Missing definition_of_done produces a clear error
    Given an action YAML string missing the "definition_of_done" field
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "definition_of_done"


  Scenario: Missing description produces a clear error
    Given an action YAML string missing the "description" field
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "description"


  Scenario: Invalid namespaced name without slash
    Given an action YAML string with name "invalid-name-no-slash"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "namespace/name"


  Scenario: Invalid namespaced name with special characters
    Given an action YAML string with name "local/bad name!!"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "namespace/name"


  Scenario: Uppercase namespace is rejected by ActionConfigSchema
    Given an action YAML string with name "MyOrg/my-action"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "namespace/name"


  Scenario: Uppercase name part is rejected by ActionConfigSchema
    Given an action YAML string with name "myorg/MyAction"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "namespace/name"


  Scenario: Fully uppercase namespaced name is rejected by ActionConfigSchema
    Given an action YAML string with name "MyOrg/MyAction"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "namespace/name"


  Scenario: Invalid argument type
    Given an action YAML string with an argument of type "array"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "type"


  Scenario: Invalid state value
    Given an action YAML string with state "draft"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "state"


  Scenario: Invalid argument name
    Given an action YAML string with an argument named "123bad"
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "identifier"


  Scenario: None YAML string raises ValueError
    Given a None action YAML string
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "None"


  Scenario: Empty YAML string raises ValueError
    Given an empty action YAML string
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "empty"


  Scenario: YAML that is a list instead of a mapping
    Given an action YAML string that is a list
    When I validate the action schema expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "mapping"


  Scenario: None file path raises ValueError
    Given a None action YAML file path
    When I validate the action schema from file expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "None"


  Scenario: Non-existent file raises FileNotFoundError
    Given the action YAML file "examples/actions/nonexistent.yaml"
    When I validate the action schema from file expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "not found"


  Scenario: Directory path raises ValueError
    Given the action YAML directory path "examples/actions"
    When I validate the action schema from file expecting failure
    Then the action schema validation should fail
    And the action schema error should mention "not a file"

    # ────────────────────────────────────────────────────────────
    # Invariant normalization scenarios
    # ────────────────────────────────────────────────────────────


  Scenario: Empty invariants are dropped
    Given an action YAML string with empty invariant strings
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config invariants list should be empty


  Scenario: Duplicate invariants are de-duplicated preserving order
    Given an action YAML string with duplicate invariants
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config should have 2 invariants
    And action invariant 0 should be "No secrets in code"
    And action invariant 1 should be "All tests must pass"


  Scenario: Invariant whitespace is trimmed
    Given an action YAML string with whitespace-padded invariants
    When I validate the action schema
    Then the action schema validation should succeed
    And action invariant 0 should be "Keep it clean"

    # ────────────────────────────────────────────────────────────
    # Key normalization scenarios
    # ────────────────────────────────────────────────────────────


  Scenario: camelCase keys are normalized to snake_case
    Given an action YAML string with camelCase keys
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config strategy_actor should be "openai/gpt-4"
    And the action config execution_actor should be "openai/gpt-4"

    # ────────────────────────────────────────────────────────────
    # Environment variable interpolation
    # ────────────────────────────────────────────────────────────


  Scenario: Environment variable interpolation in YAML values
    Given the environment variable "TEST_ACTOR" is set to "openai/gpt-4"
    And an action YAML string using env var "${TEST_ACTOR}" for strategy_actor

    When I validate the action schema
    Then the action schema validation should succeed
    And the action config strategy_actor should be "openai/gpt-4"

    # ────────────────────────────────────────────────────────────
    # Round-trip serialization
    # ────────────────────────────────────────────────────────────


  Scenario: Schema model serializes to dict correctly
    Given an action YAML string with all optional fields populated
    When I validate the action schema
    Then the action schema validation should succeed
    And the action config model_dump should contain key "name"
    And the action config model_dump should contain key "strategy_actor"
