Feature: Async Resource Cleanup and Leak Prevention As a system operator I want async resources to be tracked and closed reliably So that the system does not leak connections, tasks, or subscriptions Background: Given I have an async resource tracker Scenario: Registering an async resource and closing it Given I have a mock async resource named "db-pool" When I register the resource with the tracker And I close all tracked resources Then the resource "db-pool" should be closed And the tracker should have zero open resources Scenario: close_all awaits registered resources with timeout Given I have 3 mock async resources with varied close times When I close all tracked resources with a 5 second timeout Then all 3 resources should be closed And the tracker should have zero open resources Scenario: Leaked resources are logged by name in finalizer Given I have a mock async resource named "leaky-conn" And I register the resource with the tracker When the tracker finalizer runs without close_all Then a warning should be logged mentioning "leaky-conn" Scenario: Graceful cancellation awaits in-flight tasks before cleanup Given I have an async task tracked by the bridge When I request graceful cleanup with a 2 second timeout Then the task should be cancelled And the bridge should have no active tasks Scenario: Time-bounded shutdown warns on forced termination Given I have a mock async resource named "slow-resource" that takes 5 seconds to close And I register the resource with the tracker When I close all tracked resources with a 0.1 second timeout Then a warning should be logged about forced termination And the tracker should report the timed-out resource Scenario: Cancelled async jobs persist cancellation reason Given I have an async task tracked by the bridge When I cancel the task with reason "user-requested-shutdown" Then the cancellation reason should be "user-requested-shutdown" Scenario: Checkpoint file handles are closed on cleanup Given I have a state manager with a temporary checkpoint directory When I save a checkpoint and then close the state manager Then the checkpoint file should exist and be readable And the state manager should be marked as closed Scenario: Subscriptions are disposed on cleanup Given I have an A2A event queue with 3 active subscriptions When I close the event queue Then all subscriptions should be removed And the subscription count should be zero Scenario: Tracker rejects duplicate resource names Given I have a mock async resource named "unique-res" And I register the resource with the tracker When I try to register another resource named "unique-res" Then a ValueError should be raised mentioning "unique-res" Scenario: Tracker rejects empty resource name When I try to register a resource with an empty name Then a ValueError should be raised mentioning "name" Scenario: Tracker rejects None resource When I try to register a None resource with name "valid-name" Then a ValueError should be raised mentioning "resource" Scenario: Tracker context manager closes resources on exit Given I have a mock async resource named "ctx-resource" When I use the tracker as an async context manager and register the resource Then the resource "ctx-resource" should be closed after exiting the context Scenario: close_all is idempotent Given I have a mock async resource named "once-resource" And I register the resource with the tracker When I close all tracked resources twice Then the resource "once-resource" should be closed exactly once And the tracker should have zero open resources Scenario: Enhanced bridge cleanup awaits tasks with timeout Given I have a bridge with 2 slow async tasks When I run enhanced cleanup with a 2 second timeout Then the bridge should have no active tasks And completed tasks should be logged Scenario: Registering a resource after close_all raises RuntimeError Given I have a mock async resource named "late-resource" And I register the resource with the tracker When I close all tracked resources And I try to register a resource named "post-close" after close_all Then a RuntimeError should be raised mentioning "closed" Scenario: State update after close raises RuntimeError Given I have a state manager with a temporary checkpoint directory When I close the state manager And I try to update state after close Then a RuntimeError should be raised mentioning "closed" Scenario: State reset after close raises RuntimeError Given I have a state manager with a temporary checkpoint directory When I close the state manager And I try to reset state after close Then a RuntimeError should be raised mentioning "closed" Scenario: Publish after close raises RuntimeError on A2aEventQueue Given I have an A2A event queue with 1 active subscriptions When I close the event queue And I try to publish an event after close Then a RuntimeError should be raised mentioning "closed" Scenario: A2aEventQueue exposes is_closed property Given I have an A2A event queue with 0 active subscriptions Then the event queue is_closed should be False When I close the event queue Then the event queue is_closed should be True