Feature: AsyncWorker uncovered code paths
  As a developer
  I want full test coverage of async_worker.py edge cases
  So that race conditions, signal handling, and error recovery are verified

  # ---- cancel_job: InvalidJobTransitionError on queued job (lines 515-516) ----

  Scenario: cancel_job returns False when queued job transitions concurrently
    Given a coverage-boost async worker is initialised
    And a coverage-boost queued job exists
    And the queued job mark_cancelled is patched to raise InvalidJobTransitionError
    When I call cancel_job on the coverage-boost worker
    Then the cancel_job result should be False

  # ---- detect_stuck_jobs: InvalidJobTransitionError (lines 543-544) ----

  Scenario: detect_stuck_jobs ignores job whose mark_failed raises InvalidJobTransitionError
    Given a coverage-boost async worker with job_timeout 1
    And a coverage-boost running job with expired heartbeat exists
    And the stuck job mark_failed is patched to raise InvalidJobTransitionError
    When the coverage-boost worker detects stuck jobs
    Then the stuck jobs list should be empty

  # ---- _poll_loop: shutdown break during job dispatch (line 604) ----

  Scenario: Poll loop breaks out of dispatch when shutdown is requested mid-iteration
    Given a coverage-boost async worker is initialised
    And 5 coverage-boost queued jobs exist
    And the shutdown event is pre-set before dispatch
    When I run one poll loop iteration
    Then not all 5 queued jobs should have been dispatched

  # ---- _poll_loop: exception handler (lines 606-607) ----

  Scenario: Poll loop logs and continues when an exception occurs
    Given a coverage-boost async worker is initialised
    And the job store list_by_status is patched to raise RuntimeError
    When I run one poll loop iteration catching the exception
    Then the poll loop should have handled the exception gracefully

  # ---- _dispatch_job: fallback with no thread pool (lines 614-615) ----

  Scenario: _dispatch_job falls back to direct execution when thread pool is None
    Given a coverage-boost async worker is initialised
    And a coverage-boost queued job exists
    And the worker thread pool is None
    When I dispatch the job directly via _dispatch_job
    Then the coverage-boost job should be in a terminal state

  # ---- _dispatch_job: duplicate dispatch guard (line 618) ----

  Scenario: _dispatch_job skips job that is already in the futures dict
    Given a coverage-boost async worker is initialised with a started pool
    And a coverage-boost queued job exists
    And the job is already registered in the futures dict
    When I dispatch the job directly via _dispatch_job
    Then the futures dict should still contain exactly one entry for the job

  # ---- _signal_handler: direct invocation (lines 632-633) ----

  Scenario: Signal handler sets the shutdown event
    Given a coverage-boost async worker is initialised
    When I invoke the signal handler directly with SIGINT
    Then the worker shutdown event should be set

  # ---- _install_signal_handlers: OSError/ValueError from non-main thread (lines 642, 644) ----

  Scenario: Signal handler installation silently fails from non-main thread
    Given a coverage-boost async worker is initialised
    When I install signal handlers from a background thread
    Then no exception should be raised during signal installation

  # ---- _restore_signal_handlers: OSError/ValueError from non-main thread (lines 653-654) ----

  Scenario: Signal handler restoration silently fails from non-main thread
    Given a coverage-boost async worker is initialised
    And the worker has original signal handler references set
    When I restore signal handlers from a background thread
    Then no exception should be raised during signal restoration
