@phase1 @domain @repository @coverage
Feature: Repository Error Resilience and Edge-Case Coverage
  As a system operating under varying database conditions
  I want all repositories to handle transient failures and edge-case inputs
  So that callers receive consistent domain errors regardless of driver exceptions

  # ==========================================================================
  # Session Repository — conditional logic and error branches
  # ==========================================================================

  # ---- list_all with actor_name filter (line 3131) ----

  @session_repo @filter
  Scenario: Listing sessions filtered by actor name returns only matching sessions
    Given a clean in-memory database for repository coverage
    And a session repository backed by the coverage database
    When two sessions are created with actor "local/orchestrator"
    And one session is created with actor "local/planner"
    And sessions are listed filtered by actor "local/orchestrator"
    Then the filtered session list should contain 2 entries

  # ---- update on non-existent session (line 3184) ----

  @session_repo @error
  Scenario: Updating a non-existent session raises a database error
    Given a clean in-memory database for repository coverage
    And a session repository backed by the coverage database
    When a session update is attempted for a non-existent session identifier
    Then a DatabaseError should be raised mentioning "not found for update"

  # ---- create OperationalError branch (lines 3095-3097) ----

  @session_repo @transient_error
  Scenario: A transient database failure during session creation is wrapped in DatabaseError
    Given a session repository whose session raises OperationalError on flush
    When a session is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create session"

  # ---- create IntegrityError non-unique branch (lines 3092-3094) ----

  @session_repo @transient_error
  Scenario: A non-unique integrity violation during session creation is wrapped in DatabaseError
    Given a session repository whose session raises a non-unique IntegrityError on flush
    When a session is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create session"

  # ---- get_by_id OperationalError branch (lines 3114-3115) ----

  @session_repo @transient_error
  Scenario: A transient database failure during session retrieval is wrapped in DatabaseError
    Given a session repository whose session raises OperationalError on query
    When a session is retrieved by identifier and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get session"

  # ---- list_all OperationalError branch (lines 3134-3135) ----

  @session_repo @transient_error
  Scenario: A transient database failure during session listing is wrapped in DatabaseError
    Given a session repository whose session raises OperationalError on query
    When sessions are listed and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to list sessions"

  # ---- delete OperationalError branch (lines 3157-3159) ----

  @session_repo @transient_error
  Scenario: A transient database failure during session deletion is wrapped in DatabaseError
    Given a session repository whose session raises OperationalError on query
    When a session is deleted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to delete session"

  # ---- update OperationalError branch (lines 3209-3211) ----

  @session_repo @transient_error
  Scenario: A transient database failure during session update is wrapped in DatabaseError
    Given a session repository whose session raises OperationalError on query
    When a session is updated and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to update session"

  # ==========================================================================
  # Session Message Repository — error branches
  # ==========================================================================

  # ---- append OperationalError branch (lines 3254-3256) ----

  @session_msg_repo @transient_error
  Scenario: A transient database failure during message append is wrapped in DatabaseError
    Given a session message repository whose session raises OperationalError on flush
    When a message is appended and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to append message"

  # ---- get_for_session OperationalError branch (lines 3289-3290) ----

  @session_msg_repo @transient_error
  Scenario: A transient database failure during message retrieval is wrapped in DatabaseError
    Given a session message repository whose session raises OperationalError on query
    When messages are retrieved and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get messages"

  # ---- count_for_session OperationalError branch (lines 3311-3312) ----

  @session_msg_repo @transient_error
  Scenario: A transient database failure during message counting is wrapped in DatabaseError
    Given a session message repository whose session raises OperationalError on query
    When messages are counted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to count messages"

  # ==========================================================================
  # Tool Registry Repository — update not-found and error branches
  # ==========================================================================

  # ---- update on non-existent tool (line 2778) ----

  @tool_repo @error
  Scenario: Updating a non-existent tool raises a database error
    Given a clean in-memory database for repository coverage
    And a tool registry repository backed by the coverage database
    When a tool update is attempted for non-existent tool "local/phantom"
    Then a DatabaseError should be raised mentioning "not found for update"

  # ---- create OperationalError branch (lines 2701-2703) ----

  @tool_repo @transient_error
  Scenario: A transient database failure during tool creation is wrapped in DatabaseError
    Given a tool registry repository whose session raises OperationalError on flush
    When a tool is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create tool"

  # ---- create non-unique IntegrityError (line 2700) ----

  @tool_repo @transient_error
  Scenario: A non-unique integrity violation during tool creation is wrapped in DatabaseError
    Given a tool registry repository whose session raises a non-unique IntegrityError on flush
    When a tool is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create tool"

  # ---- get_by_name OperationalError (lines 2718-2719) ----

  @tool_repo @transient_error
  Scenario: A transient database failure during tool retrieval is wrapped in DatabaseError
    Given a tool registry repository whose session raises OperationalError on query
    When a tool is retrieved by name and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get tool"

  # ---- list_all OperationalError (lines 2749-2750) ----

  @tool_repo @transient_error
  Scenario: A transient database failure during tool listing is wrapped in DatabaseError
    Given a tool registry repository whose session raises OperationalError on query
    When tools are listed and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to list tools"

  # ---- update OperationalError (lines 2821-2823) ----

  @tool_repo @transient_error
  Scenario: A transient database failure during tool update is wrapped in DatabaseError
    Given a tool registry repository whose session raises OperationalError on query
    When a tool is updated and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to update tool"

  # ---- delete OperationalError (lines 2860-2862) ----

  @tool_repo @transient_error
  Scenario: A transient database failure during tool deletion is wrapped in DatabaseError
    Given a tool registry repository whose session raises OperationalError on query
    When a tool is deleted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to delete tool"

  # ==========================================================================
  # Validation Attachment Repository — args serialisation and error branches
  # ==========================================================================

  # ---- attach with args (line 2913) ----

  @validation_repo @logic
  Scenario: Attaching a validation with arguments serialises them to JSON
    Given a clean in-memory database for repository coverage
    And a tool registry repository backed by the coverage database
    And a validation attachment repository backed by the coverage database
    And a registered validation tool named "local/schema-check"
    When a validation is attached to resource "res-001" with arguments
    Then the attachment should store the arguments as JSON

  # ---- get_by_id returns None (line 3033) ----

  @validation_repo @logic
  Scenario: Retrieving a non-existent attachment by identifier returns nothing
    Given a clean in-memory database for repository coverage
    And a validation attachment repository backed by the coverage database
    When an attachment is retrieved by non-existent identifier
    Then the attachment result should be empty

  # ---- attach OperationalError (lines 2937-2939) ----

  @validation_repo @transient_error
  Scenario: A transient database failure during validation attach is wrapped in DatabaseError
    Given a validation attachment repository whose session raises OperationalError on flush
    When a validation is attached and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to attach validation"

  # ---- detach OperationalError (lines 2963-2965) ----

  @validation_repo @transient_error
  Scenario: A transient database failure during validation detach is wrapped in DatabaseError
    Given a validation attachment repository whose session raises OperationalError on query
    When a validation is detached and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to detach"

  # ---- list_for_resource OperationalError (lines 3013-3014) ----

  @validation_repo @transient_error
  Scenario: A transient database failure during attachment listing is wrapped in DatabaseError
    Given a validation attachment repository whose session raises OperationalError on query
    When attachments are listed and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to list"

  # ---- get_by_id OperationalError (lines 3044-3045) ----

  @validation_repo @transient_error
  Scenario: A transient database failure during attachment retrieval is wrapped in DatabaseError
    Given a validation attachment repository whose session raises OperationalError on query
    When an attachment is retrieved and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get attachment"

  # ==========================================================================
  # Lifecycle Plan Repository — error branches
  # ==========================================================================

  # ---- create non-unique IntegrityError (line 1202) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A non-unique integrity violation during lifecycle plan creation is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises a non-unique IntegrityError on flush
    When a lifecycle plan is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create plan"

  # ---- create OperationalError (lines 1203-1205) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan creation is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on flush
    When a lifecycle plan is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create plan"

  # ---- get OperationalError (lines 1220-1221) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan get is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on query
    When a lifecycle plan is retrieved and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get plan"

  # ---- get_by_name OperationalError (lines 1240-1241) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan get-by-name is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on query
    When a lifecycle plan is retrieved by name and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get plan by name"

  # ---- update OperationalError (lines 1395-1397) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan update is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on query
    When a lifecycle plan is updated and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to update plan"

  # ---- delete OperationalError (lines 1420-1422) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan deletion is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on query
    When a lifecycle plan is deleted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to delete plan"

  # ---- list_plans OperationalError (lines 1471-1472) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan listing is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on query
    When lifecycle plans are listed and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to list plans"

  # ---- count OperationalError (lines 1499-1500) ----

  @lifecycle_plan_repo @transient_error
  Scenario: A transient database failure during lifecycle plan count is wrapped in DatabaseError
    Given a lifecycle plan repository whose session raises OperationalError on query
    When lifecycle plans are counted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to count plans"

  # ==========================================================================
  # Resource Repository — namespace filter and error branches
  # ==========================================================================

  # ---- list_resources with namespace filter (line 2068) ----

  @resource_repo @filter
  Scenario: Listing resources filtered by namespace returns only matching resources
    Given a clean in-memory database for repository coverage
    And a resource type and resource repository backed by the coverage database
    And a seeded resource type "bench/filter-type"
    And a resource "bench/res-a" of type "bench/filter-type"
    And a resource "other/res-b" of type "bench/filter-type"
    When resources are listed filtered by namespace "bench"
    Then the filtered resource list should contain 1 entry

  # ---- create OperationalError (lines 1997-1999) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource creation is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on flush
    When a resource is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create resource"

  # ---- create non-unique IntegrityError (lines 1990-1993) ----

  @resource_repo @transient_error
  Scenario: A non-unique integrity violation during resource creation is wrapped in DatabaseError
    Given a resource repository whose session raises a non-unique IntegrityError on flush
    When a resource is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create resource"

  # ---- get OperationalError (lines 2016-2017) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource get is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on query
    When a resource is retrieved and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get resource"

  # ---- get_by_name OperationalError (lines 2038-2039) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource get-by-name is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on query
    When a resource is retrieved by name and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get resource by name"

  # ---- list_resources OperationalError (lines 2076-2077) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource listing is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on query
    When resources are listed and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to list resources"

  # ---- update OperationalError (lines 2126-2128) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource update is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on query
    When a resource is updated and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to update resource"

  # ---- delete OperationalError (lines 2171-2173) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource deletion is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on query
    When a resource is deleted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to delete resource"

  # ---- resolve OperationalError (lines 2215-2216) ----

  @resource_repo @transient_error
  Scenario: A transient database failure during resource resolution is wrapped in DatabaseError
    Given a resource repository whose session raises OperationalError on query
    When a resource is resolved and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to resolve resource"

  # ==========================================================================
  # Resource Type Repository — equivalence_json and error branches
  # ==========================================================================

  # ---- _to_domain with equivalence_json (line 1877) ----

  @resource_type_repo @logic
  Scenario: A resource type with equivalence metadata is correctly round-tripped
    Given a clean in-memory database for repository coverage
    And a resource type and resource repository backed by the coverage database
    When a resource type with equivalence metadata is created and retrieved
    Then the retrieved resource type should have the equivalence data

  # ---- create OperationalError (lines 1665-1666) ----

  @resource_type_repo @transient_error
  Scenario: A transient database failure during resource type creation is wrapped in DatabaseError
    Given a resource type repository whose session raises OperationalError on flush
    When a resource type is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create resource type"

  # ---- create IntegrityError non-unique (lines 1660-1663) ----

  @resource_type_repo @transient_error
  Scenario: A non-unique integrity violation during resource type creation is wrapped in DatabaseError
    Given a resource type repository whose session raises a non-unique IntegrityError on flush
    When a resource type is created and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to create resource type"

  # ---- get OperationalError (lines 1681-1682) ----

  @resource_type_repo @transient_error
  Scenario: A transient database failure during resource type get is wrapped in DatabaseError
    Given a resource type repository whose session raises OperationalError on query
    When a resource type is retrieved and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to get resource type"

  # ---- list_types OperationalError (lines 1708-1709) ----

  @resource_type_repo @transient_error
  Scenario: A transient database failure during resource type listing is wrapped in DatabaseError
    Given a resource type repository whose session raises OperationalError on query
    When resource types are listed and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to list resource types"

  # ---- update OperationalError (lines 1795-1797) ----

  @resource_type_repo @transient_error
  Scenario: A transient database failure during resource type update is wrapped in DatabaseError
    Given a resource type repository whose session raises OperationalError on query
    When a resource type is updated and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to update resource type"

  # ---- delete OperationalError (lines 1835-1837) ----

  @resource_type_repo @transient_error
  Scenario: A transient database failure during resource type deletion is wrapped in DatabaseError
    Given a resource type repository whose session raises OperationalError on query
    When a resource type is deleted and a database error is expected
    Then a DatabaseError should be raised mentioning "Failed to delete resource type"
