Feature: Actor configuration uncovered lines coverage
  As a developer maintaining actor configuration parsing
  I want robust coverage for actor config edge cases
  So that failures and overrides are validated

  Background:
    Given an isolated actor config workspace

  # --- load_blob_from_file: lines 39-55 ---

  Scenario: Missing config file surfaces helpful error
    When I load the actor config blob from "missing.json"
    Then a ValueError should be raised containing "Config file not found"

  Scenario: JSON null config becomes empty mapping
    Given an actor config file "null.json" with content:
      """
      null
      """
    When I load the actor config blob from "null.json"
    Then the loaded actor config blob should equal {}

  Scenario: JSON list config raises validation error
    Given an actor config file "list.json" with content:
      """
      [1, 2, 3]
      """
    When I load the actor config blob from "list.json"
    Then a ValueError should be raised containing "Config must be a JSON or YAML object"

  Scenario: Valid JSON config is loaded correctly
    Given an actor config file "valid.json" with content:
      """
      {"provider": "openai", "model": "gpt-4"}
      """
    When I load the actor config blob from "valid.json"
    Then the loaded actor config blob should equal {"provider": "openai", "model": "gpt-4"}

  # --- _load_v2_yaml_content: lines 59-60 (yaml unavailable) ---

  Scenario: YAML dependency absence surfaces requirement
    Given PyYAML parsing is unavailable for actor config
    And an actor config file "needs_yaml.yaml" with content:
      """
      provider: openai
      """
    When I load the actor config blob from "needs_yaml.yaml"
    Then a ValueError should be raised containing "PyYAML is required for YAML actor configs"

  # --- _load_v2_yaml_content: lines 63-106 (YAML parsing paths) ---

  Scenario: Empty YAML returns empty object
    Given an actor config file "empty.yaml" with content:
      """
      """
    When I load the actor config blob from "empty.yaml"
    Then the loaded actor config blob should equal {}

  Scenario: Non-object YAML raises validation error
    Given an actor config file "list.yaml" with content:
      """
      - provider: openai
      """
    When I load the actor config blob from "list.yaml"
    Then a ValueError should be raised containing "Config must be a JSON or YAML object"

  Scenario: Plain YAML config is loaded via safe_load path
    Given an actor config file "plain.yaml" with content:
      """
      provider: openai
      model: gpt-4
      """
    When I load the actor config blob from "plain.yaml"
    Then the loaded actor config blob should equal {"provider": "openai", "model": "gpt-4"}

  # --- _load_v2_yaml_content: lines 64-92 (templated YAML branch) ---

  Scenario: Templated YAML preserves double-brace placeholders in system_prompt
    Given an actor config file "templated.yaml" with content:
      """
      provider: openai
      model: gpt-4
      system_prompt: "Use {{ context.paper_details.topic }} to write."
      """
    When I load the actor config blob from "templated.yaml"
    Then the loaded actor config value at "system_prompt" should equal "Use {{ context.paper_details.topic }} to write."

  Scenario: Templated YAML preserves block-tag placeholders in system_prompt
    Given an actor config file "block_template.yaml" with content:
      """
      provider: openai
      model: gpt-4
      system_prompt: "{% if context.brainstorming_summary %}summary{% endif %}"
      """
    When I load the actor config blob from "block_template.yaml"
    Then the loaded actor config value at "system_prompt" should contain "summary"

  # --- _restore_template_syntax: lines 110-130 (dict and list recursion) ---

  Scenario: Restore template syntax recurses into nested dicts
    Given an actor config file "nested_template.yaml" with content:
      """
      provider: openai
      model: gpt-4
      outer:
        system_prompt: "Hello {{ context.paper_details.topic }}"
      """
    When I load the actor config blob from "nested_template.yaml"
    Then the loaded actor config nested value at "outer.system_prompt" should equal "Hello {{ context.paper_details.topic }}"

  Scenario: Restore template syntax recurses into lists
    Given an actor config file "list_template.yaml" with content:
      """
      provider: openai
      model: gpt-4
      messages:
        - role: system
          system_prompt: "Topic is {{ context.paper_details.topic }}"
        - role: user
          content: "plain text"
      """
    When I load the actor config blob from "list_template.yaml"
    Then the loaded actor config nested value at "messages.0.system_prompt" should equal "Topic is {{ context.paper_details.topic }}"

  # --- _interpolate_env_vars: lines 134-174 (env var substitution and type coercion) ---

  Scenario: Environment variable interpolation uses default boolean value
    Given an actor config file "env_bool.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        flag: "${MISSING_BOOL_VAR:true}"
      """
    And the actor config environment variable "MISSING_BOOL_VAR" is unset
    When I load the actor config blob from "env_bool.yaml"
    Then the loaded actor config value at "options.flag" should equal True

  Scenario: Environment variable interpolation uses default false boolean value
    Given an actor config file "env_false.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        flag: "${MISSING_BOOL_FALSE:false}"
      """
    And the actor config environment variable "MISSING_BOOL_FALSE" is unset
    When I load the actor config blob from "env_false.yaml"
    Then the loaded actor config value at "options.flag" should equal False

  Scenario: Environment variable interpolation uses default integer value
    Given an actor config file "env_int.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        count: "${MISSING_INT_VAR:42}"
      """
    And the actor config environment variable "MISSING_INT_VAR" is unset
    When I load the actor config blob from "env_int.yaml"
    Then the loaded actor config value at "options.count" should equal 42

  Scenario: Environment variable interpolation uses default string value
    Given an actor config file "env_str.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        greeting: "${MISSING_STR_VAR:hello}"
      """
    And the actor config environment variable "MISSING_STR_VAR" is unset
    When I load the actor config blob from "env_str.yaml"
    Then the loaded actor config value at "options.greeting" should equal "hello"

  Scenario: Environment variable interpolation uses default float value
    Given an actor config file "env_float.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        ratio: "${MISSING_FLOAT_VAR:2.5}"
      """
    And the actor config environment variable "MISSING_FLOAT_VAR" is unset
    When I load the actor config blob from "env_float.yaml"
    Then the loaded actor config value at "options.ratio" should equal 2.5

  Scenario: Environment variable interpolation reads set env var
    Given an actor config file "env_set.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        api_key: "${TEST_ACTOR_API_KEY}"
      """
    And the actor config environment variable "TEST_ACTOR_API_KEY" is set to "secret123"
    When I load the actor config blob from "env_set.yaml"
    Then the loaded actor config value at "options.api_key" should equal "secret123"

  Scenario: Missing required environment variable raises an error
    Given an actor config file "required_env.yaml" with content:
      """
      provider: openai
      model: gpt-4
      secret: "${REQUIRED_SECRET}"
      """
    And the actor config environment variable "REQUIRED_SECRET" is unset
    When I load the actor config blob from "required_env.yaml"
    Then a ValueError should be raised containing "Environment variable 'REQUIRED_SECRET' is not set"

  Scenario: Environment variable coerces top-level string true to boolean
    Given an actor config file "env_top_bool.yaml" with content:
      """
      provider: openai
      model: gpt-4
      enabled: true
      """
    When I load the actor config blob from "env_top_bool.yaml"
    Then the loaded actor config value at "enabled" should equal True

  Scenario: Environment variable coerces string integer to int
    Given an actor config file "env_top_int.yaml" with content:
      """
      provider: openai
      model: gpt-4
      retries: 3
      """
    When I load the actor config blob from "env_top_int.yaml"
    Then the loaded actor config value at "retries" should equal 3

  Scenario: Interpolation coerces negative integer default
    Given an actor config file "env_neg_int.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        offset: "${MISSING_NEG_INT:-5}"
      """
    And the actor config environment variable "MISSING_NEG_INT" is unset
    When I load the actor config blob from "env_neg_int.yaml"
    Then the loaded actor config value at "options.offset" should equal -5

  Scenario: Interpolation recurses into nested dicts and lists
    Given an actor config file "env_nested.yaml" with content:
      """
      provider: openai
      model: gpt-4
      options:
        items:
          - "${MISSING_ITEM_VAR:default_item}"
      """
    And the actor config environment variable "MISSING_ITEM_VAR" is unset
    When I load the actor config blob from "env_nested.yaml"
    Then the loaded actor config nested value at "options.items.0" should equal "default_item"

  # --- from_file: lines 189-190 ---

  Scenario: from_file applies overrides and unsafe flag
    Given an actor config file "valid_ff.json" with content:
      """
      {"provider": "file-provider", "model": "file-model", "options": {"k": "v"}, "graph_descriptor": {"node": true}}
      """
    When I parse the actor configuration from file "valid_ff.json" with overrides:
      """
      {"name": "cli-name", "graph_descriptor": {"node": "override"}, "unsafe": true}
      """
    Then the actor configuration should have provider "file-provider" and model "file-model"
    And the actor configuration name should be "cli-name"
    And the actor configuration graph descriptor should equal {"node": "override"}
    And the actor configuration options should equal {"k": "v"}
    And the actor configuration unsafe flag should be true

  # --- from_blob: lines 236 (default_options), 238 (v2_options), 250 (missing model) ---

  Scenario: from_blob rejects missing provider
    When I build an actor configuration from blob {"model": "only-model"}
    Then a ValueError should be raised containing "provider is required"

  Scenario: from_blob rejects missing model
    When I build an actor configuration from blob {"provider": "only-provider"}
    Then a ValueError should be raised containing "model is required"

  Scenario: from_blob with None blob defaults to empty data
    When I build actor config from None blob with provider and model overrides
    Then the actor configuration should have provider "override-provider" and model "override-model"

  Scenario: from_blob reads provider_type and model_id aliases
    When I build an actor configuration from blob {"provider_type": "aliased-provider", "model_id": "aliased-model"}
    Then the actor configuration should have provider "aliased-provider" and model "aliased-model"

  Scenario: from_blob resolves graph from graph key alias
    When I build actor config from blob using graph key alias
    Then the actor configuration graph descriptor should equal {"step": "one"}

  Scenario: from_blob sets unsafe from blob data
    When I build an actor configuration from blob {"provider": "p", "model": "m", "unsafe": True}
    Then the actor configuration should have provider "p" and model "m"
    And the actor configuration unsafe flag should be true

  Scenario: from_blob with non-dict graph coerces to None
    When I build an actor configuration from blob {"provider": "p", "model": "m", "graph_descriptor": "not-a-dict"}
    Then the actor configuration should have provider "p" and model "m"
    And the actor configuration graph descriptor should be None
