@phase1 @domain @repository @skill_registry
Feature: Skill Registry Persistence
  As a system operator managing skills
  I want the skill registry to reliably persist, retrieve, and filter skills
  So that the execution layer can discover and resolve skill tool sets

  Background:
    Given a clean in-memory database with the skill registry schema
    And a skill registry repository backed by the database
    And a skill registry service backed by the repository

  # ---------------------------------------------------------------------------
  # Registering skills
  # ---------------------------------------------------------------------------

  @skill_reg_create
  Scenario: A new skill is registered and retrievable
    Given a valid skill named "local/code-tools" with description "Code tools"
    When the skill is registered through the skill registry service
    Then the skill registry service should not raise an error
    And the persisted skill should have the name "local/code-tools"

  @skill_reg_create
  Scenario: A skill with tool refs is registered
    Given a valid skill named "local/editor" with description "Editor tools"
    And the skill has tool refs "local/edit-file,local/read-file"
    When the skill is registered through the skill registry service
    Then the persisted skill should have 2 items of type "tool_ref"

  @skill_reg_create
  Scenario: A skill with includes is registered
    Given a valid skill named "local/full-stack" with description "Full stack"
    And the skill includes "local/frontend,local/backend"
    When the skill is registered through the skill registry service
    Then the persisted skill should have 2 items of type "include"

  @skill_reg_create
  Scenario: A skill with inline tools is registered
    Given a valid skill named "local/custom" with description "Custom tools"
    And the skill has an inline tool with description "Custom lint"
    When the skill is registered through the skill registry service
    Then the persisted skill should have 1 items of type "inline_tool"

  @skill_reg_create
  Scenario: A skill with MCP sources is registered
    Given a valid skill named "local/mcp-skill" with description "MCP tools"
    And the skill has an MCP source "github-server"
    When the skill is registered through the skill registry service
    Then the persisted skill should have 1 items of type "mcp_source"

  @skill_reg_create
  Scenario: A skill with agent sources is registered
    Given a valid skill named "local/agent-skill" with description "Agent tools"
    And the skill has an agent source "/skills/my-agent"
    When the skill is registered through the skill registry service
    Then the persisted skill should have 1 items of type "agent_source"

  @skill_reg_create @error_handling
  Scenario: Registering a skill with a duplicate name is rejected
    Given a valid skill named "local/code-tools" with description "Code tools"
    And the skill has already been registered once in the skill registry
    When a second skill with the same name "local/code-tools" is registered
    Then a DuplicateSkillError should be raised mentioning "local/code-tools"

  # ---------------------------------------------------------------------------
  # Retrieving skills
  # ---------------------------------------------------------------------------

  @skill_reg_get
  Scenario: Retrieving a non-existent skill returns None
    When I retrieve skill "local/nonexistent" from the skill registry
    Then the skill registry result should be None

  @skill_reg_get
  Scenario: Retrieving a registered skill returns correct data
    Given a valid skill named "local/dev-tools" with description "Dev tools"
    And the skill has tool refs "local/lint"
    When the skill is registered through the skill registry service
    And I retrieve skill "local/dev-tools" from the skill registry
    Then the persisted skill should have the name "local/dev-tools"
    And the persisted skill description should be "Dev tools"

  # ---------------------------------------------------------------------------
  # Listing skills with filters
  # ---------------------------------------------------------------------------

  @skill_reg_list
  Scenario: List skills returns all skills
    Given the following skills are registered:
      | name              | description     |
      | local/code-tools  | Code tools      |
      | local/dev-tools   | Dev tools       |
      | devops/deploy     | Deploy tools    |
    When I list all skills from the skill registry
    Then the skill list should contain 3 skills

  @skill_reg_list
  Scenario: List skills with namespace filter
    Given the following skills are registered:
      | name              | description     |
      | local/code-tools  | Code tools      |
      | local/dev-tools   | Dev tools       |
      | devops/deploy     | Deploy tools    |
    When I list skills from the skill registry with namespace "local"
    Then the skill list should contain 2 skills

  # ---------------------------------------------------------------------------
  # Updating skills
  # ---------------------------------------------------------------------------

  @skill_reg_update
  Scenario: Updating a skill changes its description
    Given a valid skill named "local/code-tools" with description "Code tools"
    And the skill is registered through the skill registry service
    When I update skill "local/code-tools" with description "Updated tools"
    Then the persisted skill description should be "Updated tools"

  @skill_reg_update @error_handling
  Scenario: Updating a non-existent skill raises error
    When I try to update a non-existent skill "local/ghost"
    Then a SkillNotFoundError should be raised

  # ---------------------------------------------------------------------------
  # Removing skills
  # ---------------------------------------------------------------------------

  @skill_reg_delete
  Scenario: Removing a registered skill succeeds
    Given a valid skill named "local/temp-skill" with description "Temp"
    And the skill is registered through the skill registry service
    When I remove skill "local/temp-skill" from the skill registry
    Then the skill removal should return True
    And I retrieve skill "local/temp-skill" from the skill registry
    And the skill registry result should be None

  @skill_reg_delete
  Scenario: Removing a non-existent skill returns False
    When I remove skill "local/nonexistent" from the skill registry
    Then the skill removal should return False

  # ---------------------------------------------------------------------------
  # Invalid include detection
  # ---------------------------------------------------------------------------

  @skill_reg_include @error_handling
  Scenario: A skill with invalid include name persists but include is stored
    Given a valid skill named "local/with-includes" with description "Has includes"
    And the skill includes "local/nonexistent-skill"
    When the skill is registered through the skill registry service
    Then the persisted skill should have 1 items of type "include"

  # ---------------------------------------------------------------------------
  # Overrides round-trip (TEST-1)
  # ---------------------------------------------------------------------------

  @skill_reg_overrides
  Scenario: Skill overrides survive persistence round-trip
    Given a valid skill named "local/override-test" with overrides for "local/tool-a"
    When the skill is registered and retrieved with overrides check
    Then the skill registry service should not raise an error
    And the retrieved skill should have overrides for "local/tool-a"

  # ---------------------------------------------------------------------------
  # Item ordering stability (TEST-1)
  # ---------------------------------------------------------------------------

  @skill_reg_ordering
  Scenario: Skill items maintain stable ordering across round-trip
    Given a valid skill named "local/ordered-test" with mixed item types
    And the skill is registered through the skill registry service
    When I retrieve the skill and check item ordering
    Then the retrieved skill should have items in stable order

  # ---------------------------------------------------------------------------
  # Name validation at persistence layer (SEC-1 / TEST-1)
  # ---------------------------------------------------------------------------

  @skill_reg_name_validation @error_handling
  Scenario: Empty name is rejected at persistence layer
    When I register a skill with empty name via dict bypass
    Then a ValueError should be raised about invalid skill name

  @skill_reg_name_validation @error_handling
  Scenario: Name without slash is rejected at persistence layer
    When I register a skill with invalid name "noslash" via dict bypass
    Then a ValueError should be raised about invalid skill name

  @skill_reg_name_validation @error_handling
  Scenario: Name with special characters is rejected at persistence layer
    When I register a skill with invalid name "bad/na me!" via dict bypass
    Then a ValueError should be raised about invalid skill name

  # ---------------------------------------------------------------------------
  # Large payload (TEST-1)
  # ---------------------------------------------------------------------------

  @skill_reg_large
  Scenario: Skill with 50 tool refs persists correctly
    Given a valid skill named "local/large-skill" with 50 tool refs
    When the skill is registered through the skill registry service
    Then the persisted skill should have 50 tool refs

  # ---------------------------------------------------------------------------
  # Domain object return type (DESIGN-1)
  # ---------------------------------------------------------------------------

  @skill_reg_domain
  Scenario: Listed skills are proper Skill domain objects
    Given the following skills are registered:
      | name              | description     |
      | local/code-tools  | Code tools      |
      | local/dev-tools   | Dev tools       |
    When I list all skills from the skill registry
    Then the skill list entries should all be Skill domain objects
