Feature: Devcontainer Health Checking As a CleverAgents developer I want running devcontainers to be health-checked periodically So that unhealthy containers are detected and transitioned to failed state # ── Health check ─────────────────────────────────────────── Scenario: Health check failure transitions to error Given a mock devcontainer CLI runner And the runner configured for failed health check And an active container "01TESTLIFECYCLE0000000050" with container ID "ctr-hc" When I run a single health check probe for "01TESTLIFECYCLE0000000050" Then the container state for "01TESTLIFECYCLE0000000050" should be "failed" # ── start_health_check and health_check_loop coverage ────── Scenario: Health check loop success path runs and returns Given a mock devcontainer CLI runner And the runner configured for successful health check And an active container "01TESTLIFECYCLE0000000100" with container ID "ctr-hcbg" When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000100" Then the health check should have probed "01TESTLIFECYCLE0000000100" And the container state for "01TESTLIFECYCLE0000000100" should be "running" Scenario: Health check loop transitions to error on probe failure Given a mock devcontainer CLI runner And the runner configured for failed health check And an active container "01TESTLIFECYCLE0000000101" with container ID "ctr-hcf" When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000101" Then the container state for "01TESTLIFECYCLE0000000101" should be "failed" Scenario: Health check loop transitions to error on exception Given a mock devcontainer CLI runner And the runner configured to raise exception on exec And an active container "01TESTLIFECYCLE0000000102" with container ID "ctr-hce" When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000102" Then the container state for "01TESTLIFECYCLE0000000102" should be "failed" Scenario: start_health_check registers thread and stop event Given a mock devcontainer CLI runner And the runner configured for successful health check And an active container "01TESTLIFECYCLE0000000103" with container ID "ctr-reg" When I call start_health_check for "01TESTLIFECYCLE0000000103" Then a health check thread should be registered for "01TESTLIFECYCLE0000000103" Scenario: Stopping active container stops running health check Given a mock devcontainer CLI runner And the runner configured for successful health check And an active container "01TESTLIFECYCLE0000000104" with container ID "ctr-hcstop" And a registered health check for "01TESTLIFECYCLE0000000104" When I stop container "01TESTLIFECYCLE0000000104" Then the container state for "01TESTLIFECYCLE0000000104" should be "stopped" And the health check for "01TESTLIFECYCLE0000000104" should be unregistered Scenario: Health check exits when container is no longer active Given a mock devcontainer CLI runner And the runner configured for successful health check And a stopped container "01TESTLIFECYCLE0000000105" When I run one iteration of the health check loop for "01TESTLIFECYCLE0000000105" Then the container state for "01TESTLIFECYCLE0000000105" should be "stopped" Scenario: start_health_check rejects empty resource_id When I attempt to start health check with empty resource_id Then the health check should raise ValueError # ── T2: Concurrent activation rejects second caller ──────── Scenario: Concurrent activation of the same container is rejected Given a mock devcontainer CLI runner And the runner configured for successful activation And a lifecycle tracker for resource "01TESTLIFECYCLE0000000310" When I activate the container concurrently from two threads Then exactly one activation should succeed And exactly one activation should fail with ValueError # ── T3: _single_probe uses /workspace fallback ───────────── Scenario: Single probe falls back to /workspace when workspace_path is None Given a mock devcontainer CLI runner And an active container "01TESTLIFECYCLE0000000320" with container ID "ctr-t3" When I run a single probe with no workspace_path set Then the probe command should use "/workspace" as workspace folder # ── T4: Health check thread join timeout ─────────────────── Scenario: Stopping health check joins thread with timeout Given a mock devcontainer CLI runner And an active container "01TESTLIFECYCLE0000000330" with container ID "ctr-t4" And a running health check for "01TESTLIFECYCLE0000000330" When I stop the health check for "01TESTLIFECYCLE0000000330" Then the health check thread should have been joined # ── F7: Concurrent stop_container ────────────────────────── Scenario: Concurrent stop of the same container is handled safely Given a mock devcontainer CLI runner And an active container "01TESTLIFECYCLE0000000390" with container ID "ctr-cs" When I stop the container concurrently from two threads Then both stops should succeed And the container state for "01TESTLIFECYCLE0000000390" should be "stopped" And exactly 1 docker stop call should have been made # ── R7-F3: Auto health check on activation ───────────────── Scenario: Activation automatically starts health check Given a mock devcontainer CLI runner And the runner configured for successful activation When I activate container "01TESTLIFECYCLE0000000620" at "/workspace/project" Then the container state should be "running" And a health check thread should be registered for "01TESTLIFECYCLE0000000620" # ── F16: resolve() triggers lazy activation ───────────────── Scenario: DevcontainerHandler.resolve triggers lazy activation for detected resource Given a mock devcontainer CLI runner And the runner configured for successful activation And a lifecycle tracker for resource "01TESTLIFECYCLE0000000820" When I resolve a devcontainer-instance "01TESTLIFECYCLE0000000820" at "/workspace/project" Then the container state for "01TESTLIFECYCLE0000000820" should be "running" Scenario: DevcontainerHandler.resolve skips activation for running resource Given a mock devcontainer CLI runner And an active container "01TESTLIFECYCLE0000000821" with container ID "ctr-resolve" When I resolve a devcontainer-instance "01TESTLIFECYCLE0000000821" at "/workspace/project" Then the container state for "01TESTLIFECYCLE0000000821" should be "running" And the runner should not have received a devcontainer up call