Feature: Context service coverage gap tests
  As a maintainer
  I want uncovered context_service branches exercised
  So that coverage gaps on context_service.py are closed

  # ---------- _load_agentsignore exception branch (lines 268-269) ----------

  @coverage
  Scenario: Gracefully handle unreadable .agentsignore files
    Given a coverage gap workspace
    And an unreadable .agentsignore file in the workspace
    When I load agentsignore patterns for the workspace directory
    Then the loaded patterns should be an empty list

  # ---------- _get_current_plan (lines 525-528) ----------

  @coverage
  Scenario: Return None from _get_current_plan when project has no id
    Given a coverage gap workspace
    When I call _get_current_plan with a project that has no id
    Then the coverage _get_current_plan result should be None

  @coverage
  Scenario: Return the current plan from _get_current_plan when project has an id
    Given a coverage gap workspace
    When I call _get_current_plan with the workspace project
    Then the coverage _get_current_plan result should match the workspace plan

  # ---------- _build_langsmith_config (lines 540-560) ----------

  @coverage
  Scenario: Build LangSmith config returns empty dict when tracing is disabled
    Given a coverage gap workspace
    When I build a LangSmith config with tracing disabled
    Then the LangSmith config result should be an empty dict

  @coverage
  Scenario: Build LangSmith config returns populated dict when tracing is enabled
    Given a coverage gap workspace with LangSmith tracing enabled
    When I build a LangSmith config with tracing enabled
    Then the LangSmith config result should contain project metadata
    And the LangSmith config result should contain a project tag

  # ---------- _prepare_analysis_config (lines 577-585) ----------

  @coverage
  Scenario: Prepare analysis config includes a unique thread_id
    Given a coverage gap workspace
    When I prepare an analysis config for the workspace project
    Then the analysis config should contain a configurable thread_id

  # ---------- _refresh_vector_index ConfigurationError (lines 595-598) ----------

  @coverage
  Scenario: Log warning when vector store refresh raises ConfigurationError
    Given a coverage gap workspace with a failing vector store
    When I trigger a vector index refresh for the workspace plan
    Then the refresh should complete without raising an exception

  # ---------- _get_context_agent (lines 624-626) ----------

  @coverage
  Scenario: Obtain a ContextAnalysisAgent instance from the service
    Given a coverage gap workspace
    When I request a context analysis agent from the coverage service
    Then the returned agent should be a ContextAnalysisAgent instance

  # ---------- analyze_context empty path (lines 656-670) ----------

  @coverage
  Scenario: Analyze context returns empty state when no files are loaded
    Given a coverage gap workspace with no context files
    When I run analyze_context on the workspace project
    Then the analysis documents should be empty
    And the analysis summary should say no files to analyze

  # ---------- analyze_context with files (lines 673-691) ----------

  @coverage
  Scenario: Analyze context processes loaded context files
    Given a coverage gap workspace with a context file "module.py"
    When I run analyze_context on the workspace project
    Then the analysis documents should not be empty

  # ---------- analyze_context_async empty path (lines 709-722) ----------

  @coverage
  Scenario: Async analyze context returns empty state when no files are loaded
    Given a coverage gap workspace with no context files
    When I run analyze_context_async on the workspace project
    Then the async analysis documents should be empty
    And the async analysis summary should say no files to analyze

  # ---------- analyze_context_async with files (lines 724-742) ----------

  @coverage
  Scenario: Async analyze context processes loaded context files
    Given a coverage gap workspace with a context file "module.py"
    When I run analyze_context_async on the workspace project
    Then the async analysis documents should not be empty

  # ---------- analyze_context_streaming empty path (lines 761-765) ----------

  @coverage
  Scenario: Streaming analysis yields complete event when no files are loaded
    Given a coverage gap workspace with no context files
    When I stream analyze_context on the workspace project
    Then the only streaming event should indicate no files to analyze

  # ---------- analyze_context_streaming with files (lines 767-787) ----------

  @coverage
  Scenario: Streaming analysis yields node events for loaded files
    Given a coverage gap workspace with a context file "module.py"
    When I stream analyze_context on the workspace project
    Then the streaming events should include workflow node results

  # ---------- analyze_context_streaming_async empty (lines 805-809) ----------

  @coverage
  Scenario: Async streaming analysis yields complete event when no files loaded
    Given a coverage gap workspace with no context files
    When I async stream analyze_context on the workspace project
    Then the only async streaming event should indicate no files to analyze

  # ---------- analyze_context_streaming_async with files (lines 811-832) ----------

  @coverage
  Scenario: Async streaming analysis yields events for loaded files
    Given a coverage gap workspace with a context file "module.py"
    When I async stream analyze_context on the workspace project
    Then the async streaming events should contain workflow results

  # ---------- get_context_summary (lines 851-852) ----------

  @coverage
  Scenario: Get context summary returns summary text
    Given a coverage gap workspace with a context file "module.py"
    When I get the context summary from the coverage service
    Then the summary should be a non-empty string from coverage service

  # ---------- get_context_dependencies (lines 871-872) ----------

  @coverage
  Scenario: Get context dependencies returns dependency mapping
    Given a coverage gap workspace with a context file "module.py"
    When I get the context dependencies from the coverage service
    Then the dependency result should be a dictionary

  # ---------- get_relevant_files (lines 892-898) ----------

  @coverage
  Scenario: Get relevant files returns scored file list
    Given a coverage gap workspace with a context file "module.py"
    When I get relevant files with threshold 0.0 from the coverage service
    Then the relevant files result should be a list of tuples

  # ---------- search_context full path (lines 910-944) ----------

  @coverage
  Scenario: Search context returns empty for blank query
    Given a coverage gap workspace with vector search enabled
    When I search the coverage context for "   "
    Then the coverage search results should be empty

  @coverage
  Scenario: Search context returns empty when project has no plan
    Given a coverage gap workspace with vector search enabled
    And the coverage workspace project has no id
    When I search the coverage context for "find something"
    Then the coverage search results should be empty

  @coverage
  Scenario: Search context returns empty when vector store is disabled
    Given a coverage gap workspace with vector search disabled
    When I search the coverage context for "find something"
    Then the coverage search results should be empty

  @coverage
  Scenario: Search context returns results from vector store
    Given a coverage gap workspace with vector search enabled
    And the vector store stub has results for the coverage workspace
    When I search the coverage context for "find something"
    Then the coverage search results should not be empty

  @coverage
  Scenario: Search context handles ConfigurationError from vector store search
    Given a coverage gap workspace with vector search enabled
    And the vector store search raises a ConfigurationError
    When I search the coverage context for "find something"
    Then the coverage search results should be empty
