Feature: Devcontainer Lifecycle State Model As a CleverAgents developer I want the container lifecycle state model to enforce valid transitions So that containers follow a predictable state machine # ── Lifecycle state model ────────────────────────────────── Scenario: ContainerLifecycleState has all required values When I inspect ContainerLifecycleState enum values Then the lifecycle enum should contain "discovered" And the lifecycle enum should contain "building" And the lifecycle enum should contain "running" And the lifecycle enum should contain "stopping" And the lifecycle enum should contain "stopped" And the lifecycle enum should contain "failed" Scenario: Valid transitions are accepted Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000001" When I transition from "discovered" to "building" Then the transition should succeed And the tracker state should be "building" Scenario: Active transition after starting Given a lifecycle tracker in "building" state for resource "01TESTLIFECYCLE0000000002" When I transition from "building" to "running" Then the transition should succeed And the tracker state should be "running" Scenario: Invalid transition is rejected Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000003" When I attempt to transition from "discovered" to "running" Then the transition should raise ValueError Scenario: Stopping to error transition is valid Given a lifecycle tracker in "stopping" state for resource "01TESTLIFECYCLE0000000004" When I transition from "stopping" to "failed" Then the transition should succeed And the tracker state should be "failed" Scenario: Error to starting transition is valid for retry Given a lifecycle tracker in "failed" state for resource "01TESTLIFECYCLE0000000005" When I transition from "failed" to "building" Then the transition should succeed And the tracker state should be "building" Scenario: Stopped to starting transition is valid for rebuild Given a lifecycle tracker in "stopped" state for resource "01TESTLIFECYCLE0000000006" When I transition from "stopped" to "building" Then the transition should succeed Scenario: Transition history is recorded Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000007" When I transition from "discovered" to "building" Then the tracker should have 1 transition in history # ── Lifecycle registry ───────────────────────────────────── Scenario: Lifecycle tracker persists state across calls Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000060" When I transition from "discovered" to "building" And I retrieve the tracker for "01TESTLIFECYCLE0000000060" Then the retrieved tracker state should be "building" Scenario: List active containers returns only active ones Given a mock devcontainer CLI runner And the runner configured for successful activation And an active container "01TESTLIFECYCLE0000000070" with container ID "ctr-x" And a lifecycle tracker for resource "01TESTLIFECYCLE0000000071" When I list active containers Then the active list should contain "01TESTLIFECYCLE0000000070" And the active list should not contain "01TESTLIFECYCLE0000000071" # ── JSON output parsing ──────────────────────────────────── Scenario: Parse valid devcontainer up JSON output When I parse devcontainer up output with containerId "abcdef123456" and workspace "/ws" Then the parsed container ID should be "abcdef123456" And the parsed workspace path should be "/ws" Scenario: Parse invalid devcontainer up JSON output gracefully When I parse devcontainer up output with invalid JSON Then the parsed container ID should be None And the parsed workspace path should be None # ── Argument validation ──────────────────────────────────── Scenario: validate_transition rejects wrong types When I call validate_transition with non-enum arguments Then it should raise TypeError Scenario: validate_transition rejects wrong to_state type When I call validate_transition with non-enum to_state Then it should raise TypeError Scenario: transition_state rejects wrong tracker type When I call transition_state with non-tracker argument Then it should raise TypeError Scenario: transition_state rejects wrong to_state type When I call transition_state with non-enum to_state argument Then it should raise TypeError # ── Registry edge cases ──────────────────────────────────── Scenario: get_lifecycle_tracker rejects empty resource_id When I attempt to get tracker with empty resource_id Then the get tracker should raise ValueError Scenario: set_lifecycle_tracker rejects wrong type When I attempt to set tracker with wrong type Then the set tracker should raise TypeError # ── R13: Additional invalid transition coverage ──────────── Scenario: Invalid transition running to building is rejected Given a lifecycle tracker in "running" state for resource "01TESTLIFECYCLE0000000240" When I attempt to transition from "running" to "building" Then the transition should raise ValueError Scenario: Invalid transition stopped to running is rejected Given a lifecycle tracker in "stopped" state for resource "01TESTLIFECYCLE0000000241" When I attempt to transition from "stopped" to "running" Then the transition should raise ValueError Scenario: Invalid transition building to stopped is rejected Given a lifecycle tracker in "building" state for resource "01TESTLIFECYCLE0000000242" When I attempt to transition from "building" to "stopped" Then the transition should raise ValueError Scenario: Invalid transition failed to running is rejected Given a lifecycle tracker in "failed" state for resource "01TESTLIFECYCLE0000000243" When I attempt to transition from "failed" to "running" Then the transition should raise ValueError Scenario: Invalid transition discovered to stopping is rejected Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000244" When I attempt to transition from "discovered" to "stopping" Then the transition should raise ValueError Scenario: Invalid transition building to discovered is rejected Given a lifecycle tracker in "building" state for resource "01TESTLIFECYCLE0000000245" When I attempt to transition from "building" to "discovered" Then the transition should raise ValueError # ── R4: Multi-line JSON output parsing ───────────────────── Scenario: Parse devcontainer up output with log lines before JSON When I parse devcontainer up output with log lines before JSON Then the parsed container ID should be "aabbccddee0099887766" And the parsed workspace path should be "/workspaces/multi" # ── T1: Transition history cap at 100 ────────────────────── Scenario: Transition history is capped at 100 entries Given a lifecycle tracker for resource "01TESTLIFECYCLE0000000300" When I perform 105 transitions cycling through valid states Then the tracker should have at most 100 transitions # ── S1: Container ID format validation ───────────────────── Scenario: Invalid container ID format is rejected during parsing When I parse devcontainer up output with invalid container ID "not-a-hex-id!" Then the parsed container ID should be empty # ── F11: Invalid workspace path rejected during parsing ──── Scenario: Parse devcontainer up output with relative workspace path When I parse devcontainer up output with relative workspace "relative/ws" Then the parsed container ID should be "aabbccddee0011223344" And the parsed workspace path should be None # ── R7-F8: Terminal tracker eviction ──────────────────────── Scenario: Terminal tracker eviction removes oldest stopped trackers Given 210 stopped container trackers in the registry When I run terminal tracker eviction Then the registry should have at most 200 terminal trackers # ── TEST-3: Coverage gap scenarios ────────────────────────── Scenario: evict_terminal_trackers returns 0 when below threshold Given 50 stopped container trackers in the registry When I run terminal tracker eviction Then the eviction count should be 0 Scenario: get_lifecycle_tracker auto-creates tracker for new resource When I get tracker for new resource "01TESTLIFECYCLE0000000730" Then the auto-created tracker state should be "discovered" And the auto-created tracker resource_id should be "01TESTLIFECYCLE0000000730" Scenario: clear_lifecycle_registry stops health check threads Given a mock devcontainer CLI runner And the runner configured for successful health check And an active container "01TESTLIFECYCLE0000000740" with container ID "ctr-clr" And a running health check for "01TESTLIFECYCLE0000000740" When I clear the lifecycle registry Then the registry should be empty And the health check for "01TESTLIFECYCLE0000000740" should be unregistered