From b6bb9c51133ef4e910efe109e2d49fc26478ca89 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Mon, 13 Apr 2026 21:48:08 +0000 Subject: [PATCH] fix(resource): align DETECTED->DISCOVERED rename and remove build artifacts - Remove committed build artifacts (test_reports/summary.txt, test_reports/test_results.json) and add test_reports/ to .gitignore - Fix CLI resource.py: update lifecycle state condition and warning banner from 'detected (not built)' to 'discovered (not built)' and 'Devcontainer detected' to 'Devcontainer discovered' to align with ContainerLifecycleState.DISCOVERED rename - Fix BDD feature file: update resource_list_lifecycle_state.feature scenario title and assertion from 'Devcontainer detected' to 'Devcontainer discovered' - Fix robot/helper_devcontainer_lifecycle.py: update enum value check from 'detected' to 'discovered' in cmd_enum_values() - Fix robot/helper_devcontainer_handler.py: update strategy check assertion from 'none' to 'snapshot' to match PR #8304 change - Update CONTRIBUTORS.md with HAL 9000 feature contribution entry Closes #7555 (via PR #8304) Fixes: CI unit_tests and integration_tests failures from PR #8304 --- CONTRIBUTORS.md | 1 + .../resource_list_lifecycle_state.feature | 6 +- robot/helper_devcontainer_handler.py | 7 +- robot/helper_devcontainer_lifecycle.py | 2 +- src/cleveragents/cli/commands/resource.py | 6 +- test_reports/summary.txt | 674 ------ test_reports/test_results.json | 2054 ----------------- 7 files changed, 11 insertions(+), 2739 deletions(-) delete mode 100644 test_reports/summary.txt delete mode 100644 test_reports/test_results.json diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index af51c30bc..637b143fd 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -63,3 +63,4 @@ Below are some of the specific details of various contributions. * HAL 9000 has contributed the alembic fileConfig error handling fix (PR #8288 / issue #7874): wrapped the `fileConfig()` call in `alembic/env.py` with a `try/except` block to catch malformed INI logging configuration and emit clear, actionable error messages to stderr. * HAL 9000 has contributed the Definition-of-Done gating feature for the Apply phase (PR #8299 / issue #7927): `PlanLifecycleService.apply_plan` now evaluates DoD criteria before transitioning to Apply, raising `DoDGatingError` when required criteria fail and storing evaluation results in `plan.validation_summary`. * HAL 9000 has contributed the engine cache TOCTOU race condition fix (PR #8265 / issue #7566): added `MEMORY_ENGINES_LOCK` to `engine_cache.py` and wrapped the check-and-set operation in `UnitOfWork.engine` with `with MEMORY_ENGINES_LOCK:` to prevent concurrent threads from creating duplicate in-memory SQLite engine instances; also fixed a cache-hit bug where `self._engine` was never assigned on a cache hit. +* HAL 9000 has contributed the `--clone-into` CLI argument for `container-instance`, the `CloneIntoHandler` module, the `devcontainer-instance` snapshot sandbox strategy, and the `ContainerLifecycleState.DISCOVERED` terminology alignment (PR #8304, issue #7555). diff --git a/features/resource_list_lifecycle_state.feature b/features/resource_list_lifecycle_state.feature index 95ca48550..e8ffdf7c6 100644 --- a/features/resource_list_lifecycle_state.feature +++ b/features/resource_list_lifecycle_state.feature @@ -43,16 +43,16 @@ Feature: agents resource list shows devcontainer lifecycle state column Then the resource output should contain "local/my-repo" And the resource output should contain "git-checkout" - Scenario: resource list shows warning banner when devcontainer is in detected state + Scenario: resource list shows warning banner when devcontainer is in discovered state Given a devcontainer-instance resource is registered When I run resource list with all flag - Then the resource output should contain "Devcontainer detected" + Then the resource output should contain "Devcontainer discovered" Scenario: resource list does not show warning banner when devcontainer is running Given a devcontainer-instance resource is registered And the devcontainer lifecycle state is "running" When I run resource list with all flag - Then the resource output should not contain "Devcontainer detected" + Then the resource output should not contain "Devcontainer discovered" @tdd_issue @tdd_issue_4263 @tdd_expected_fail Scenario: resource list JSON output includes lifecycle_state for devcontainer-instance diff --git a/robot/helper_devcontainer_handler.py b/robot/helper_devcontainer_handler.py index 7492d62cf..db79c3a52 100644 --- a/robot/helper_devcontainer_handler.py +++ b/robot/helper_devcontainer_handler.py @@ -75,12 +75,11 @@ def cmd_protocol_check() -> None: def cmd_strategy_check() -> None: """Verify DevcontainerHandler default strategy. - F22/F25 fix: handler uses ``none`` because SandboxFactory has not yet - implemented ``snapshot``. The container itself provides isolation. - Known limitation — will switch to ``snapshot`` once implemented. + PR #8304 fix: handler now uses ``snapshot`` strategy for safe plan + execution inside containers (ADR-043 devcontainer integration). """ handler = DevcontainerHandler() - assert handler._default_strategy.value == "none" + assert handler._default_strategy.value == "snapshot" print("strategy-check-ok") diff --git a/robot/helper_devcontainer_lifecycle.py b/robot/helper_devcontainer_lifecycle.py index 604bab7d6..8922be874 100644 --- a/robot/helper_devcontainer_lifecycle.py +++ b/robot/helper_devcontainer_lifecycle.py @@ -104,7 +104,7 @@ class _MockRunner: def cmd_enum_values() -> None: """Verify all six lifecycle states exist.""" - expected = {"detected", "building", "running", "stopping", "stopped", "failed"} + expected = {"discovered", "building", "running", "stopping", "stopped", "failed"} actual = {s.value for s in ContainerLifecycleState} assert actual == expected, f"Expected {expected}, got {actual}" print("enum-values-ok") diff --git a/src/cleveragents/cli/commands/resource.py b/src/cleveragents/cli/commands/resource.py index bb85d3942..bc4d6a754 100644 --- a/src/cleveragents/cli/commands/resource.py +++ b/src/cleveragents/cli/commands/resource.py @@ -159,7 +159,7 @@ def _get_lifecycle_state_str(resource: Any) -> str | None: resource: A Resource domain object. Returns: - Lifecycle state string (e.g. ``"detected (not built)"``, ``"running"``) + Lifecycle state string (e.g. ``"discovered (not built)"``, ``"running"``) or ``None`` if the resource type has no lifecycle state. """ if resource.resource_type_name not in _CONTAINER_TYPES: @@ -897,7 +897,7 @@ def resource_list( if len(res_id) > 12: res_id = res_id[:12] + "..." lifecycle_state = _get_lifecycle_state_str(res) - if lifecycle_state == "detected (not built)": + if lifecycle_state == "discovered (not built)": detected_devcontainers.append(res) if lifecycle_state: lifecycle_states.append((res, lifecycle_state)) @@ -921,7 +921,7 @@ def resource_list( location = res.location or "(unknown path)" devcontainer_json = f"{location}/.devcontainer/devcontainer.json" console.print( - f"[yellow]⚠ Devcontainer detected at {devcontainer_json}[/yellow]" + f"[yellow]⚠ Devcontainer discovered at {devcontainer_json}[/yellow]" ) console.print(" Container will be built lazily on first access.") console.print( diff --git a/test_reports/summary.txt b/test_reports/summary.txt deleted file mode 100644 index f0a0e18c7..000000000 --- a/test_reports/summary.txt +++ /dev/null @@ -1,674 +0,0 @@ -Test Framework: generic -Total Tests: 155 -Passed: 107 -Failed: 48 - ---- Test Results --- -✓ Output Block 1 -✓ Output Block 2 -✓ Output Block 3 -✓ Output Block 4 -✓ Output Block 5 -✓ Output Block 6 -✓ Output Block 7 -✓ Output Block 8 -✓ Output Block 9 -✓ Output Block 10 -✗ Output Block 11 -✓ Output Block 12 -✓ Output Block 13 -✗ Output Block 14 -✗ Output Block 15 -✗ Output Block 16 -✓ Output Block 17 -✓ Output Block 18 -✓ Output Block 19 -✓ Output Block 20 -✓ Output Block 21 -✓ Output Block 22 -✗ Output Block 23 -✗ Output Block 24 -✗ Output Block 25 -✗ Output Block 26 -✓ Output Block 27 -✗ Output Block 28 -✗ Output Block 29 -✗ Output Block 30 -✗ Output Block 31 -✗ Output Block 32 -✗ Output Block 33 -✗ Output Block 34 -✗ Output Block 35 -✓ Output Block 36 -✓ Output Block 37 -✓ Output Block 38 -✓ Output Block 39 -✓ Output Block 40 -✓ Output Block 41 -✓ Output Block 42 -✓ Output Block 43 -✓ Output Block 44 -✗ Output Block 45 -✓ Output Block 46 -✓ Output Block 47 -✗ Output Block 48 -✓ Output Block 49 -✓ Output Block 50 -✗ FAIL: Output Block 51 -✓ Output Block 52 -✗ Output Block 53 -✗ FAIL: Output Block 54 -✓ Output Block 55 -✓ Output Block 56 -✗ Output Block 57 -✗ Output Block 58 -✓ Output Block 59 -✓ Output Block 60 -✗ Output Block 61 -✗ Output Block 62 -✓ Output Block 63 -✓ Output Block 64 -✓ Output Block 65 -✓ Output Block 66 -✓ Output Block 67 -✓ Output Block 68 -✓ Output Block 69 -✓ Output Block 70 -✓ Output Block 71 -✓ Output Block 72 -✓ Output Block 73 -✓ Output Block 74 -✓ Output Block 75 -✓ Output Block 76 -✓ Output Block 77 -✓ Output Block 78 -✓ Output Block 79 -✓ Output Block 80 -✓ Output Block 81 -✓ Output Block 82 -✗ Output Block 83 -✓ Output Block 84 -✓ Output Block 85 -✗ Output Block 86 -✓ Output Block 87 -✗ Output Block 88 -✓ Output Block 89 -✓ Output Block 90 -✓ Output Block 91 -✓ Output Block 92 -✗ Output Block 93 -✗ Output Block 94 -✓ Output Block 95 -✓ Output Block 96 -✓ Output Block 97 -✓ Output Block 98 -✗ Output Block 99 -✓ Output Block 100 -✓ Output Block 101 -✓ Output Block 102 -✓ Output Block 103 -✗ Output Block 104 -✓ Output Block 105 -✓ Output Block 106 -✗ Output Block 107 -✓ Output Block 108 -✓ Output Block 109 -✗ Output Block 110 -✓ Output Block 111 -✗ Output Block 112 -✓ Output Block 113 -✗ Output Block 114 -✓ Output Block 115 -✗ Output Block 116 -✓ Output Block 117 -✓ Output Block 118 -✓ Output Block 119 -✓ Output Block 120 -✓ Output Block 121 -✓ Output Block 122 -✗ Output Block 123 -✓ Output Block 124 -✓ Output Block 125 -✓ Output Block 126 -✓ Output Block 127 -✓ Output Block 128 -✓ Output Block 129 -✓ Output Block 130 -✗ Output Block 131 -✗ Output Block 132 -✓ Output Block 133 -✓ Output Block 134 -✓ Output Block 135 -✓ Output Block 136 -✓ Output Block 137 -✓ Output Block 138 -✓ Output Block 139 -✓ Output Block 140 -✗ Output Block 141 -✗ Output Block 142 -✗ Output Block 143 -✗ Output Block 144 -✓ Output Block 145 -✓ Output Block 146 -✓ Output Block 147 -✓ Output Block 148 -✓ Output Block 149 -✓ Output Block 150 -✓ Output Block 151 -✗ Output Block 152 -✗ Output Block 153 -✗ nox > Running session unit_tests-3.13 -✗ Error Output - ---- Failed Tests --- -✗ Output Block 11 - 1 feature passed, 0 failed, 0 skipped - 10 scenarios passed, 0 failed, 0 skipped - 23 steps passed, 0 failed, 0 skipped - Took 0min 0.006s - 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 - 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" - -✗ Output Block 14 - 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 - -✗ Output Block 15 - 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" - -✗ Output Block 16 - 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" - -✗ Output Block 23 - Scenario: validate_transition rejects wrong types - When I call validate_transition with non-enum arguments - Then it should raise TypeError - -✗ Output Block 24 - Scenario: validate_transition rejects wrong to_state type - When I call validate_transition with non-enum to_state - Then it should raise TypeError - -✗ Output Block 25 - Scenario: transition_state rejects wrong tracker type - When I call transition_state with non-tracker argument - Then it should raise TypeError - -✗ Output Block 26 - Scenario: transition_state rejects wrong to_state type - When I call transition_state with non-enum to_state argument - Then it should raise TypeError - Feature: agents resource list shows devcontainer lifecycle state column - As a CleverAgents user - I want the resource list to show the lifecycle state for devcontainer-instance resources - So that I can see whether a devcontainer is discovered, running, stopped, or failed - Feature: agents resource list shows devcontainer lifecycle state column - -✗ Output Block 28 - 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 - -✗ Output Block 29 - Scenario: set_lifecycle_tracker rejects wrong type - When I attempt to set tracker with wrong type - Then the set tracker should raise TypeError - -✗ Output Block 30 - 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 - -✗ Output Block 31 - 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 - -✗ Output Block 32 - 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 - -✗ Output Block 33 - 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 - -✗ Output Block 34 - 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 - -✗ Output Block 35 - 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 - -✗ Output Block 45 - 1 feature passed, 0 failed, 0 skipped - 32 scenarios passed, 0 failed, 0 skipped - 106 steps passed, 0 failed, 0 skipped - Took 0min 0.037s - And built-in types are bootstrapped - Given a devcontainer-instance resource is registered - When I run resource list with all flag - Then the resource output should contain "discovered (not built)" - -✗ Output Block 48 - Scenario: resource list shows "failed" state for a failed devcontainer - Given a fresh in-memory resource registry - And built-in types are bootstrapped - Given a devcontainer-instance resource is registered - And the devcontainer lifecycle state is "failed" - When I run resource list with all flag - Then the resource output should contain "failed" - -✗ FAIL: Output Block 51 - ASSERT FAILED: Expected 'Devcontainer detected' in output, got: - Resources (1 total) - ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓ - ┃ ID ┃ Name ┃ Type ┃ Status ┃ Kind ┃ Location ┃ Description ┃ - ┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩ - │ 01KP2TDV4GAR... │ (unnamed) │ devcontainer-instance │ discovered (not built) │ physical │ /tmp/test-project │ Test devcontainer │ - └─────────────────┴───────────┴───────────────────────┴────────────────────────┴──────────┴───────────────────┴───────────────────┘ - -✗ Output Block 53 - @tdd_issue @tdd_issue_4263 @tdd_expected_fail - Scenario: resource list JSON output includes lifecycle_state for devcontainer-instance - Given a fresh in-memory resource registry - And built-in types are bootstrapped - Given a devcontainer-instance resource is registered - When I run resource list with all flag and format "json" - Then the resource output should be valid JSON - And the resource JSON output should contain key "lifecycle_state" - -✗ FAIL: Output Block 54 - ASSERT FAILED: Key 'lifecycle_state' not found in JSON output - -✗ Output Block 57 - Scenario: resource list succeeds gracefully when lifecycle tracker raises an error - Given a fresh in-memory resource registry - And built-in types are bootstrapped - Feature: Devcontainer Resource Handler - As a CleverAgents developer - I want devcontainer resources to be auto-discovered and manually registered - So that devcontainer environments integrate into the resource model Given a devcontainer-instance resource is registered - -✗ Output Block 58 - Scenario: Register devcontainer-instance manually - Given a temporary directory with a valid devcontainer.json - When I create a devcontainer-instance resource at that path - Then And the resource should have type "the lifecycle tracker raises an error for the resourcedevcontainer-instance" - -✗ Output Block 61 - - Failing scenarios: - features/resource_list_lifecycle_state.feature:44 resource list shows warning banner when devcontainer is in detected state - -✗ Output Block 62 - 0 features passed, 1 failed, 0 skipped - 11 scenarios passed, 1 failed, 0 skipped - 69 steps passed, 1 failed, 0 skipped - Took 0min 1.827s - -✗ Output Block 83 - Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.1 - When I validate clone-into URL "not-a-url" - Then it should raise a ValueError - Then the clone-into URL should be invalid - -✗ Output Block 86 - Scenario: clone_repo_into_container rejects empty container_id - When I call clone_repo_into_container with empty container_id - Then it should raise ValueError mentioning "container_id" - -✗ Output Block 88 - Scenario: clone_repo_into_container rejects empty repo_url - When I call clone_repo_into_container with empty repo_url - And the directory has a named devcontainer configuration "frontend" - Then it should raise ValueError mentioning "repo_url" - When I run devcontainer discovery on the directory as "git-checkout" - Then discovery should return 2 results - And the result config names should include "api" - -✗ Output Block 93 - Scenario: clone_repo_into_container raises CloneIntoError when docker exec fails - Given a mock docker exec that fails for clone with stderr "fatal: repository not found" - When I clone "https://github.com/org/missing.git" into container "abc123def456" - When I run devcontainer discovery on the directory as "git-checkout" - Then the clone should raise CloneIntoError - And the CloneIntoError should mention "repository not found" - Then discovery should return 1 result - And the first result should have no config name - -✗ Output Block 94 - Scenario: CloneIntoError stores repo_url, container_id, and stderr - Given a CloneIntoError with repo "https://example.com/repo.git" container "ctr-001" stderr "auth failed" - Then the CloneIntoError repo_url should be "https://example.com/repo.git" - And the CloneIntoError container_id should be "ctr-001" - And the CloneIntoError stderr should be "auth failed" - -✗ Output Block 99 - 1 feature passed, 0 failed, 0 skipped - 17 scenarios passed, 0 failed, 0 skipped - 44 steps passed, 0 failed, 0 skipped - Took 0min 0.008s - Then discovery should return 0 results - -✗ Output Block 104 - 1 feature passed, 0 failed, 0 skipped - 26 scenarios passed, 0 failed, 0 skipped - 90 steps passed, 0 failed, 0 skipped - Took 0min 0.026s - Feature: Devcontainer Session Cleanup and CLI Commands - As a CleverAgents developer - I want session-scoped container cleanup and CLI stop/rebuild commands - So that containers are cleaned up when sessions end and can be managed via CLI - Scenario: Active containers stopped on session cleanup - Given a mock devcontainer CLI runner - And an active container "01TESTLIFECYCLE0000000040" with container ID "ctr-a" - And an active container "01TESTLIFECYCLE0000000041" with container ID "ctr-b" - When I run session cleanup for session "session-001" - Then the container state for "01TESTLIFECYCLE0000000040" should be "stopped" - And the container state for "01TESTLIFECYCLE0000000041" should be "stopped" - -✗ Output Block 107 - Scenario: Session cleanup handles stop failure gracefully - Given a mock devcontainer CLI runner - And the runner configured to raise exception on stop - And an active container "01TESTLIFECYCLE0000000130" with container ID "ctr-fail" - When I run session cleanup for session "session-err" - Then the cleanup should return 0 stopped containers - -✗ Output Block 110 - Scenario: dcproto delete fails when container is stopped - Given dcproto a devcontainer handler - And dcproto a devcontainer-instance resource with location "/ws/project" - And dcproto subprocess returns failed rm output with stderr "container not running" - When dcproto I delete path "file.txt" from the resource - Then the CLI exit code should be 0 - And the CLI output should contain "Stopped" - Then dcproto the delete should fail - And dcproto the delete failure message should contain "container not running" - -✗ Output Block 112 - Scenario: dcproto delete from resource with no location raises ValueError - Given dcproto a devcontainer handler - And dcproto a devcontainer-instance resource with no location - When dcproto I delete path "any/file.txt" from the resource - Then dcproto the delete should raise ValueError containing "no location" - -✗ Output Block 114 - Scenario: dcproto list_children returns empty list when container is stopped - Given dcproto a devcontainer handler - And dcproto a devcontainer-instance resource with location "/ws/project" - And dcproto subprocess returns failed ls output - When dcproto I list children of the resource - Then dcproto the children list should have 0 entries - -✗ Output Block 116 - Scenario: dcproto list_children from resource with no location raises ValueError - Given dcproto a devcontainer handler - And dcproto a devcontainer-instance resource with no location - When dcproto I list children of the resource - Then dcproto the list children should raise ValueError containing "no location" - -✗ Output Block 123 - Scenario: dcproto diff from resource with no location raises ValueError - Given dcproto a devcontainer handler - And dcproto a devcontainer-instance resource with no location - When dcproto I diff the resource against "/some/path" - Then the devcontainer CLI exit code should be non-zero - Then dcproto the diff should raise ValueError containing "no location" - And the CLI output should contain "no location" - -✗ Output Block 131 - Scenario: dcproto create_sandbox raises ValueError for resource with no location - Given dcproto a devcontainer handler - And dcproto a devcontainer-instance resource with no location - And dcproto a mock sandbox manager that returns a valid sandbox - When dcproto I create a sandbox for the resource with plan "plan-004" - Then dcproto the create_sandbox should raise ValueError containing "no location" - -✗ Output Block 132 - 1 feature passed, 0 failed, 0 skipped - 18 scenarios passed, 0 failed, 0 skipped - 102 steps passed, 0 failed, 0 skipped - Took 0min 0.028s - Then the CLI exit code should be 0 - And the CLI rebuild mock should have been called with "01TESTLIFECYCLE0000000221" and "/workspace/project" - -✗ Output Block 141 - Scenario: CLI stop handles NotFoundError from show_resource - Given a mock resource service that raises NotFoundError for "local/missing" - When I invoke CLI resource stop "local/missing" - Then the devcontainer CLI exit code should be non-zero - And the CLI output should contain "Resource not found" - -✗ Output Block 142 - Scenario: CLI rebuild handles NotFoundError from show_resource - Given a mock resource service that raises NotFoundError for "local/missing-rb" - When I invoke CLI resource rebuild "local/missing-rb" - Then the devcontainer CLI exit code should be non-zero - And the CLI output should contain "Resource not found" - -✗ Output Block 143 - Scenario: CLI stop handles RuntimeError from stop_container - Given a mock resource service with devcontainer "local/dc-rterr" id "01TESTLIFECYCLE0000000500" at "/workspace/project" - And an active container "01TESTLIFECYCLE0000000500" with container ID "ctr-rterr" - And CLI stop_container mock that raises RuntimeError - When I invoke CLI resource stop with error mock "local/dc-rterr" - Then the devcontainer CLI exit code should be non-zero - And the CLI output should contain "Stop failed" - -✗ Output Block 144 - Scenario: CLI rebuild handles RuntimeError from rebuild_container - Given a mock resource service with devcontainer "local/dc-rberr" id "01TESTLIFECYCLE0000000501" at "/workspace/project" - And a stopped container "01TESTLIFECYCLE0000000501" - And CLI rebuild_container mock that raises RuntimeError - When I invoke CLI resource rebuild with error mock "local/dc-rberr" - Then the devcontainer CLI exit code should be non-zero - And the CLI output should contain "Rebuild failed" - -✗ Output Block 152 - 1 feature passed, 0 failed, 0 skipped - 30 scenarios passed, 0 failed, 0 skipped - 143 steps passed, 0 failed, 0 skipped - Took 0min 0.436s - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - 2026-04-13 07:00:42 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:42 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - Including unscoped container 01TESTLIFECYCLE0000000040 in session 'session-001' cleanup (container has no session_id set) - Including unscoped container 01TESTLIFECYCLE0000000041 in session 'session-001' cleanup (container has no session_id set) - Container 01TESTLIFECYCLE0000000040: running -> stopping (manual stop) - Container 01TESTLIFECYCLE0000000040: stopping -> stopped (container stopped) - Stopped container 01TESTLIFECYCLE0000000040 (session=session-001) - Container 01TESTLIFECYCLE0000000041: running -> stopping (manual stop) - Container 01TESTLIFECYCLE0000000041: stopping -> stopped (container stopped) - Stopped container 01TESTLIFECYCLE0000000041 (session=session-001) - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - Registered built-in resource type: fs-mount - Registered built-in resource type: git-checkout - Registered built-in resource type: fs-directory - Registered built-in resource type: container-instance - Registered built-in resource type: devcontainer-instance - Registered built-in resource type: devcontainer-file - Registered built-in resource type: git - Registered built-in resource type: git-remote - Registered built-in resource type: git-branch - Registered built-in resource type: git-tag - Registered built-in resource type: git-commit - Registered built-in resource type: git-tree - Registered built-in resource type: git-tree-entry - Registered built-in resource type: git-stash - Registered built-in resource type: git-submodule - Registered built-in resource type: fs-symlink - Registered built-in resource type: fs-hardlink - Registered built-in resource type: cloud-account - Registered built-in resource type: cloud-region - Registered built-in resource type: cloud-network - Registered built-in resource type: cloud-subnet - Registered built-in resource type: cloud-security-group - Registered built-in resource type: cloud-load-balancer - Registered built-in resource type: cloud-compute-instance - Registered built-in resource type: cloud-object-store - Registered built-in resource type: cloud-block-storage - Registered built-in resource type: cloud-identity-principal - Registered built-in resource type: cloud-role - Registered built-in resource type: cloud-policy - Registered built-in resource type: cloud-log-group - Registered built-in resource type: cloud-alarm - Registered built-in resource type: cloud-queue - Registered built-in resource type: cloud-topic - Registered built-in resource type: cloud-container-repo - Registered built-in resource type: cloud-container-cluster - Registered built-in resource type: cloud-container-service - Registered built-in resource type: aws-account - Registered built-in resource type: aws-region - Registered built-in resource type: aws-vpc - Registered built-in resource type: aws-subnet - Registered built-in resource type: aws-igw - Registered built-in resource type: aws-nat-gw - Registered built-in resource type: aws-route-table - Registered built-in resource type: aws-nacl - Registered built-in resource type: aws-security-group - Registered built-in resource type: aws-alb - Registered built-in resource type: aws-nlb - Registered built-in resource type: aws-target-group - Registered built-in resource type: aws-listener - Registered built-in resource type: aws-ec2-instance - Registered built-in resource type: aws-ami - Registered built-in resource type: aws-launch-template - Registered built-in resource type: aws-asg - Registered built-in resource type: aws-s3-bucket - Registered built-in resource type: aws-ebs-volume - Registered built-in resource type: aws-efs-filesystem - Registered built-in resource type: aws-iam-user - Registered built-in resource type: aws-iam-role - Registered built-in resource type: aws-iam-policy - Registered built-in resource type: aws-iam-instance-profile - Registered built-in resource type: aws-cloudwatch-log-group - Registered built-in resource type: aws-cloudwatch-alarm - Registered built-in resource type: aws-cloudwatch-metric - Registered built-in resource type: aws-eventbridge-bus - Registered built-in resource type: aws-eventbridge-rule - Registered built-in resource type: aws-eventbridge-target - Registered built-in resource type: aws-sqs-queue - Registered built-in resource type: aws-sns-topic - Registered built-in resource type: aws-sns-subscription - Registered built-in resource type: aws-ecr-repo - Registered built-in resource type: aws-ecs-cluster - Registered built-in resource type: aws-ecs-service - Registered built-in resource type: aws-ecs-task-def - Registered built-in resource type: aws-eks-cluster - Registered built-in resource type: aws-eks-nodegroup - Registered built-in resource type: gcp - Registered built-in resource type: azure - Registered built-in resource type: container-runtime - Registered built-in resource type: container-image - Registered built-in resource type: container-mount - Registered built-in resource type: container-exec-env - Registered built-in resource type: container-port - Registered built-in resource type: container-volume - Registered built-in resource type: container-network - Registered built-in resource type: postgres - Registered built-in resource type: mysql - Registered built-in resource type: sqlite - Registered built-in resource type: duckdb - Registered built-in resource type: file - Registered built-in resource type: directory - Registered built-in resource type: commit - Registered built-in resource type: branch - Registered built-in resource type: tag - Registered built-in resource type: tree - Registered built-in resource type: remote - Registered built-in resource type: submodule - Registered built-in resource type: symlink - Registered built-in resource type: executable - Registered built-in resource type: lsp-server - Registered built-in resource type: lsp-workspace - Registered built-in resource type: lsp-document - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code: - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED - 2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12 - -✗ Output Block 153 - Overall summary: - 6 features passed, 1 failed, 0 errored, 0 skipped - 144 scenarios passed, 1 failed, 0 errored, 0 skipped - 553 steps passed, 1 failed, 0 errored, 0 skipped - Took 2.366s - Wall time: 2m 47.786s - -✗ nox > Running session unit_tests-3.13 - nox > Running session unit_tests-3.13 - nox > Reusing existing virtual environment at .nox/unit_tests-3-13. - nox > uv pip install -e '.[tests]' - nox > uv pip install setuptools wheel - nox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess - nox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db - nox > python -m compileall -q features/ - nox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature - nox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1 - nox > Session unit_tests-3.13 failed. - -✗ Error Output - nox > Running session unit_tests-3.13 - nox > Reusing existing virtual environment at .nox/unit_tests-3-13. - nox > uv pip install -e '.[tests]' - nox > uv pip install setuptools wheel - nox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess - nox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db - nox > python -m compileall -q features/ - nox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature - nox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1 - nox > Session unit_tests-3.13 failed. - - diff --git a/test_reports/test_results.json b/test_reports/test_results.json deleted file mode 100644 index acafaa4f7..000000000 --- a/test_reports/test_results.json +++ /dev/null @@ -1,2054 +0,0 @@ -{ - "framework": "generic", - "tests": [ - { - "name": "Output Block 1", - "passed": true, - "output": [ - "@devcontainer-sandbox", - "Feature: devcontainer-instance uses snapshot sandbox strategy", - " As a CleverAgents developer", - " I want devcontainer-instance resources to use the snapshot sandbox strategy", - " So that plan execution inside containers is safely isolated", - " Scenario: DevcontainerHandler default strategy is snapshot ", - " When I inspect DevcontainerHandler class attributes", - " Then the DevcontainerHandler _default_strategy should be \"snapshot\"" - ], - "rawOutput": "@devcontainer-sandbox\nFeature: devcontainer-instance uses snapshot sandbox strategy\n As a CleverAgents developer\n I want devcontainer-instance resources to use the snapshot sandbox strategy\n So that plan execution inside containers is safely isolated\n Scenario: DevcontainerHandler default strategy is snapshot \n When I inspect DevcontainerHandler class attributes\n Then the DevcontainerHandler _default_strategy should be \"snapshot\"" - }, - { - "name": "Output Block 2", - "passed": true, - "output": [ - " Scenario: devcontainer-instance resource type has snapshot sandbox strategy ", - " When I look up the \"devcontainer-instance\" resource type spec", - " Then the spec sandbox_strategy should be \"snapshot\"" - ], - "rawOutput": " Scenario: devcontainer-instance resource type has snapshot sandbox strategy \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec sandbox_strategy should be \"snapshot\"" - }, - { - "name": "Output Block 3", - "passed": true, - "output": [ - " Scenario: devcontainer-instance child_types includes container-mount ", - " When I look up the \"devcontainer-instance\" resource type spec", - " Then the spec child_types should contain \"container-mount\"" - ], - "rawOutput": " Scenario: devcontainer-instance child_types includes container-mount \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"container-mount\"" - }, - { - "name": "Output Block 4", - "passed": true, - "output": [ - " Scenario: devcontainer-instance child_types includes container-exec-env ", - " When I look up the \"devcontainer-instance\" resource type spec", - " Then the spec child_types should contain \"container-exec-env\"" - ], - "rawOutput": " Scenario: devcontainer-instance child_types includes container-exec-env \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"container-exec-env\"" - }, - { - "name": "Output Block 5", - "passed": true, - "output": [ - " Scenario: devcontainer-instance child_types includes container-port ", - " When I look up the \"devcontainer-instance\" resource type spec", - " Then the spec child_types should contain \"container-port\"" - ], - "rawOutput": " Scenario: devcontainer-instance child_types includes container-port \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"container-port\"" - }, - { - "name": "Output Block 6", - "passed": true, - "output": [ - " Scenario: devcontainer-instance child_types includes devcontainer-file ", - " When I look up the \"devcontainer-instance\" resource type spec", - " Then the spec child_types should contain \"devcontainer-file\"" - ], - "rawOutput": " Scenario: devcontainer-instance child_types includes devcontainer-file \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"devcontainer-file\"" - }, - { - "name": "Output Block 7", - "passed": true, - "output": [ - " Scenario: ContainerLifecycleTracker default state is discovered ", - " When I create a new ContainerLifecycleTracker for resource \"01SANDBOX0000000000000001\"", - " Then the tracker initial state should be \"discovered\"" - ], - "rawOutput": " Scenario: ContainerLifecycleTracker default state is discovered \n When I create a new ContainerLifecycleTracker for resource \"01SANDBOX0000000000000001\"\n Then the tracker initial state should be \"discovered\"" - }, - { - "name": "Output Block 8", - "passed": true, - "output": [ - " Scenario: ContainerLifecycleState has discovered value ", - " When I inspect ContainerLifecycleState enum values", - " Then the lifecycle enum values should contain \"discovered\"", - " And the lifecycle enum values should not contain \"detected\"" - ], - "rawOutput": " Scenario: ContainerLifecycleState has discovered value \n When I inspect ContainerLifecycleState enum values\n Then the lifecycle enum values should contain \"discovered\"\n And the lifecycle enum values should not contain \"detected\"" - }, - { - "name": "Output Block 9", - "passed": true, - "output": [ - " Scenario: devcontainer-instance in BUILTIN_TYPES has snapshot strategy ", - " When I look up \"devcontainer-instance\" in BUILTIN_TYPES", - " Then the BUILTIN_TYPES entry sandbox_strategy should be \"snapshot\"" - ], - "rawOutput": " Scenario: devcontainer-instance in BUILTIN_TYPES has snapshot strategy \n When I look up \"devcontainer-instance\" in BUILTIN_TYPES\n Then the BUILTIN_TYPES entry sandbox_strategy should be \"snapshot\"" - }, - { - "name": "Output Block 10", - "passed": true, - "output": [ - " Scenario: devcontainer-instance in BUILTIN_TYPES has correct child_types ", - " When I look up \"devcontainer-instance\" in BUILTIN_TYPES", - " Then the BUILTIN_TYPES entry child_types should include \"container-mount\"", - " And the BUILTIN_TYPES entry child_types should include \"container-exec-env\"", - " And the BUILTIN_TYPES entry child_types should include \"container-port\"" - ], - "rawOutput": " Scenario: devcontainer-instance in BUILTIN_TYPES has correct child_types \n When I look up \"devcontainer-instance\" in BUILTIN_TYPES\n Then the BUILTIN_TYPES entry child_types should include \"container-mount\"\n And the BUILTIN_TYPES entry child_types should include \"container-exec-env\"\n And the BUILTIN_TYPES entry child_types should include \"container-port\"" - }, - { - "name": "Output Block 11", - "passed": false, - "output": [ - "1 feature passed, 0 failed, 0 skipped", - "10 scenarios passed, 0 failed, 0 skipped", - "23 steps passed, 0 failed, 0 skipped", - "Took 0min 0.006s", - "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", - " 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\"" - ], - "rawOutput": "1 feature passed, 0 failed, 0 skipped\n10 scenarios passed, 0 failed, 0 skipped\n23 steps passed, 0 failed, 0 skipped\nTook 0min 0.006s\nFeature: Devcontainer Lifecycle State Model\n As a CleverAgents developer\n I want the container lifecycle state model to enforce valid transitions\n So that containers follow a predictable state machine\n Scenario: ContainerLifecycleState has all required values \n When I inspect ContainerLifecycleState enum values\n Then the lifecycle enum should contain \"discovered\"\n And the lifecycle enum should contain \"building\"\n And the lifecycle enum should contain \"running\"\n And the lifecycle enum should contain \"stopping\"\n And the lifecycle enum should contain \"stopped\"\n And the lifecycle enum should contain \"failed\"" - }, - { - "name": "Output Block 12", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Valid transitions are accepted \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000001\"\n When I transition from \"discovered\" to \"building\"\n Then the transition should succeed\n And the tracker state should be \"building\"" - }, - { - "name": "Output Block 13", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Active transition after starting \n Given a lifecycle tracker in \"building\" state for resource \"01TESTLIFECYCLE0000000002\"\n When I transition from \"building\" to \"running\"\n Then the transition should succeed\n And the tracker state should be \"running\"" - }, - { - "name": "Output Block 14", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition is rejected \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000003\"\n When I attempt to transition from \"discovered\" to \"running\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 15", - "passed": false, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Stopping to error transition is valid \n Given a lifecycle tracker in \"stopping\" state for resource \"01TESTLIFECYCLE0000000004\"\n When I transition from \"stopping\" to \"failed\"\n Then the transition should succeed\n And the tracker state should be \"failed\"" - }, - { - "name": "Output Block 16", - "passed": false, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Error to starting transition is valid for retry \n Given a lifecycle tracker in \"failed\" state for resource \"01TESTLIFECYCLE0000000005\"\n When I transition from \"failed\" to \"building\"\n Then the transition should succeed\n And the tracker state should be \"building\"" - }, - { - "name": "Output Block 17", - "passed": true, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Stopped to starting transition is valid for rebuild \n Given a lifecycle tracker in \"stopped\" state for resource \"01TESTLIFECYCLE0000000006\"\n When I transition from \"stopped\" to \"building\"\n Then the transition should succeed" - }, - { - "name": "Output Block 18", - "passed": true, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Transition history is recorded \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000007\"\n When I transition from \"discovered\" to \"building\"\n Then the tracker should have 1 transition in history" - }, - { - "name": "Output Block 19", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Lifecycle tracker persists state across calls \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000060\"\n When I transition from \"discovered\" to \"building\"\n And I retrieve the tracker for \"01TESTLIFECYCLE0000000060\"\n Then the retrieved tracker state should be \"building\"" - }, - { - "name": "Output Block 20", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: List active containers returns only active ones \n Given a mock devcontainer CLI runner\n And the runner configured for successful activation\n And an active container \"01TESTLIFECYCLE0000000070\" with container ID \"ctr-x\"\n And a lifecycle tracker for resource \"01TESTLIFECYCLE0000000071\"\n When I list active containers\n Then the active list should contain \"01TESTLIFECYCLE0000000070\"\n And the active list should not contain \"01TESTLIFECYCLE0000000071\"" - }, - { - "name": "Output Block 21", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Parse valid devcontainer up JSON output \n When I parse devcontainer up output with containerId \"abcdef123456\" and workspace \"/ws\"\n Then the parsed container ID should be \"abcdef123456\"\n And the parsed workspace path should be \"/ws\"" - }, - { - "name": "Output Block 22", - "passed": true, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Parse invalid devcontainer up JSON output gracefully \n When I parse devcontainer up output with invalid JSON\n Then the parsed container ID should be None\n And the parsed workspace path should be None" - }, - { - "name": "Output Block 23", - "passed": false, - "output": [ - " Scenario: validate_transition rejects wrong types ", - " When I call validate_transition with non-enum arguments", - " Then it should raise TypeError" - ], - "rawOutput": " Scenario: validate_transition rejects wrong types \n When I call validate_transition with non-enum arguments\n Then it should raise TypeError" - }, - { - "name": "Output Block 24", - "passed": false, - "output": [ - " Scenario: validate_transition rejects wrong to_state type ", - " When I call validate_transition with non-enum to_state", - " Then it should raise TypeError" - ], - "rawOutput": " Scenario: validate_transition rejects wrong to_state type \n When I call validate_transition with non-enum to_state\n Then it should raise TypeError" - }, - { - "name": "Output Block 25", - "passed": false, - "output": [ - " Scenario: transition_state rejects wrong tracker type ", - " When I call transition_state with non-tracker argument", - " Then it should raise TypeError" - ], - "rawOutput": " Scenario: transition_state rejects wrong tracker type \n When I call transition_state with non-tracker argument\n Then it should raise TypeError" - }, - { - "name": "Output Block 26", - "passed": false, - "output": [ - " Scenario: transition_state rejects wrong to_state type ", - " When I call transition_state with non-enum to_state argument", - " Then it should raise TypeError", - "Feature: agents resource list shows devcontainer lifecycle state column", - " As a CleverAgents user", - " I want the resource list to show the lifecycle state for devcontainer-instance resources", - " So that I can see whether a devcontainer is discovered, running, stopped, or failed", - " Feature: agents resource list shows devcontainer lifecycle state column " - ], - "rawOutput": " Scenario: transition_state rejects wrong to_state type \n When I call transition_state with non-enum to_state argument\n Then it should raise TypeError\nFeature: agents resource list shows devcontainer lifecycle state column\n As a CleverAgents user\n I want the resource list to show the lifecycle state for devcontainer-instance resources\n So that I can see whether a devcontainer is discovered, running, stopped, or failed\n Feature: agents resource list shows devcontainer lifecycle state column " - }, - { - "name": "Output Block 27", - "passed": true, - "output": [ - " Scenario: resource list shows \"Status\" column header ", - " Given a fresh in-memory resource registry" - ], - "rawOutput": " Scenario: resource list shows \"Status\" column header \n Given a fresh in-memory resource registry" - }, - { - "name": "Output Block 28", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: get_lifecycle_tracker rejects empty resource_id \n When I attempt to get tracker with empty resource_id\n Then the get tracker should raise ValueError" - }, - { - "name": "Output Block 29", - "passed": false, - "output": [ - " Scenario: set_lifecycle_tracker rejects wrong type ", - " When I attempt to set tracker with wrong type", - " Then the set tracker should raise TypeError" - ], - "rawOutput": " Scenario: set_lifecycle_tracker rejects wrong type \n When I attempt to set tracker with wrong type\n Then the set tracker should raise TypeError" - }, - { - "name": "Output Block 30", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition running to building is rejected \n Given a lifecycle tracker in \"running\" state for resource \"01TESTLIFECYCLE0000000240\"\n When I attempt to transition from \"running\" to \"building\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 31", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition stopped to running is rejected \n Given a lifecycle tracker in \"stopped\" state for resource \"01TESTLIFECYCLE0000000241\"\n When I attempt to transition from \"stopped\" to \"running\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 32", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition building to stopped is rejected \n Given a lifecycle tracker in \"building\" state for resource \"01TESTLIFECYCLE0000000242\"\n When I attempt to transition from \"building\" to \"stopped\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 33", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition failed to running is rejected \n Given a lifecycle tracker in \"failed\" state for resource \"01TESTLIFECYCLE0000000243\"\n When I attempt to transition from \"failed\" to \"running\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 34", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition discovered to stopping is rejected \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000244\"\n When I attempt to transition from \"discovered\" to \"stopping\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 35", - "passed": false, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Invalid transition building to discovered is rejected \n Given a lifecycle tracker in \"building\" state for resource \"01TESTLIFECYCLE0000000245\"\n When I attempt to transition from \"building\" to \"discovered\"\n Then the transition should raise ValueError" - }, - { - "name": "Output Block 36", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: Parse devcontainer up output with log lines before JSON \n When I parse devcontainer up output with log lines before JSON\n Then the parsed container ID should be \"aabbccddee0099887766\"\n And the parsed workspace path should be \"/workspaces/multi\"" - }, - { - "name": "Output Block 37", - "passed": true, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Transition history is capped at 100 entries \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000300\"\n When I perform 105 transitions cycling through valid states\n Then the tracker should have at most 100 transitions" - }, - { - "name": "Output Block 38", - "passed": true, - "output": [ - " 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", - " And built-in types are bootstrapped" - ], - "rawOutput": " Scenario: Invalid container ID format is rejected during parsing \n When I parse devcontainer up output with invalid container ID \"not-a-hex-id!\"\n Then the parsed container ID should be empty\n And built-in types are bootstrapped" - }, - { - "name": "Output Block 39", - "passed": true, - "output": [ - " 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\"", - " Given a devcontainer-instance resource is registered", - " And the parsed workspace path should be None", - " When I run resource list with all flag" - ], - "rawOutput": " Scenario: Parse devcontainer up output with relative workspace path \n When I parse devcontainer up output with relative workspace \"relative/ws\"\n Then the parsed container ID should be \"aabbccddee0011223344\"\n Given a devcontainer-instance resource is registered\n And the parsed workspace path should be None\n When I run resource list with all flag" - }, - { - "name": "Output Block 40", - "passed": true, - "output": [ - " 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" - ], - "rawOutput": " Scenario: Terminal tracker eviction removes oldest stopped trackers \n Given 210 stopped container trackers in the registry\n When I run terminal tracker eviction\n Then the registry should have at most 200 terminal trackers" - }, - { - "name": "Output Block 41", - "passed": true, - "output": [ - " 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" - ], - "rawOutput": " Scenario: evict_terminal_trackers returns 0 when below threshold \n Given 50 stopped container trackers in the registry\n When I run terminal tracker eviction\n Then the eviction count should be 0" - }, - { - "name": "Output Block 42", - "passed": true, - "output": [ - " 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\"", - " Then the resource output should contain \"Status\"" - ], - "rawOutput": " Scenario: get_lifecycle_tracker auto-creates tracker for new resource \n When I get tracker for new resource \"01TESTLIFECYCLE0000000730\"\n Then the auto-created tracker state should be \"discovered\"\n And the auto-created tracker resource_id should be \"01TESTLIFECYCLE0000000730\"\n Then the resource output should contain \"Status\"" - }, - { - "name": "Output Block 43", - "passed": true, - "output": [ - " 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\"" - ], - "rawOutput": " Scenario: clear_lifecycle_registry stops health check threads \n Given a mock devcontainer CLI runner\n And the runner configured for successful health check\n And an active container \"01TESTLIFECYCLE0000000740\" with container ID \"ctr-clr\"" - }, - { - "name": "Output Block 44", - "passed": true, - "output": [ - " Scenario: resource list shows \"discovered (not built)\" for a new devcontainer-instance ", - " Given a fresh in-memory resource registry", - " 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" - ], - "rawOutput": " Scenario: resource list shows \"discovered (not built)\" for a new devcontainer-instance \n Given a fresh in-memory resource registry\n And a running health check for \"01TESTLIFECYCLE0000000740\"\n When I clear the lifecycle registry\n Then the registry should be empty\n And the health check for \"01TESTLIFECYCLE0000000740\" should be unregistered" - }, - { - "name": "Output Block 45", - "passed": false, - "output": [ - "1 feature passed, 0 failed, 0 skipped", - "32 scenarios passed, 0 failed, 0 skipped", - "106 steps passed, 0 failed, 0 skipped", - "Took 0min 0.037s", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " When I run resource list with all flag", - " Then the resource output should contain \"discovered (not built)\"" - ], - "rawOutput": "1 feature passed, 0 failed, 0 skipped\n32 scenarios passed, 0 failed, 0 skipped\n106 steps passed, 0 failed, 0 skipped\nTook 0min 0.037s\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n When I run resource list with all flag\n Then the resource output should contain \"discovered (not built)\"" - }, - { - "name": "Output Block 46", - "passed": true, - "output": [ - " Scenario: resource list shows \"running\" state for a running devcontainer ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " And the devcontainer lifecycle state is \"running\"", - " When I run resource list with all flag", - " Then the resource output should contain \"running\"" - ], - "rawOutput": " Scenario: resource list shows \"running\" state for a running devcontainer \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"running\"\n When I run resource list with all flag\n Then the resource output should contain \"running\"" - }, - { - "name": "Output Block 47", - "passed": true, - "output": [ - " Scenario: resource list shows \"stopped\" state for a stopped devcontainer ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " And the devcontainer lifecycle state is \"stopped\"", - " When I run resource list with all flag", - " Then the resource output should contain \"stopped\"" - ], - "rawOutput": " Scenario: resource list shows \"stopped\" state for a stopped devcontainer \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"stopped\"\n When I run resource list with all flag\n Then the resource output should contain \"stopped\"" - }, - { - "name": "Output Block 48", - "passed": false, - "output": [ - " Scenario: resource list shows \"failed\" state for a failed devcontainer ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " And the devcontainer lifecycle state is \"failed\"", - " When I run resource list with all flag", - " Then the resource output should contain \"failed\"" - ], - "rawOutput": " Scenario: resource list shows \"failed\" state for a failed devcontainer \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"failed\"\n When I run resource list with all flag\n Then the resource output should contain \"failed\"" - }, - { - "name": "Output Block 49", - "passed": true, - "output": [ - " Scenario: resource list shows empty state for non-container resources ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given I run resource add \"git-checkout\" \"local/my-repo\" with path \"/tmp/repo\"", - " When I run resource list", - " Then the resource output should contain \"local/my-repo\"", - " And the resource output should contain \"git-checkout\"" - ], - "rawOutput": " Scenario: resource list shows empty state for non-container resources \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given I run resource add \"git-checkout\" \"local/my-repo\" with path \"/tmp/repo\"\n When I run resource list\n Then the resource output should contain \"local/my-repo\"\n And the resource output should contain \"git-checkout\"" - }, - { - "name": "Output Block 50", - "passed": true, - "output": [ - " Scenario: resource list shows warning banner when devcontainer is in detected state ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " When I run resource list with all flag", - " Then the resource output should contain \"Devcontainer detected\"" - ], - "rawOutput": " Scenario: resource list shows warning banner when devcontainer is in detected state \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n When I run resource list with all flag\n Then the resource output should contain \"Devcontainer detected\"" - }, - { - "name": "FAIL: Output Block 51", - "passed": false, - "output": [ - " ASSERT FAILED: Expected 'Devcontainer detected' in output, got:", - " Resources (1 total) ", - " ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓", - " ┃ ID ┃ Name ┃ Type ┃ Status ┃ Kind ┃ Location ┃ Description ┃", - " ┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩", - " │ 01KP2TDV4GAR... │ (unnamed) │ devcontainer-instance │ discovered (not built) │ physical │ /tmp/test-project │ Test devcontainer │", - " └─────────────────┴───────────┴───────────────────────┴────────────────────────┴──────────┴───────────────────┴───────────────────┘" - ], - "rawOutput": " ASSERT FAILED: Expected 'Devcontainer detected' in output, got:\n Resources (1 total) \n ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n ┃ ID ┃ Name ┃ Type ┃ Status ┃ Kind ┃ Location ┃ Description ┃\n ┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n │ 01KP2TDV4GAR... │ (unnamed) │ devcontainer-instance │ discovered (not built) │ physical │ /tmp/test-project │ Test devcontainer │\n └─────────────────┴───────────┴───────────────────────┴────────────────────────┴──────────┴───────────────────┴───────────────────┘" - }, - { - "name": "Output Block 52", - "passed": true, - "output": [ - "", - " Scenario: resource list does not show warning banner when devcontainer is running ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " And the devcontainer lifecycle state is \"running\"", - " When I run resource list with all flag", - " Then the resource output should not contain \"Devcontainer detected\"" - ], - "rawOutput": "\n Scenario: resource list does not show warning banner when devcontainer is running \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"running\"\n When I run resource list with all flag\n Then the resource output should not contain \"Devcontainer detected\"" - }, - { - "name": "Output Block 53", - "passed": false, - "output": [ - " @tdd_issue @tdd_issue_4263 @tdd_expected_fail", - " Scenario: resource list JSON output includes lifecycle_state for devcontainer-instance ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a devcontainer-instance resource is registered", - " When I run resource list with all flag and format \"json\"", - " Then the resource output should be valid JSON", - " And the resource JSON output should contain key \"lifecycle_state\"" - ], - "rawOutput": " @tdd_issue @tdd_issue_4263 @tdd_expected_fail\n Scenario: resource list JSON output includes lifecycle_state for devcontainer-instance \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n When I run resource list with all flag and format \"json\"\n Then the resource output should be valid JSON\n And the resource JSON output should contain key \"lifecycle_state\"" - }, - { - "name": "FAIL: Output Block 54", - "passed": false, - "output": [ - " ASSERT FAILED: Key 'lifecycle_state' not found in JSON output" - ], - "rawOutput": " ASSERT FAILED: Key 'lifecycle_state' not found in JSON output" - }, - { - "name": "Output Block 55", - "passed": true, - "output": [ - "", - " Scenario: resource list JSON output has null lifecycle_state for non-container resources ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given I run resource add \"git-checkout\" \"local/my-repo\" with path \"/tmp/repo\"", - " When I run resource list with format \"json\"", - " Then the resource output should be valid JSON", - " And the resource JSON lifecycle_state should be null for non-container resources" - ], - "rawOutput": "\n Scenario: resource list JSON output has null lifecycle_state for non-container resources \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given I run resource add \"git-checkout\" \"local/my-repo\" with path \"/tmp/repo\"\n When I run resource list with format \"json\"\n Then the resource output should be valid JSON\n And the resource JSON lifecycle_state should be null for non-container resources" - }, - { - "name": "Output Block 56", - "passed": true, - "output": [ - " Scenario: resource list shows lifecycle state for container-instance resources ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - " Given a container-instance resource is registered", - " When I run resource list with all flag", - " Then the resource output should contain \"Status\"", - " And the resource output should contain \"discovered (not built)\"" - ], - "rawOutput": " Scenario: resource list shows lifecycle state for container-instance resources \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a container-instance resource is registered\n When I run resource list with all flag\n Then the resource output should contain \"Status\"\n And the resource output should contain \"discovered (not built)\"" - }, - { - "name": "Output Block 57", - "passed": false, - "output": [ - " Scenario: resource list succeeds gracefully when lifecycle tracker raises an error ", - " Given a fresh in-memory resource registry", - " And built-in types are bootstrapped", - "Feature: Devcontainer Resource Handler", - " As a CleverAgents developer", - " I want devcontainer resources to be auto-discovered and manually registered", - " So that devcontainer environments integrate into the resource model Given a devcontainer-instance resource is registered" - ], - "rawOutput": " Scenario: resource list succeeds gracefully when lifecycle tracker raises an error \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\nFeature: Devcontainer Resource Handler\n As a CleverAgents developer\n I want devcontainer resources to be auto-discovered and manually registered\n So that devcontainer environments integrate into the resource model Given a devcontainer-instance resource is registered" - }, - { - "name": "Output Block 58", - "passed": false, - "output": [ - " Scenario: Register devcontainer-instance manually ", - " Given a temporary directory with a valid devcontainer.json", - " When I create a devcontainer-instance resource at that path", - " Then And the resource should have type \"the lifecycle tracker raises an error for the resourcedevcontainer-instance\"" - ], - "rawOutput": " Scenario: Register devcontainer-instance manually \n Given a temporary directory with a valid devcontainer.json\n When I create a devcontainer-instance resource at that path\n Then And the resource should have type \"the lifecycle tracker raises an error for the resourcedevcontainer-instance\"" - }, - { - "name": "Output Block 59", - "passed": true, - "output": [ - " And the resource should have a non-empty resource_id", - " When I run resource list with all flag", - " Then the resource list command should succeed" - ], - "rawOutput": " And the resource should have a non-empty resource_id\n When I run resource list with all flag\n Then the resource list command should succeed" - }, - { - "name": "Output Block 60", - "passed": true, - "output": [ - " Scenario: Register container-instance manually ", - " When I create a container-instance resource with image \"ubuntu:latest\"", - " Then the container resource should have type \"container-instance\"", - " And the resource output should contain \"devcontainer-instance\"" - ], - "rawOutput": " Scenario: Register container-instance manually \n When I create a container-instance resource with image \"ubuntu:latest\"\n Then the container resource should have type \"container-instance\"\n And the resource output should contain \"devcontainer-instance\"" - }, - { - "name": "Output Block 61", - "passed": false, - "output": [ - "", - "Failing scenarios:", - " features/resource_list_lifecycle_state.feature:44 resource list shows warning banner when devcontainer is in detected state" - ], - "rawOutput": "\nFailing scenarios:\n features/resource_list_lifecycle_state.feature:44 resource list shows warning banner when devcontainer is in detected state" - }, - { - "name": "Output Block 62", - "passed": false, - "output": [ - "0 features passed, 1 failed, 0 skipped", - "11 scenarios passed, 1 failed, 0 skipped", - "69 steps passed, 1 failed, 0 skipped", - "Took 0min 1.827s" - ], - "rawOutput": "0 features passed, 1 failed, 0 skipped\n11 scenarios passed, 1 failed, 0 skipped\n69 steps passed, 1 failed, 0 skipped\nTook 0min 1.827s" - }, - { - "name": "Output Block 63", - "passed": true, - "output": [ - " Scenario: Auto-discover devcontainer from git-checkout resource ", - " Given a temporary directory simulating a git checkout", - " And the directory has a .devcontainer/devcontainer.json file", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 1 result", - " And the discovered config path should end with \"devcontainer.json\"" - ], - "rawOutput": " Scenario: Auto-discover devcontainer from git-checkout resource \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n And the discovered config path should end with \"devcontainer.json\"" - }, - { - "name": "Output Block 64", - "passed": true, - "output": [ - " Scenario: Auto-discover root devcontainer.json from git-checkout ", - " Given a temporary directory simulating a git checkout", - " And the directory has a root .devcontainer.json file", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 1 result" - ], - "rawOutput": " Scenario: Auto-discover root devcontainer.json from git-checkout \n Given a temporary directory simulating a git checkout\n And the directory has a root .devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result" - }, - { - "name": "Output Block 65", - "passed": true, - "output": [ - " Scenario: Auto-discover both devcontainer locations ", - " Given a temporary directory simulating a git checkout", - " And the directory has a .devcontainer/devcontainer.json file", - " And the directory has a root .devcontainer.json file", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 2 results" - ], - "rawOutput": " Scenario: Auto-discover both devcontainer locations \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file\n And the directory has a root .devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 2 results" - }, - { - "name": "Output Block 66", - "passed": true, - "output": [ - " Scenario: Auto-discover devcontainer from fs-directory resource ", - " Given a temporary directory simulating a filesystem mount", - " And the directory has a .devcontainer/devcontainer.json file", - " When I run devcontainer discovery on the directory as \"fs-directory\"", - " Then discovery should return 1 result" - ], - "rawOutput": " Scenario: Auto-discover devcontainer from fs-directory resource \n Given a temporary directory simulating a filesystem mount\n And the directory has a .devcontainer/devcontainer.json file\n When I run devcontainer discovery on the directory as \"fs-directory\"\n Then discovery should return 1 result" - }, - { - "name": "Output Block 67", - "passed": true, - "output": [ - " Scenario: No discovery for non-trigger resource types ", - " Given a temporary directory simulating a filesystem mount", - " And the directory has a .devcontainer/devcontainer.json file", - " When I run devcontainer discovery on the directory as \"fs-file\"", - " Then discovery should return 0 results" - ], - "rawOutput": " Scenario: No discovery for non-trigger resource types \n Given a temporary directory simulating a filesystem mount\n And the directory has a .devcontainer/devcontainer.json file\n When I run devcontainer discovery on the directory as \"fs-file\"\n Then discovery should return 0 results" - }, - { - "name": "Output Block 68", - "passed": true, - "output": [ - " Scenario: Skip invalid JSON in devcontainer.json ", - " Given a temporary directory with an invalid devcontainer.json", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 0 results" - ], - "rawOutput": " Scenario: Skip invalid JSON in devcontainer.json \n Given a temporary directory with an invalid devcontainer.json\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results" - }, - { - "name": "Output Block 69", - "passed": true, - "output": [ - " Scenario: Skip non-object JSON in devcontainer.json ", - " Given a temporary directory with a non-object devcontainer.json", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 0 results" - ], - "rawOutput": " Scenario: Skip non-object JSON in devcontainer.json \n Given a temporary directory with a non-object devcontainer.json\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results" - }, - { - "name": "Output Block 70", - "passed": true, - "output": [ - " Scenario: Handle missing devcontainer directory gracefully ", - " Given a temporary directory with no devcontainer configuration", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 0 results", - "@clone-into", - "Feature: container-instance --clone-into argument", - " As a CleverAgents user", - " I want to clone a git repository into a running container", - " So that I can work with the repository inside the container environment", - " Scenario: Devcontainer types appear in resource type list ", - " Given the built-in resource type registry" - ], - "rawOutput": " Scenario: Handle missing devcontainer directory gracefully \n Given a temporary directory with no devcontainer configuration\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results\n@clone-into\nFeature: container-instance --clone-into argument\n As a CleverAgents user\n I want to clone a git repository into a running container\n So that I can work with the repository inside the container environment\n Scenario: Devcontainer types appear in resource type list \n Given the built-in resource type registry" - }, - { - "name": "Output Block 71", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.1 ", - " When I validate clone-into URL \"https://github.com/org/repo.git\"", - " When I list all built-in type names", - " Then the clone-into URL should be valid", - " Then the type list should contain \"devcontainer-instance\"", - " And the type list should contain \"devcontainer-file\"", - " And the type list should contain \"container-instance\"" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.1 \n When I validate clone-into URL \"https://github.com/org/repo.git\"\n When I list all built-in type names\n Then the clone-into URL should be valid\n Then the type list should contain \"devcontainer-instance\"\n And the type list should contain \"devcontainer-file\"\n And the type list should contain \"container-instance\"" - }, - { - "name": "Output Block 72", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.2 ", - " When I validate clone-into URL \"http://internal.example.com/repo.git\"", - " Then the clone-into URL should be valid" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.2 \n When I validate clone-into URL \"http://internal.example.com/repo.git\"\n Then the clone-into URL should be valid" - }, - { - "name": "Output Block 73", - "passed": true, - "output": [ - " Scenario: DevcontainerHandler satisfies ResourceHandler protocol ", - " When I instantiate DevcontainerHandler", - " Then it should satisfy the ResourceHandler protocol" - ], - "rawOutput": " Scenario: DevcontainerHandler satisfies ResourceHandler protocol \n When I instantiate DevcontainerHandler\n Then it should satisfy the ResourceHandler protocol" - }, - { - "name": "Output Block 74", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.3 ", - " When I validate clone-into URL \"git@github.com:org/repo.git\"", - " Then the clone-into URL should be valid" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.3 \n When I validate clone-into URL \"git@github.com:org/repo.git\"\n Then the clone-into URL should be valid" - }, - { - "name": "Output Block 75", - "passed": true, - "output": [ - " Scenario: DevcontainerHandler has correct default strategy ", - " When I instantiate DevcontainerHandler" - ], - "rawOutput": " Scenario: DevcontainerHandler has correct default strategy \n When I instantiate DevcontainerHandler" - }, - { - "name": "Output Block 76", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.4 ", - " When I validate clone-into URL \"ssh://git@bitbucket.org/org/repo.git\"", - " Then the clone-into URL should be valid", - " Then its default strategy should be \"snapshot\"" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.4 \n When I validate clone-into URL \"ssh://git@bitbucket.org/org/repo.git\"\n Then the clone-into URL should be valid\n Then its default strategy should be \"snapshot\"" - }, - { - "name": "Output Block 77", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.5 ", - " When I validate clone-into URL \"git://github.com/org/repo.git\"" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.5 \n When I validate clone-into URL \"git://github.com/org/repo.git\"" - }, - { - "name": "Output Block 78", - "passed": true, - "output": [ - " Scenario: DevcontainerHandler has correct type label ", - " When I instantiate DevcontainerHandler", - " Then the clone-into URL should be valid", - " Then its type label should be \"devcontainer\"" - ], - "rawOutput": " Scenario: DevcontainerHandler has correct type label \n When I instantiate DevcontainerHandler\n Then the clone-into URL should be valid\n Then its type label should be \"devcontainer\"" - }, - { - "name": "Output Block 79", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.6 ", - " When I validate clone-into URL \"/local/path/to/repo\"", - " Then the clone-into URL should be valid" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.6 \n When I validate clone-into URL \"/local/path/to/repo\"\n Then the clone-into URL should be valid" - }, - { - "name": "Output Block 80", - "passed": true, - "output": [ - " Scenario: Discovery result requires valid config_path ", - " When I create a discovery result with valid parameters", - " Then the result should have a config_path attribute" - ], - "rawOutput": " Scenario: Discovery result requires valid config_path \n When I create a discovery result with valid parameters\n Then the result should have a config_path attribute" - }, - { - "name": "Output Block 81", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.7 ", - " When I validate clone-into URL \"./relative/repo\"", - " Then the clone-into URL should be valid" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.7 \n When I validate clone-into URL \"./relative/repo\"\n Then the clone-into URL should be valid" - }, - { - "name": "Output Block 82", - "passed": true, - "output": [ - " Scenario: Discovery result rejects empty parent_location ", - " When I create a discovery result with empty parent_location" - ], - "rawOutput": " Scenario: Discovery result rejects empty parent_location \n When I create a discovery result with empty parent_location" - }, - { - "name": "Output Block 83", - "passed": false, - "output": [ - " Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.1 ", - " When I validate clone-into URL \"not-a-url\"", - " Then it should raise a ValueError", - " Then the clone-into URL should be invalid" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.1 \n When I validate clone-into URL \"not-a-url\"\n Then it should raise a ValueError\n Then the clone-into URL should be invalid" - }, - { - "name": "Output Block 84", - "passed": true, - "output": [ - " Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.2 ", - " When I validate clone-into URL \"ftp://example.com\"" - ], - "rawOutput": " Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.2 \n When I validate clone-into URL \"ftp://example.com\"" - }, - { - "name": "Output Block 85", - "passed": true, - "output": [ - " Scenario: Auto-discover named devcontainer configuration ", - " Given a temporary directory simulating a git checkout", - " Then the clone-into URL should be invalid", - " And the directory has a named devcontainer configuration \"api\"", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 1 result", - " And the first result should have config name \"api\"" - ], - "rawOutput": " Scenario: Auto-discover named devcontainer configuration \n Given a temporary directory simulating a git checkout\n Then the clone-into URL should be invalid\n And the directory has a named devcontainer configuration \"api\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n And the first result should have config name \"api\"" - }, - { - "name": "Output Block 86", - "passed": false, - "output": [ - " Scenario: clone_repo_into_container rejects empty container_id ", - " When I call clone_repo_into_container with empty container_id", - " Then it should raise ValueError mentioning \"container_id\"" - ], - "rawOutput": " Scenario: clone_repo_into_container rejects empty container_id \n When I call clone_repo_into_container with empty container_id\n Then it should raise ValueError mentioning \"container_id\"" - }, - { - "name": "Output Block 87", - "passed": true, - "output": [ - " Scenario: Auto-discover multiple named devcontainer configurations ", - " Given a temporary directory simulating a git checkout", - " And the directory has a named devcontainer configuration \"api\"" - ], - "rawOutput": " Scenario: Auto-discover multiple named devcontainer configurations \n Given a temporary directory simulating a git checkout\n And the directory has a named devcontainer configuration \"api\"" - }, - { - "name": "Output Block 88", - "passed": false, - "output": [ - " Scenario: clone_repo_into_container rejects empty repo_url ", - " When I call clone_repo_into_container with empty repo_url", - " And the directory has a named devcontainer configuration \"frontend\"", - " Then it should raise ValueError mentioning \"repo_url\"", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 2 results", - " And the result config names should include \"api\"" - ], - "rawOutput": " Scenario: clone_repo_into_container rejects empty repo_url \n When I call clone_repo_into_container with empty repo_url\n And the directory has a named devcontainer configuration \"frontend\"\n Then it should raise ValueError mentioning \"repo_url\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 2 results\n And the result config names should include \"api\"" - }, - { - "name": "Output Block 89", - "passed": true, - "output": [ - " Scenario: clone_repo_into_container succeeds when docker exec returns 0 ", - " Given a mock docker exec that succeeds for clone", - " And the result config names should include \"frontend\"", - " When I clone \"https://github.com/org/repo.git\" into container \"abc123def456\"", - " Then the clone should succeed", - " And the clone target should be \"/workspace\"" - ], - "rawOutput": " Scenario: clone_repo_into_container succeeds when docker exec returns 0 \n Given a mock docker exec that succeeds for clone\n And the result config names should include \"frontend\"\n When I clone \"https://github.com/org/repo.git\" into container \"abc123def456\"\n Then the clone should succeed\n And the clone target should be \"/workspace\"" - }, - { - "name": "Output Block 90", - "passed": true, - "output": [ - " Scenario: Auto-discover mixed root and named devcontainer configurations ", - " Given a temporary directory simulating a git checkout", - " And the directory has a .devcontainer/devcontainer.json file" - ], - "rawOutput": " Scenario: Auto-discover mixed root and named devcontainer configurations \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file" - }, - { - "name": "Output Block 91", - "passed": true, - "output": [ - " Scenario: clone_repo_into_container uses custom target directory ", - " Given a mock docker exec that succeeds for clone", - " And the directory has a named devcontainer configuration \"api\"", - " When I clone repo \"https://github.com/org/repo.git\" into container \"abc123def456\" with target \"/custom/dir\"", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then the clone should succeed", - " And the clone target should be \"/custom/dir\"", - " Then discovery should return 2 results" - ], - "rawOutput": " Scenario: clone_repo_into_container uses custom target directory \n Given a mock docker exec that succeeds for clone\n And the directory has a named devcontainer configuration \"api\"\n When I clone repo \"https://github.com/org/repo.git\" into container \"abc123def456\" with target \"/custom/dir\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then the clone should succeed\n And the clone target should be \"/custom/dir\"\n Then discovery should return 2 results" - }, - { - "name": "Output Block 92", - "passed": true, - "output": [ - " Scenario: Root devcontainer.json has no config name ", - " Given a temporary directory simulating a git checkout", - " And the directory has a .devcontainer/devcontainer.json file" - ], - "rawOutput": " Scenario: Root devcontainer.json has no config name \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file" - }, - { - "name": "Output Block 93", - "passed": false, - "output": [ - " Scenario: clone_repo_into_container raises CloneIntoError when docker exec fails ", - " Given a mock docker exec that fails for clone with stderr \"fatal: repository not found\"", - " When I clone \"https://github.com/org/missing.git\" into container \"abc123def456\"", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then the clone should raise CloneIntoError", - " And the CloneIntoError should mention \"repository not found\"", - " Then discovery should return 1 result", - " And the first result should have no config name" - ], - "rawOutput": " Scenario: clone_repo_into_container raises CloneIntoError when docker exec fails \n Given a mock docker exec that fails for clone with stderr \"fatal: repository not found\"\n When I clone \"https://github.com/org/missing.git\" into container \"abc123def456\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then the clone should raise CloneIntoError\n And the CloneIntoError should mention \"repository not found\"\n Then discovery should return 1 result\n And the first result should have no config name" - }, - { - "name": "Output Block 94", - "passed": false, - "output": [ - " Scenario: CloneIntoError stores repo_url, container_id, and stderr ", - " Given a CloneIntoError with repo \"https://example.com/repo.git\" container \"ctr-001\" stderr \"auth failed\"", - " Then the CloneIntoError repo_url should be \"https://example.com/repo.git\"", - " And the CloneIntoError container_id should be \"ctr-001\"", - " And the CloneIntoError stderr should be \"auth failed\"" - ], - "rawOutput": " Scenario: CloneIntoError stores repo_url, container_id, and stderr \n Given a CloneIntoError with repo \"https://example.com/repo.git\" container \"ctr-001\" stderr \"auth failed\"\n Then the CloneIntoError repo_url should be \"https://example.com/repo.git\"\n And the CloneIntoError container_id should be \"ctr-001\"\n And the CloneIntoError stderr should be \"auth failed\"" - }, - { - "name": "Output Block 95", - "passed": true, - "output": [ - " Scenario: Root .devcontainer.json has no config name ", - " Given a temporary directory simulating a git checkout", - " And the directory has a root .devcontainer.json file", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 1 result", - " And ", - "the first result should have no config name Scenario: container-instance resource type has clone-into CLI argument " - ], - "rawOutput": " Scenario: Root .devcontainer.json has no config name \n Given a temporary directory simulating a git checkout\n And the directory has a root .devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n And \nthe first result should have no config name Scenario: container-instance resource type has clone-into CLI argument " - }, - { - "name": "Output Block 96", - "passed": true, - "output": [ - " When I look up the \"container-instance\" resource type spec", - " Then the spec should have a CLI argument named \"clone-into\"", - " And the clone-into argument should be of type \"string\"", - " And the clone-into argument should not be required" - ], - "rawOutput": " When I look up the \"container-instance\" resource type spec\n Then the spec should have a CLI argument named \"clone-into\"\n And the clone-into argument should be of type \"string\"\n And the clone-into argument should not be required" - }, - { - "name": "Output Block 97", - "passed": true, - "output": [ - " Scenario: Named config with invalid JSON is skipped ", - " Given a temporary directory simulating a git checkout", - " And the directory has a named devcontainer configuration \"broken\" with invalid JSON" - ], - "rawOutput": " Scenario: Named config with invalid JSON is skipped \n Given a temporary directory simulating a git checkout\n And the directory has a named devcontainer configuration \"broken\" with invalid JSON" - }, - { - "name": "Output Block 98", - "passed": true, - "output": [ - " Scenario: validate_clone_into_url rejects whitespace-only string ", - " When I validate clone-into URL with whitespace only", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then the clone-into URL should be invalid" - ], - "rawOutput": " Scenario: validate_clone_into_url rejects whitespace-only string \n When I validate clone-into URL with whitespace only\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then the clone-into URL should be invalid" - }, - { - "name": "Output Block 99", - "passed": false, - "output": [ - "1 feature passed, 0 failed, 0 skipped", - "17 scenarios passed, 0 failed, 0 skipped", - "44 steps passed, 0 failed, 0 skipped", - "Took 0min 0.008s", - " Then discovery should return 0 results" - ], - "rawOutput": "1 feature passed, 0 failed, 0 skipped\n17 scenarios passed, 0 failed, 0 skipped\n44 steps passed, 0 failed, 0 skipped\nTook 0min 0.008s\n Then discovery should return 0 results" - }, - { - "name": "Output Block 100", - "passed": true, - "output": [ - " Scenario: Empty .devcontainer directory returns no results ", - " Given a temporary directory simulating a git checkout", - " And the directory has an empty .devcontainer directory", - " When I run devcontainer discovery on the directory as \"git-checkout\"", - " Then discovery should return 0 results" - ], - "rawOutput": " Scenario: Empty .devcontainer directory returns no results \n Given a temporary directory simulating a git checkout\n And the directory has an empty .devcontainer directory\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results" - }, - { - "name": "Output Block 101", - "passed": true, - "output": [ - " Scenario: git-checkout is a trigger type ", - " Then \"git-checkout\" should be a trigger type" - ], - "rawOutput": " Scenario: git-checkout is a trigger type \n Then \"git-checkout\" should be a trigger type" - }, - { - "name": "Output Block 102", - "passed": true, - "output": [ - " Scenario: fs-directory is a trigger type ", - " Then \"fs-directory\" should be a trigger type" - ], - "rawOutput": " Scenario: fs-directory is a trigger type \n Then \"fs-directory\" should be a trigger type" - }, - { - "name": "Output Block 103", - "passed": true, - "output": [ - " Scenario: devcontainer-instance is not a trigger type ", - " Then \"devcontainer-instance\" should not be a trigger type" - ], - "rawOutput": " Scenario: devcontainer-instance is not a trigger type \n Then \"devcontainer-instance\" should not be a trigger type" - }, - { - "name": "Output Block 104", - "passed": false, - "output": [ - "1 feature passed, 0 failed, 0 skipped", - "26 scenarios passed, 0 failed, 0 skipped", - "90 steps passed, 0 failed, 0 skipped", - "Took 0min 0.026s", - "Feature: Devcontainer Session Cleanup and CLI Commands", - " As a CleverAgents developer", - " I want session-scoped container cleanup and CLI stop/rebuild commands", - " So that containers are cleaned up when sessions end and can be managed via CLI", - " Scenario: Active containers stopped on session cleanup ", - " Given a mock devcontainer CLI runner", - " And an active container \"01TESTLIFECYCLE0000000040\" with container ID \"ctr-a\"", - " And an active container \"01TESTLIFECYCLE0000000041\" with container ID \"ctr-b\"", - " When I run session cleanup for session \"session-001\"", - " Then the container state for \"01TESTLIFECYCLE0000000040\" should be \"stopped\"", - " And the container state for \"01TESTLIFECYCLE0000000041\" should be \"stopped\"" - ], - "rawOutput": "1 feature passed, 0 failed, 0 skipped\n26 scenarios passed, 0 failed, 0 skipped\n90 steps passed, 0 failed, 0 skipped\nTook 0min 0.026s\nFeature: Devcontainer Session Cleanup and CLI Commands\n As a CleverAgents developer\n I want session-scoped container cleanup and CLI stop/rebuild commands\n So that containers are cleaned up when sessions end and can be managed via CLI\n Scenario: Active containers stopped on session cleanup \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000040\" with container ID \"ctr-a\"\n And an active container \"01TESTLIFECYCLE0000000041\" with container ID \"ctr-b\"\n When I run session cleanup for session \"session-001\"\n Then the container state for \"01TESTLIFECYCLE0000000040\" should be \"stopped\"\n And the container state for \"01TESTLIFECYCLE0000000041\" should be \"stopped\"" - }, - { - "name": "Output Block 105", - "passed": true, - "output": [ - " Scenario: CleanupService stop_active_devcontainers is callable and returns list ", - " When I call CleanupService stop_active_devcontainers with no active containers", - " Then the cleanup result should be an empty list", - " And CleanupService should have a stop_active_devcontainers method" - ], - "rawOutput": " Scenario: CleanupService stop_active_devcontainers is callable and returns list \n When I call CleanupService stop_active_devcontainers with no active containers\n Then the cleanup result should be an empty list\n And CleanupService should have a stop_active_devcontainers method" - }, - { - "name": "Output Block 106", - "passed": true, - "output": [ - " Scenario: CleanupService stop_active_devcontainers calls handler cleanup ", - " When I call CleanupService stop_active_devcontainers with no active containers", - " Then the cleanup result should be an empty list" - ], - "rawOutput": " Scenario: CleanupService stop_active_devcontainers calls handler cleanup \n When I call CleanupService stop_active_devcontainers with no active containers\n Then the cleanup result should be an empty list" - }, - { - "name": "Output Block 107", - "passed": false, - "output": [ - " Scenario: Session cleanup handles stop failure gracefully ", - " Given a mock devcontainer CLI runner", - " And the runner configured to raise exception on stop", - " And an active container \"01TESTLIFECYCLE0000000130\" with container ID \"ctr-fail\"", - " When I run session cleanup for session \"session-err\"", - " Then the cleanup should return 0 stopped containers" - ], - "rawOutput": " Scenario: Session cleanup handles stop failure gracefully \n Given a mock devcontainer CLI runner\n And the runner configured to raise exception on stop\n And an active container \"01TESTLIFECYCLE0000000130\" with container ID \"ctr-fail\"\n When I run session cleanup for session \"session-err\"\n Then the cleanup should return 0 stopped containers" - }, - { - "name": "Output Block 108", - "passed": true, - "output": [ - " Scenario: CLI stop succeeds for active devcontainer-instance ", - " Given a mock resource service with devcontainer \"local/test-dc\" id \"01TESTLIFECYCLE0000000200\" at \"/workspace/project\"", - " And an active container \"01TESTLIFECYCLE0000000200\" with container ID \"ctr-cli-stop\"", - " When I invoke CLI resource stop \"local/test-dc\"", - "Feature: DevcontainerHandler missing protocol methods", - " As a developer using DevcontainerHandler", - " I want delete(), list_children(), diff(), and create_sandbox() to be implemented", - " So that the handler satisfies the full ResourceHandler protocol (issue #1242)", - " Scenario: dcproto delete file successfully from devcontainer ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns successful rm output", - " When dcproto I delete path \"src/old_file.py\" from the resource", - " Then dcproto the delete should succeed", - " And dcproto the delete message should contain \"src/old_file.py\"", - " And dcproto the subprocess should have been called with \"rm\" and \"src/old_file.py\"" - ], - "rawOutput": " Scenario: CLI stop succeeds for active devcontainer-instance \n Given a mock resource service with devcontainer \"local/test-dc\" id \"01TESTLIFECYCLE0000000200\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000200\" with container ID \"ctr-cli-stop\"\n When I invoke CLI resource stop \"local/test-dc\"\nFeature: DevcontainerHandler missing protocol methods\n As a developer using DevcontainerHandler\n I want delete(), list_children(), diff(), and create_sandbox() to be implemented\n So that the handler satisfies the full ResourceHandler protocol (issue #1242)\n Scenario: dcproto delete file successfully from devcontainer \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful rm output\n When dcproto I delete path \"src/old_file.py\" from the resource\n Then dcproto the delete should succeed\n And dcproto the delete message should contain \"src/old_file.py\"\n And dcproto the subprocess should have been called with \"rm\" and \"src/old_file.py\"" - }, - { - "name": "Output Block 109", - "passed": true, - "output": [ - " Scenario: dcproto delete with empty path targets workspace root ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns successful rm output", - " When dcproto I delete with empty path from the resource", - " Then dcproto the delete should succeed", - " And dcproto the subprocess should have been called with \"rm\" and \".\"" - ], - "rawOutput": " Scenario: dcproto delete with empty path targets workspace root \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful rm output\n When dcproto I delete with empty path from the resource\n Then dcproto the delete should succeed\n And dcproto the subprocess should have been called with \"rm\" and \".\"" - }, - { - "name": "Output Block 110", - "passed": false, - "output": [ - " Scenario: dcproto delete fails when container is stopped ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns failed rm output with stderr \"container not running\"", - " When dcproto I delete path \"file.txt\" from the resource", - " Then the CLI exit code should be 0", - " And the CLI output should contain \"Stopped\"", - " Then dcproto the delete should fail", - " And dcproto the delete failure message should contain \"container not running\"" - ], - "rawOutput": " Scenario: dcproto delete fails when container is stopped \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns failed rm output with stderr \"container not running\"\n When dcproto I delete path \"file.txt\" from the resource\n Then the CLI exit code should be 0\n And the CLI output should contain \"Stopped\"\n Then dcproto the delete should fail\n And dcproto the delete failure message should contain \"container not running\"" - }, - { - "name": "Output Block 111", - "passed": true, - "output": [ - " Scenario: CLI stop rejects non-devcontainer resource type ", - " Given a mock resource service with git-checkout \"local/my-repo\" id \"01TESTLIFECYCLE0000000201\"", - " When I invoke CLI resource stop \"local/my-repo\"" - ], - "rawOutput": " Scenario: CLI stop rejects non-devcontainer resource type \n Given a mock resource service with git-checkout \"local/my-repo\" id \"01TESTLIFECYCLE0000000201\"\n When I invoke CLI resource stop \"local/my-repo\"" - }, - { - "name": "Output Block 112", - "passed": false, - "output": [ - " Scenario: dcproto delete from resource with no location raises ValueError ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with no location", - " When dcproto I delete path \"any/file.txt\" from the resource", - " Then dcproto the delete should raise ValueError containing \"no location\"" - ], - "rawOutput": " Scenario: dcproto delete from resource with no location raises ValueError \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n When dcproto I delete path \"any/file.txt\" from the resource\n Then dcproto the delete should raise ValueError containing \"no location\"" - }, - { - "name": "Output Block 113", - "passed": true, - "output": [ - " Scenario: dcproto list_children returns sorted names from devcontainer ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns successful ls listing \"src\\ntests\\nREADME.md\"", - " When dcproto I list children of the resource", - " Then dcproto the children list should have 3 entries", - " And dcproto the children list should be \"README.md,src,tests\"" - ], - "rawOutput": " Scenario: dcproto list_children returns sorted names from devcontainer \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful ls listing \"src\\ntests\\nREADME.md\"\n When dcproto I list children of the resource\n Then dcproto the children list should have 3 entries\n And dcproto the children list should be \"README.md,src,tests\"" - }, - { - "name": "Output Block 114", - "passed": false, - "output": [ - " Scenario: dcproto list_children returns empty list when container is stopped ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns failed ls output", - " When dcproto I list children of the resource", - " Then dcproto the children list should have 0 entries" - ], - "rawOutput": " Scenario: dcproto list_children returns empty list when container is stopped \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns failed ls output\n When dcproto I list children of the resource\n Then dcproto the children list should have 0 entries" - }, - { - "name": "Output Block 115", - "passed": true, - "output": [ - " Scenario: dcproto list_children filters blank lines from ls output ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns successful ls listing \"alpha\\n\\n\\nbeta\\n\"", - " When dcproto I list children of the resource", - " Then dcproto the children list should have 2 entries", - " And dcproto the children list should be \"alpha,beta\"" - ], - "rawOutput": " Scenario: dcproto list_children filters blank lines from ls output \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful ls listing \"alpha\\n\\n\\nbeta\\n\"\n When dcproto I list children of the resource\n Then dcproto the children list should have 2 entries\n And dcproto the children list should be \"alpha,beta\"" - }, - { - "name": "Output Block 116", - "passed": false, - "output": [ - " Scenario: dcproto list_children from resource with no location raises ValueError ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with no location", - " When dcproto I list children of the resource", - " Then dcproto the list children should raise ValueError containing \"no location\"" - ], - "rawOutput": " Scenario: dcproto list_children from resource with no location raises ValueError \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n When dcproto I list children of the resource\n Then dcproto the list children should raise ValueError containing \"no location\"" - }, - { - "name": "Output Block 117", - "passed": true, - "output": [ - " Scenario: dcproto list_children uses devcontainer exec ls command ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto subprocess returns successful ls listing \"main.py\"", - " When dcproto I list children of the resource", - " Then dcproto the subprocess should have been called with \"ls\" and \"--workspace-folder\"" - ], - "rawOutput": " Scenario: dcproto list_children uses devcontainer exec ls command \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful ls listing \"main.py\"\n When dcproto I list children of the resource\n Then dcproto the subprocess should have been called with \"ls\" and \"--workspace-folder\"" - }, - { - "name": "Output Block 118", - "passed": true, - "output": [ - " Scenario: dcproto diff detects changes when hashes differ ", - " Given dcproto a devcontainer handler", - " Then the devcontainer CLI exit code should be non-zero", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And the CLI output should contain \"not a stoppable container type\"", - " And dcproto the container content hash is \"aabbccdd\"", - " And dcproto a temporary directory with a different file", - " When dcproto I diff the resource against the temporary directory", - " Then dcproto the diff should report has_changes true", - " And dcproto the diff files_changed should be 1" - ], - "rawOutput": " Scenario: dcproto diff detects changes when hashes differ \n Given dcproto a devcontainer handler\n Then the devcontainer CLI exit code should be non-zero\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And the CLI output should contain \"not a stoppable container type\"\n And dcproto the container content hash is \"aabbccdd\"\n And dcproto a temporary directory with a different file\n When dcproto I diff the resource against the temporary directory\n Then dcproto the diff should report has_changes true\n And dcproto the diff files_changed should be 1" - }, - { - "name": "Output Block 119", - "passed": true, - "output": [ - " Scenario: CLI rebuild succeeds for stopped devcontainer-instance ", - " Given a mock resource service with devcontainer \"local/test-dc-rb\" id \"01TESTLIFECYCLE0000000210\" at \"/workspace/project\"", - " And a stopped container \"01TESTLIFECYCLE0000000210\"", - " When I invoke CLI resource rebuild \"local/test-dc-rb\"" - ], - "rawOutput": " Scenario: CLI rebuild succeeds for stopped devcontainer-instance \n Given a mock resource service with devcontainer \"local/test-dc-rb\" id \"01TESTLIFECYCLE0000000210\" at \"/workspace/project\"\n And a stopped container \"01TESTLIFECYCLE0000000210\"\n When I invoke CLI resource rebuild \"local/test-dc-rb\"" - }, - { - "name": "Output Block 120", - "passed": true, - "output": [ - " Scenario: dcproto diff reports no changes when hashes match ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto the container content hash matches the other location", - " When dcproto I diff the resource against the same location", - " Then dcproto the diff should report has_changes false", - " And dcproto the diff files_changed should be 0", - " Then the CLI exit code should be 0", - " And the CLI output should contain \"Rebuilt\"" - ], - "rawOutput": " Scenario: dcproto diff reports no changes when hashes match \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container content hash matches the other location\n When dcproto I diff the resource against the same location\n Then dcproto the diff should report has_changes false\n And dcproto the diff files_changed should be 0\n Then the CLI exit code should be 0\n And the CLI output should contain \"Rebuilt\"" - }, - { - "name": "Output Block 121", - "passed": true, - "output": [ - " Scenario: dcproto diff reports no changes when both sides are absent ", - " Given dcproto a devcontainer handler" - ], - "rawOutput": " Scenario: dcproto diff reports no changes when both sides are absent \n Given dcproto a devcontainer handler" - }, - { - "name": "Output Block 122", - "passed": true, - "output": [ - " Scenario: CLI rebuild rejects resource with no location ", - " Given a mock resource service with devcontainer \"local/dc-no-loc\" id \"01TESTLIFECYCLE0000000211\" with no location", - " And dcproto a devcontainer-instance resource with location \"/nonexistent/path\"", - " And a stopped container \"01TESTLIFECYCLE0000000211\"", - " When dcproto I diff the resource against \"/another/nonexistent/path\"", - " When I invoke CLI resource rebuild \"local/dc-no-loc\"", - " Then dcproto the diff should report has_changes false" - ], - "rawOutput": " Scenario: CLI rebuild rejects resource with no location \n Given a mock resource service with devcontainer \"local/dc-no-loc\" id \"01TESTLIFECYCLE0000000211\" with no location\n And dcproto a devcontainer-instance resource with location \"/nonexistent/path\"\n And a stopped container \"01TESTLIFECYCLE0000000211\"\n When dcproto I diff the resource against \"/another/nonexistent/path\"\n When I invoke CLI resource rebuild \"local/dc-no-loc\"\n Then dcproto the diff should report has_changes false" - }, - { - "name": "Output Block 123", - "passed": false, - "output": [ - " Scenario: dcproto diff from resource with no location raises ValueError ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with no location", - " When dcproto I diff the resource against \"/some/path\"", - " Then the devcontainer CLI exit code should be non-zero", - " Then dcproto the diff should raise ValueError containing \"no location\"", - " And the CLI output should contain \"no location\"" - ], - "rawOutput": " Scenario: dcproto diff from resource with no location raises ValueError \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n When dcproto I diff the resource against \"/some/path\"\n Then the devcontainer CLI exit code should be non-zero\n Then dcproto the diff should raise ValueError containing \"no location\"\n And the CLI output should contain \"no location\"" - }, - { - "name": "Output Block 124", - "passed": true, - "output": [ - " Scenario: dcproto diff unified_diff is always empty string ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"" - ], - "rawOutput": " Scenario: dcproto diff unified_diff is always empty string \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"" - }, - { - "name": "Output Block 125", - "passed": true, - "output": [ - " Scenario: CLI rebuild rejects non-devcontainer resource type ", - " Given a mock resource service with git-checkout \"local/git-rb\" id \"01TESTLIFECYCLE0000000212\"", - " And dcproto the container content hash is \"aabbccdd\"", - " And dcproto a temporary directory with a different file", - " When I invoke CLI resource rebuild \"local/git-rb\"", - " When dcproto I diff the resource against the temporary directory", - " Then dcproto the diff unified_diff should be empty" - ], - "rawOutput": " Scenario: CLI rebuild rejects non-devcontainer resource type \n Given a mock resource service with git-checkout \"local/git-rb\" id \"01TESTLIFECYCLE0000000212\"\n And dcproto the container content hash is \"aabbccdd\"\n And dcproto a temporary directory with a different file\n When I invoke CLI resource rebuild \"local/git-rb\"\n When dcproto I diff the resource against the temporary directory\n Then dcproto the diff unified_diff should be empty" - }, - { - "name": "Output Block 126", - "passed": true, - "output": [ - " Scenario: dcproto create_sandbox delegates to base class for running container ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto the container is in RUNNING state", - " And dcproto a mock sandbox manager that returns a valid sandbox", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"rebuild requires devcontainer\"", - " When dcproto I create a sandbox for the resource with plan \"plan-001\"", - " Then dcproto the sandbox result should have strategy \"snapshot\"", - " And dcproto the sandbox result should have a sandbox path" - ], - "rawOutput": " Scenario: dcproto create_sandbox delegates to base class for running container \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container is in RUNNING state\n And dcproto a mock sandbox manager that returns a valid sandbox\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"rebuild requires devcontainer\"\n When dcproto I create a sandbox for the resource with plan \"plan-001\"\n Then dcproto the sandbox result should have strategy \"snapshot\"\n And dcproto the sandbox result should have a sandbox path" - }, - { - "name": "Output Block 127", - "passed": true, - "output": [ - " Scenario: CLI stop calls stop_container with correct resource_id ", - " Given a mock resource service with devcontainer \"local/test-dc-r7\" id \"01TESTLIFECYCLE0000000220\" at \"/workspace/project\"", - " And an active container \"01TESTLIFECYCLE0000000220\" with container ID \"ctr-r7\"", - " When I invoke CLI resource stop \"local/test-dc-r7\"" - ], - "rawOutput": " Scenario: CLI stop calls stop_container with correct resource_id \n Given a mock resource service with devcontainer \"local/test-dc-r7\" id \"01TESTLIFECYCLE0000000220\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000220\" with container ID \"ctr-r7\"\n When I invoke CLI resource stop \"local/test-dc-r7\"" - }, - { - "name": "Output Block 128", - "passed": true, - "output": [ - " Scenario: dcproto create_sandbox activates container when in DETECTED state ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto the container is in DETECTED state", - " And dcproto a mock sandbox manager that returns a valid sandbox", - " And dcproto activate_container is mocked to succeed", - " When dcproto I create a sandbox for the resource with plan \"plan-002\"", - " Then dcproto activate_container should have been called", - " Then the CLI exit code should be 0", - " And the CLI stop mock should have been called with \"01TESTLIFECYCLE0000000220\"" - ], - "rawOutput": " Scenario: dcproto create_sandbox activates container when in DETECTED state \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container is in DETECTED state\n And dcproto a mock sandbox manager that returns a valid sandbox\n And dcproto activate_container is mocked to succeed\n When dcproto I create a sandbox for the resource with plan \"plan-002\"\n Then dcproto activate_container should have been called\n Then the CLI exit code should be 0\n And the CLI stop mock should have been called with \"01TESTLIFECYCLE0000000220\"" - }, - { - "name": "Output Block 129", - "passed": true, - "output": [ - " Scenario: dcproto create_sandbox activates container when in STOPPED state ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with location \"/ws/project\"", - " And dcproto the container is in STOPPED state", - " And dcproto a mock sandbox manager that returns a valid sandbox", - " And dcproto activate_container is mocked to succeed", - " When dcproto I create a sandbox for the resource with plan \"plan-003\"" - ], - "rawOutput": " Scenario: dcproto create_sandbox activates container when in STOPPED state \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container is in STOPPED state\n And dcproto a mock sandbox manager that returns a valid sandbox\n And dcproto activate_container is mocked to succeed\n When dcproto I create a sandbox for the resource with plan \"plan-003\"" - }, - { - "name": "Output Block 130", - "passed": true, - "output": [ - " Scenario: CLI rebuild calls rebuild_container with correct args ", - " Given a mock resource service with devcontainer \"local/test-dc-r7rb\" id \"01TESTLIFECYCLE0000000221\" at \"/workspace/project\"", - " And a stopped container \"01TESTLIFECYCLE0000000221\"", - " Then dcproto activate_container should have been called", - " When I invoke CLI resource rebuild \"local/test-dc-r7rb\"" - ], - "rawOutput": " Scenario: CLI rebuild calls rebuild_container with correct args \n Given a mock resource service with devcontainer \"local/test-dc-r7rb\" id \"01TESTLIFECYCLE0000000221\" at \"/workspace/project\"\n And a stopped container \"01TESTLIFECYCLE0000000221\"\n Then dcproto activate_container should have been called\n When I invoke CLI resource rebuild \"local/test-dc-r7rb\"" - }, - { - "name": "Output Block 131", - "passed": false, - "output": [ - " Scenario: dcproto create_sandbox raises ValueError for resource with no location ", - " Given dcproto a devcontainer handler", - " And dcproto a devcontainer-instance resource with no location", - " And dcproto a mock sandbox manager that returns a valid sandbox", - " When dcproto I create a sandbox for the resource with plan \"plan-004\"", - " Then dcproto the create_sandbox should raise ValueError containing \"no location\"" - ], - "rawOutput": " Scenario: dcproto create_sandbox raises ValueError for resource with no location \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n And dcproto a mock sandbox manager that returns a valid sandbox\n When dcproto I create a sandbox for the resource with plan \"plan-004\"\n Then dcproto the create_sandbox should raise ValueError containing \"no location\"" - }, - { - "name": "Output Block 132", - "passed": false, - "output": [ - "1 feature passed, 0 failed, 0 skipped", - "18 scenarios passed, 0 failed, 0 skipped", - "102 steps passed, 0 failed, 0 skipped", - "Took 0min 0.028s", - " Then the CLI exit code should be 0", - " And the CLI rebuild mock should have been called with \"01TESTLIFECYCLE0000000221\" and \"/workspace/project\"" - ], - "rawOutput": "1 feature passed, 0 failed, 0 skipped\n18 scenarios passed, 0 failed, 0 skipped\n102 steps passed, 0 failed, 0 skipped\nTook 0min 0.028s\n Then the CLI exit code should be 0\n And the CLI rebuild mock should have been called with \"01TESTLIFECYCLE0000000221\" and \"/workspace/project\"" - }, - { - "name": "Output Block 133", - "passed": true, - "output": [ - " Scenario: DevcontainerHandler has expected class attributes and is instantiable ", - " Then DevcontainerHandler should have _default_strategy \"snapshot\"", - " And DevcontainerHandler should have _type_label \"devcontainer\"", - " And DevcontainerHandler should be instantiable" - ], - "rawOutput": " Scenario: DevcontainerHandler has expected class attributes and is instantiable \n Then DevcontainerHandler should have _default_strategy \"snapshot\"\n And DevcontainerHandler should have _type_label \"devcontainer\"\n And DevcontainerHandler should be instantiable" - }, - { - "name": "Output Block 134", - "passed": true, - "output": [ - " Scenario: DevcontainerHandler extends BaseResourceHandler and inherits resolve interface ", - " Then DevcontainerHandler should be a subclass of BaseResourceHandler", - " And DevcontainerHandler instance should have a resolve method" - ], - "rawOutput": " Scenario: DevcontainerHandler extends BaseResourceHandler and inherits resolve interface \n Then DevcontainerHandler should be a subclass of BaseResourceHandler\n And DevcontainerHandler instance should have a resolve method" - }, - { - "name": "Output Block 135", - "passed": true, - "output": [ - " Scenario: CLI stop rejects container not in running state ", - " Given a mock resource service with devcontainer \"local/dc-det\" id \"01TESTLIFECYCLE0000000230\" at \"/workspace/project\"", - " And a lifecycle tracker for resource \"01TESTLIFECYCLE0000000230\"", - " When I invoke CLI resource stop \"local/dc-det\"", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"Cannot stop\"" - ], - "rawOutput": " Scenario: CLI stop rejects container not in running state \n Given a mock resource service with devcontainer \"local/dc-det\" id \"01TESTLIFECYCLE0000000230\" at \"/workspace/project\"\n And a lifecycle tracker for resource \"01TESTLIFECYCLE0000000230\"\n When I invoke CLI resource stop \"local/dc-det\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Cannot stop\"" - }, - { - "name": "Output Block 136", - "passed": true, - "output": [ - " Scenario: CLI rebuild rejects container in running state ", - " Given a mock resource service with devcontainer \"local/dc-run\" id \"01TESTLIFECYCLE0000000231\" at \"/workspace/project\"", - " And an active container \"01TESTLIFECYCLE0000000231\" with container ID \"ctr-rb-state\"", - " When I invoke CLI resource rebuild \"local/dc-run\"", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"Cannot rebuild\"" - ], - "rawOutput": " Scenario: CLI rebuild rejects container in running state \n Given a mock resource service with devcontainer \"local/dc-run\" id \"01TESTLIFECYCLE0000000231\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000231\" with container ID \"ctr-rb-state\"\n When I invoke CLI resource rebuild \"local/dc-run\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Cannot rebuild\"" - }, - { - "name": "Output Block 137", - "passed": true, - "output": [ - " Scenario: Session cleanup returns list of stopped resource IDs ", - " Given a mock devcontainer CLI runner", - " And an active container \"01TESTLIFECYCLE0000000250\" with container ID \"ctr-r14a\"", - " And an active container \"01TESTLIFECYCLE0000000251\" with container ID \"ctr-r14b\"", - " When I run session cleanup for session \"session-r14\"", - " Then the cleanup stopped list should contain \"01TESTLIFECYCLE0000000250\"", - " And the cleanup stopped list should contain \"01TESTLIFECYCLE0000000251\"" - ], - "rawOutput": " Scenario: Session cleanup returns list of stopped resource IDs \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000250\" with container ID \"ctr-r14a\"\n And an active container \"01TESTLIFECYCLE0000000251\" with container ID \"ctr-r14b\"\n When I run session cleanup for session \"session-r14\"\n Then the cleanup stopped list should contain \"01TESTLIFECYCLE0000000250\"\n And the cleanup stopped list should contain \"01TESTLIFECYCLE0000000251\"" - }, - { - "name": "Output Block 138", - "passed": true, - "output": [ - " Scenario: CLI stop with --yes skips confirmation and calls stop_container ", - " Given a CLI-mockable running devcontainer resource \"test-dc-yes-stop\"", - " When I invoke CLI resource stop \"test-dc-yes-stop\"", - " Then the devcontainer CLI exit code should be 0", - " And the CLI stop mock should have been called once" - ], - "rawOutput": " Scenario: CLI stop with --yes skips confirmation and calls stop_container \n Given a CLI-mockable running devcontainer resource \"test-dc-yes-stop\"\n When I invoke CLI resource stop \"test-dc-yes-stop\"\n Then the devcontainer CLI exit code should be 0\n And the CLI stop mock should have been called once" - }, - { - "name": "Output Block 139", - "passed": true, - "output": [ - " Scenario: CLI rebuild with --yes skips confirmation and calls rebuild_container ", - " Given a CLI-mockable stopped devcontainer resource \"test-dc-yes-rebuild\"", - " When I invoke CLI resource rebuild \"test-dc-yes-rebuild\"", - " Then the devcontainer CLI exit code should be 0", - " And the CLI rebuild mock should have been called once" - ], - "rawOutput": " Scenario: CLI rebuild with --yes skips confirmation and calls rebuild_container \n Given a CLI-mockable stopped devcontainer resource \"test-dc-yes-rebuild\"\n When I invoke CLI resource rebuild \"test-dc-yes-rebuild\"\n Then the devcontainer CLI exit code should be 0\n And the CLI rebuild mock should have been called once" - }, - { - "name": "Output Block 140", - "passed": true, - "output": [ - " Scenario: CLI stop accepts container-instance type (issue #2588 fix) ", - " Given a mock resource service with container-instance \"local/ctr-stop\" id \"01TESTLIFECYCLE0000000370\" at \"/workspace/project\"", - " And an active container \"01TESTLIFECYCLE0000000370\" with container ID \"ctr-ci-stop\"", - " When I invoke CLI resource stop \"local/ctr-stop\"", - " Then the CLI exit code should be 0", - " And the CLI output should contain \"Stopped\"" - ], - "rawOutput": " Scenario: CLI stop accepts container-instance type (issue #2588 fix) \n Given a mock resource service with container-instance \"local/ctr-stop\" id \"01TESTLIFECYCLE0000000370\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000370\" with container ID \"ctr-ci-stop\"\n When I invoke CLI resource stop \"local/ctr-stop\"\n Then the CLI exit code should be 0\n And the CLI output should contain \"Stopped\"" - }, - { - "name": "Output Block 141", - "passed": false, - "output": [ - " Scenario: CLI stop handles NotFoundError from show_resource ", - " Given a mock resource service that raises NotFoundError for \"local/missing\"", - " When I invoke CLI resource stop \"local/missing\"", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"Resource not found\"" - ], - "rawOutput": " Scenario: CLI stop handles NotFoundError from show_resource \n Given a mock resource service that raises NotFoundError for \"local/missing\"\n When I invoke CLI resource stop \"local/missing\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Resource not found\"" - }, - { - "name": "Output Block 142", - "passed": false, - "output": [ - " Scenario: CLI rebuild handles NotFoundError from show_resource ", - " Given a mock resource service that raises NotFoundError for \"local/missing-rb\"", - " When I invoke CLI resource rebuild \"local/missing-rb\"", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"Resource not found\"" - ], - "rawOutput": " Scenario: CLI rebuild handles NotFoundError from show_resource \n Given a mock resource service that raises NotFoundError for \"local/missing-rb\"\n When I invoke CLI resource rebuild \"local/missing-rb\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Resource not found\"" - }, - { - "name": "Output Block 143", - "passed": false, - "output": [ - " Scenario: CLI stop handles RuntimeError from stop_container ", - " Given a mock resource service with devcontainer \"local/dc-rterr\" id \"01TESTLIFECYCLE0000000500\" at \"/workspace/project\"", - " And an active container \"01TESTLIFECYCLE0000000500\" with container ID \"ctr-rterr\"", - " And CLI stop_container mock that raises RuntimeError", - " When I invoke CLI resource stop with error mock \"local/dc-rterr\"", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"Stop failed\"" - ], - "rawOutput": " Scenario: CLI stop handles RuntimeError from stop_container \n Given a mock resource service with devcontainer \"local/dc-rterr\" id \"01TESTLIFECYCLE0000000500\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000500\" with container ID \"ctr-rterr\"\n And CLI stop_container mock that raises RuntimeError\n When I invoke CLI resource stop with error mock \"local/dc-rterr\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Stop failed\"" - }, - { - "name": "Output Block 144", - "passed": false, - "output": [ - " Scenario: CLI rebuild handles RuntimeError from rebuild_container ", - " Given a mock resource service with devcontainer \"local/dc-rberr\" id \"01TESTLIFECYCLE0000000501\" at \"/workspace/project\"", - " And a stopped container \"01TESTLIFECYCLE0000000501\"", - " And CLI rebuild_container mock that raises RuntimeError", - " When I invoke CLI resource rebuild with error mock \"local/dc-rberr\"", - " Then the devcontainer CLI exit code should be non-zero", - " And the CLI output should contain \"Rebuild failed\"" - ], - "rawOutput": " Scenario: CLI rebuild handles RuntimeError from rebuild_container \n Given a mock resource service with devcontainer \"local/dc-rberr\" id \"01TESTLIFECYCLE0000000501\" at \"/workspace/project\"\n And a stopped container \"01TESTLIFECYCLE0000000501\"\n And CLI rebuild_container mock that raises RuntimeError\n When I invoke CLI resource rebuild with error mock \"local/dc-rberr\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Rebuild failed\"" - }, - { - "name": "Output Block 145", - "passed": true, - "output": [ - " Scenario: Session cleanup only stops containers belonging to that session ", - " Given a mock devcontainer CLI runner", - " And a session-scoped active container \"01TESTLIFECYCLE0000000600\" with ID \"ctr-s1\" session \"sess-A\"", - " And a session-scoped active container \"01TESTLIFECYCLE0000000601\" with ID \"ctr-s2\" session \"sess-B\"", - " When I run session cleanup for session \"sess-A\"", - " Then the container state for \"01TESTLIFECYCLE0000000600\" should be \"stopped\"", - " And the container state for \"01TESTLIFECYCLE0000000601\" should be \"running\"" - ], - "rawOutput": " Scenario: Session cleanup only stops containers belonging to that session \n Given a mock devcontainer CLI runner\n And a session-scoped active container \"01TESTLIFECYCLE0000000600\" with ID \"ctr-s1\" session \"sess-A\"\n And a session-scoped active container \"01TESTLIFECYCLE0000000601\" with ID \"ctr-s2\" session \"sess-B\"\n When I run session cleanup for session \"sess-A\"\n Then the container state for \"01TESTLIFECYCLE0000000600\" should be \"stopped\"\n And the container state for \"01TESTLIFECYCLE0000000601\" should be \"running\"" - }, - { - "name": "Output Block 146", - "passed": true, - "output": [ - " Scenario: Session cleanup with no session_id stops all containers ", - " Given a mock devcontainer CLI runner", - " And an active container \"01TESTLIFECYCLE0000000610\" with container ID \"ctr-all1\"", - " And an active container \"01TESTLIFECYCLE0000000611\" with container ID \"ctr-all2\"", - " When I run session cleanup with no session filter", - " Then the container state for \"01TESTLIFECYCLE0000000610\" should be \"stopped\"", - " And the container state for \"01TESTLIFECYCLE0000000611\" should be \"stopped\"" - ], - "rawOutput": " Scenario: Session cleanup with no session_id stops all containers \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000610\" with container ID \"ctr-all1\"\n And an active container \"01TESTLIFECYCLE0000000611\" with container ID \"ctr-all2\"\n When I run session cleanup with no session filter\n Then the container state for \"01TESTLIFECYCLE0000000610\" should be \"stopped\"\n And the container state for \"01TESTLIFECYCLE0000000611\" should be \"stopped\"" - }, - { - "name": "Output Block 147", - "passed": true, - "output": [ - " Scenario: Session cleanup triggers terminal tracker eviction ", - " Given a mock devcontainer CLI runner", - " And 210 stopped container trackers in the registry", - " And an active container \"01TESTLIFECYCLE0000000650\" with container ID \"ctr-evict\"", - " When I run session cleanup for session \"session-evict\"", - " Then the container state for \"01TESTLIFECYCLE0000000650\" should be \"stopped\"", - " And the registry should have at most 200 terminal trackers" - ], - "rawOutput": " Scenario: Session cleanup triggers terminal tracker eviction \n Given a mock devcontainer CLI runner\n And 210 stopped container trackers in the registry\n And an active container \"01TESTLIFECYCLE0000000650\" with container ID \"ctr-evict\"\n When I run session cleanup for session \"session-evict\"\n Then the container state for \"01TESTLIFECYCLE0000000650\" should be \"stopped\"\n And the registry should have at most 200 terminal trackers" - }, - { - "name": "Output Block 148", - "passed": true, - "output": [ - " Scenario: list_active_containers_for_session returns only matching session ", - " Given a mock devcontainer CLI runner", - " And a session-scoped active container \"01TESTLIFECYCLE0000000700\" with ID \"ctr-ts3a\" session \"sess-X\"", - " And a session-scoped active container \"01TESTLIFECYCLE0000000701\" with ID \"ctr-ts3b\" session \"sess-Y\"", - " When I list active containers for session \"sess-X\"", - " Then the session container list should contain \"01TESTLIFECYCLE0000000700\"", - " And the session container list should not contain \"01TESTLIFECYCLE0000000701\"" - ], - "rawOutput": " Scenario: list_active_containers_for_session returns only matching session \n Given a mock devcontainer CLI runner\n And a session-scoped active container \"01TESTLIFECYCLE0000000700\" with ID \"ctr-ts3a\" session \"sess-X\"\n And a session-scoped active container \"01TESTLIFECYCLE0000000701\" with ID \"ctr-ts3b\" session \"sess-Y\"\n When I list active containers for session \"sess-X\"\n Then the session container list should contain \"01TESTLIFECYCLE0000000700\"\n And the session container list should not contain \"01TESTLIFECYCLE0000000701\"" - }, - { - "name": "Output Block 149", - "passed": true, - "output": [ - " Scenario: list_active_containers_for_session with empty session returns all ", - " Given a mock devcontainer CLI runner", - " And an active container \"01TESTLIFECYCLE0000000710\" with container ID \"ctr-ts3c\"", - " And an active container \"01TESTLIFECYCLE0000000711\" with container ID \"ctr-ts3d\"", - " When I list active containers for an empty session", - " Then the session container list should contain \"01TESTLIFECYCLE0000000710\"", - " And the session container list should contain \"01TESTLIFECYCLE0000000711\"" - ], - "rawOutput": " Scenario: list_active_containers_for_session with empty session returns all \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000710\" with container ID \"ctr-ts3c\"\n And an active container \"01TESTLIFECYCLE0000000711\" with container ID \"ctr-ts3d\"\n When I list active containers for an empty session\n Then the session container list should contain \"01TESTLIFECYCLE0000000710\"\n And the session container list should contain \"01TESTLIFECYCLE0000000711\"" - }, - { - "name": "Output Block 150", - "passed": true, - "output": [ - " Scenario: list_active_containers_for_session includes unscoped containers ", - " Given a mock devcontainer CLI runner", - " And an active container \"01TESTLIFECYCLE0000000720\" with container ID \"ctr-unscoped\"", - " And a session-scoped active container \"01TESTLIFECYCLE0000000721\" with ID \"ctr-scoped\" session \"sess-Z\"", - " When I list active containers for session \"sess-Z\"", - " Then the session container list should contain \"01TESTLIFECYCLE0000000720\"", - " And the session container list should contain \"01TESTLIFECYCLE0000000721\"" - ], - "rawOutput": " Scenario: list_active_containers_for_session includes unscoped containers \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000720\" with container ID \"ctr-unscoped\"\n And a session-scoped active container \"01TESTLIFECYCLE0000000721\" with ID \"ctr-scoped\" session \"sess-Z\"\n When I list active containers for session \"sess-Z\"\n Then the session container list should contain \"01TESTLIFECYCLE0000000720\"\n And the session container list should contain \"01TESTLIFECYCLE0000000721\"" - }, - { - "name": "Output Block 151", - "passed": true, - "output": [ - " Scenario: Session close cleans up containers even without session service ", - " Given a facade with no session service", - " And a session-scoped active container \"01TESTLIFECYCLE0000000630\" with no docker ID session \"sess-f4\"", - " When I close session \"sess-f4\" via the facade", - " Then the container state for \"01TESTLIFECYCLE0000000630\" should be \"stopped\"" - ], - "rawOutput": " Scenario: Session close cleans up containers even without session service \n Given a facade with no session service\n And a session-scoped active container \"01TESTLIFECYCLE0000000630\" with no docker ID session \"sess-f4\"\n When I close session \"sess-f4\" via the facade\n Then the container state for \"01TESTLIFECYCLE0000000630\" should be \"stopped\"" - }, - { - "name": "Output Block 152", - "passed": false, - "output": [ - "1 feature passed, 0 failed, 0 skipped", - "30 scenarios passed, 0 failed, 0 skipped", - "143 steps passed, 0 failed, 0 skipped", - "Took 0min 0.436s", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12", - "2026-04-13 07:00:42 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:42 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12", - "\u001b[1mIncluding unscoped container 01TESTLIFECYCLE0000000040 in session 'session-001' cleanup (container has no session_id set)\u001b[0m", - "\u001b[1mIncluding unscoped container 01TESTLIFECYCLE0000000041 in session 'session-001' cleanup (container has no session_id set)\u001b[0m", - "\u001b[1mContainer 01TESTLIFECYCLE0000000040: running -> stopping (manual stop)\u001b[0m", - "\u001b[1mContainer 01TESTLIFECYCLE0000000040: stopping -> stopped (container stopped)\u001b[0m", - "\u001b[1mStopped container 01TESTLIFECYCLE0000000040 (session=session-001)\u001b[0m", - "\u001b[1mContainer 01TESTLIFECYCLE0000000041: running -> stopping (manual stop)\u001b[0m", - "\u001b[1mContainer 01TESTLIFECYCLE0000000041: stopping -> stopped (container stopped)\u001b[0m", - "\u001b[1mStopped container 01TESTLIFECYCLE0000000041 (session=session-001)\u001b[0m", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12", - "\u001b[1mRegistered built-in resource type: fs-mount\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-checkout\u001b[0m", - "\u001b[1mRegistered built-in resource type: fs-directory\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-instance\u001b[0m", - "\u001b[1mRegistered built-in resource type: devcontainer-instance\u001b[0m", - "\u001b[1mRegistered built-in resource type: devcontainer-file\u001b[0m", - "\u001b[1mRegistered built-in resource type: git\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-remote\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-branch\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-tag\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-commit\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-tree\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-tree-entry\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-stash\u001b[0m", - "\u001b[1mRegistered built-in resource type: git-submodule\u001b[0m", - "\u001b[1mRegistered built-in resource type: fs-symlink\u001b[0m", - "\u001b[1mRegistered built-in resource type: fs-hardlink\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-account\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-region\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-network\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-subnet\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-security-group\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-load-balancer\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-compute-instance\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-object-store\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-block-storage\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-identity-principal\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-role\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-policy\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-log-group\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-alarm\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-queue\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-topic\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-container-repo\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-container-cluster\u001b[0m", - "\u001b[1mRegistered built-in resource type: cloud-container-service\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-account\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-region\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-vpc\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-subnet\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-igw\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-nat-gw\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-route-table\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-nacl\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-security-group\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-alb\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-nlb\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-target-group\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-listener\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ec2-instance\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ami\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-launch-template\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-asg\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-s3-bucket\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ebs-volume\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-efs-filesystem\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-iam-user\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-iam-role\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-iam-policy\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-iam-instance-profile\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-cloudwatch-log-group\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-cloudwatch-alarm\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-cloudwatch-metric\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-eventbridge-bus\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-eventbridge-rule\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-eventbridge-target\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-sqs-queue\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-sns-topic\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-sns-subscription\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ecr-repo\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ecs-cluster\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ecs-service\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-ecs-task-def\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-eks-cluster\u001b[0m", - "\u001b[1mRegistered built-in resource type: aws-eks-nodegroup\u001b[0m", - "\u001b[1mRegistered built-in resource type: gcp\u001b[0m", - "\u001b[1mRegistered built-in resource type: azure\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-runtime\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-image\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-mount\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-exec-env\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-port\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-volume\u001b[0m", - "\u001b[1mRegistered built-in resource type: container-network\u001b[0m", - "\u001b[1mRegistered built-in resource type: postgres\u001b[0m", - "\u001b[1mRegistered built-in resource type: mysql\u001b[0m", - "\u001b[1mRegistered built-in resource type: sqlite\u001b[0m", - "\u001b[1mRegistered built-in resource type: duckdb\u001b[0m", - "\u001b[1mRegistered built-in resource type: file\u001b[0m", - "\u001b[1mRegistered built-in resource type: directory\u001b[0m", - "\u001b[1mRegistered built-in resource type: commit\u001b[0m", - "\u001b[1mRegistered built-in resource type: branch\u001b[0m", - "\u001b[1mRegistered built-in resource type: tag\u001b[0m", - "\u001b[1mRegistered built-in resource type: tree\u001b[0m", - "\u001b[1mRegistered built-in resource type: remote\u001b[0m", - "\u001b[1mRegistered built-in resource type: submodule\u001b[0m", - "\u001b[1mRegistered built-in resource type: symlink\u001b[0m", - "\u001b[1mRegistered built-in resource type: executable\u001b[0m", - "\u001b[1mRegistered built-in resource type: lsp-server\u001b[0m", - "\u001b[1mRegistered built-in resource type: lsp-workspace\u001b[0m", - "\u001b[1mRegistered built-in resource type: lsp-document\u001b[0m", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED", - "2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12" - ], - "rawOutput": "1 feature passed, 0 failed, 0 skipped\n30 scenarios passed, 0 failed, 0 skipped\n143 steps passed, 0 failed, 0 skipped\nTook 0min 0.436s\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n\u001b[1mIncluding unscoped container 01TESTLIFECYCLE0000000040 in session 'session-001' cleanup (container has no session_id set)\u001b[0m\n\u001b[1mIncluding unscoped container 01TESTLIFECYCLE0000000041 in session 'session-001' cleanup (container has no session_id set)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000040: running -> stopping (manual stop)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000040: stopping -> stopped (container stopped)\u001b[0m\n\u001b[1mStopped container 01TESTLIFECYCLE0000000040 (session=session-001)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000041: running -> stopping (manual stop)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000041: stopping -> stopped (container stopped)\u001b[0m\n\u001b[1mStopped container 01TESTLIFECYCLE0000000041 (session=session-001)\u001b[0m\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n\u001b[1mRegistered built-in resource type: fs-mount\u001b[0m\n\u001b[1mRegistered built-in resource type: git-checkout\u001b[0m\n\u001b[1mRegistered built-in resource type: fs-directory\u001b[0m\n\u001b[1mRegistered built-in resource type: container-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: devcontainer-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: devcontainer-file\u001b[0m\n\u001b[1mRegistered built-in resource type: git\u001b[0m\n\u001b[1mRegistered built-in resource type: git-remote\u001b[0m\n\u001b[1mRegistered built-in resource type: git-branch\u001b[0m\n\u001b[1mRegistered built-in resource type: git-tag\u001b[0m\n\u001b[1mRegistered built-in resource type: git-commit\u001b[0m\n\u001b[1mRegistered built-in resource type: git-tree\u001b[0m\n\u001b[1mRegistered built-in resource type: git-tree-entry\u001b[0m\n\u001b[1mRegistered built-in resource type: git-stash\u001b[0m\n\u001b[1mRegistered built-in resource type: git-submodule\u001b[0m\n\u001b[1mRegistered built-in resource type: fs-symlink\u001b[0m\n\u001b[1mRegistered built-in resource type: fs-hardlink\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-account\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-region\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-network\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-subnet\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-security-group\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-load-balancer\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-compute-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-object-store\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-block-storage\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-identity-principal\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-role\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-policy\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-log-group\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-alarm\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-queue\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-topic\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-container-repo\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-container-cluster\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-container-service\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-account\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-region\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-vpc\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-subnet\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-igw\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-nat-gw\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-route-table\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-nacl\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-security-group\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-alb\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-nlb\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-target-group\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-listener\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ec2-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ami\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-launch-template\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-asg\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-s3-bucket\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ebs-volume\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-efs-filesystem\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-user\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-role\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-policy\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-instance-profile\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-cloudwatch-log-group\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-cloudwatch-alarm\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-cloudwatch-metric\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eventbridge-bus\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eventbridge-rule\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eventbridge-target\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-sqs-queue\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-sns-topic\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-sns-subscription\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecr-repo\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecs-cluster\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecs-service\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecs-task-def\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eks-cluster\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eks-nodegroup\u001b[0m\n\u001b[1mRegistered built-in resource type: gcp\u001b[0m\n\u001b[1mRegistered built-in resource type: azure\u001b[0m\n\u001b[1mRegistered built-in resource type: container-runtime\u001b[0m\n\u001b[1mRegistered built-in resource type: container-image\u001b[0m\n\u001b[1mRegistered built-in resource type: container-mount\u001b[0m\n\u001b[1mRegistered built-in resource type: container-exec-env\u001b[0m\n\u001b[1mRegistered built-in resource type: container-port\u001b[0m\n\u001b[1mRegistered built-in resource type: container-volume\u001b[0m\n\u001b[1mRegistered built-in resource type: container-network\u001b[0m\n\u001b[1mRegistered built-in resource type: postgres\u001b[0m\n\u001b[1mRegistered built-in resource type: mysql\u001b[0m\n\u001b[1mRegistered built-in resource type: sqlite\u001b[0m\n\u001b[1mRegistered built-in resource type: duckdb\u001b[0m\n\u001b[1mRegistered built-in resource type: file\u001b[0m\n\u001b[1mRegistered built-in resource type: directory\u001b[0m\n\u001b[1mRegistered built-in resource type: commit\u001b[0m\n\u001b[1mRegistered built-in resource type: branch\u001b[0m\n\u001b[1mRegistered built-in resource type: tag\u001b[0m\n\u001b[1mRegistered built-in resource type: tree\u001b[0m\n\u001b[1mRegistered built-in resource type: remote\u001b[0m\n\u001b[1mRegistered built-in resource type: submodule\u001b[0m\n\u001b[1mRegistered built-in resource type: symlink\u001b[0m\n\u001b[1mRegistered built-in resource type: executable\u001b[0m\n\u001b[1mRegistered built-in resource type: lsp-server\u001b[0m\n\u001b[1mRegistered built-in resource type: lsp-workspace\u001b[0m\n\u001b[1mRegistered built-in resource type: lsp-document\u001b[0m\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12" - }, - { - "name": "Output Block 153", - "passed": false, - "output": [ - "Overall summary:", - "6 features passed, 1 failed, 0 errored, 0 skipped", - "144 scenarios passed, 1 failed, 0 errored, 0 skipped", - "553 steps passed, 1 failed, 0 errored, 0 skipped", - "Took 2.366s", - "Wall time: 2m 47.786s" - ], - "rawOutput": "Overall summary:\n6 features passed, 1 failed, 0 errored, 0 skipped\n144 scenarios passed, 1 failed, 0 errored, 0 skipped\n553 steps passed, 1 failed, 0 errored, 0 skipped\nTook 2.366s\nWall time: 2m 47.786s" - }, - { - "name": "nox > Running session unit_tests-3.13", - "passed": false, - "output": [ - "nox > Running session unit_tests-3.13", - "nox > Reusing existing virtual environment at .nox/unit_tests-3-13.", - "nox > uv pip install -e '.[tests]'", - "nox > uv pip install setuptools wheel", - "nox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess", - "nox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db", - "nox > python -m compileall -q features/", - "nox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature", - "nox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1", - "nox > Session unit_tests-3.13 failed." - ], - "rawOutput": "nox > Running session unit_tests-3.13\nnox > Reusing existing virtual environment at .nox/unit_tests-3-13.\nnox > uv pip install -e '.[tests]'\nnox > uv pip install setuptools wheel\nnox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess\nnox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db\nnox > python -m compileall -q features/\nnox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature\nnox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1\nnox > Session unit_tests-3.13 failed." - }, - { - "name": "Error Output", - "passed": false, - "output": [ - "nox > Running session unit_tests-3.13", - "nox > Reusing existing virtual environment at .nox/unit_tests-3-13.", - "nox > uv pip install -e '.[tests]'", - "nox > uv pip install setuptools wheel", - "nox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess", - "nox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db", - "nox > python -m compileall -q features/", - "nox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature", - "nox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1", - "nox > Session unit_tests-3.13 failed.", - "" - ], - "rawOutput": "nox > Running session unit_tests-3.13\nnox > Reusing existing virtual environment at .nox/unit_tests-3-13.\nnox > uv pip install -e '.[tests]'\nnox > uv pip install setuptools wheel\nnox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess\nnox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db\nnox > python -m compileall -q features/\nnox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature\nnox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1\nnox > Session unit_tests-3.13 failed.\n" - } - ], - "summary": { - "total": 155, - "passed": 107, - "failed": 48 - }, - "rawOutput": "@devcontainer-sandbox\nFeature: devcontainer-instance uses snapshot sandbox strategy\n As a CleverAgents developer\n I want devcontainer-instance resources to use the snapshot sandbox strategy\n So that plan execution inside containers is safely isolated\n Scenario: DevcontainerHandler default strategy is snapshot \n When I inspect DevcontainerHandler class attributes\n Then the DevcontainerHandler _default_strategy should be \"snapshot\"\n\n Scenario: devcontainer-instance resource type has snapshot sandbox strategy \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec sandbox_strategy should be \"snapshot\"\n\n Scenario: devcontainer-instance child_types includes container-mount \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"container-mount\"\n\n Scenario: devcontainer-instance child_types includes container-exec-env \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"container-exec-env\"\n\n Scenario: devcontainer-instance child_types includes container-port \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"container-port\"\n\n Scenario: devcontainer-instance child_types includes devcontainer-file \n When I look up the \"devcontainer-instance\" resource type spec\n Then the spec child_types should contain \"devcontainer-file\"\n\n Scenario: ContainerLifecycleTracker default state is discovered \n When I create a new ContainerLifecycleTracker for resource \"01SANDBOX0000000000000001\"\n Then the tracker initial state should be \"discovered\"\n\n Scenario: ContainerLifecycleState has discovered value \n When I inspect ContainerLifecycleState enum values\n Then the lifecycle enum values should contain \"discovered\"\n And the lifecycle enum values should not contain \"detected\"\n\n Scenario: devcontainer-instance in BUILTIN_TYPES has snapshot strategy \n When I look up \"devcontainer-instance\" in BUILTIN_TYPES\n Then the BUILTIN_TYPES entry sandbox_strategy should be \"snapshot\"\n\n Scenario: devcontainer-instance in BUILTIN_TYPES has correct child_types \n When I look up \"devcontainer-instance\" in BUILTIN_TYPES\n Then the BUILTIN_TYPES entry child_types should include \"container-mount\"\n And the BUILTIN_TYPES entry child_types should include \"container-exec-env\"\n And the BUILTIN_TYPES entry child_types should include \"container-port\"\n\n1 feature passed, 0 failed, 0 skipped\n10 scenarios passed, 0 failed, 0 skipped\n23 steps passed, 0 failed, 0 skipped\nTook 0min 0.006s\nFeature: Devcontainer Lifecycle State Model\n As a CleverAgents developer\n I want the container lifecycle state model to enforce valid transitions\n So that containers follow a predictable state machine\n Scenario: ContainerLifecycleState has all required values \n When I inspect ContainerLifecycleState enum values\n Then the lifecycle enum should contain \"discovered\"\n And the lifecycle enum should contain \"building\"\n And the lifecycle enum should contain \"running\"\n And the lifecycle enum should contain \"stopping\"\n And the lifecycle enum should contain \"stopped\"\n And the lifecycle enum should contain \"failed\"\n\n Scenario: Valid transitions are accepted \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000001\"\n When I transition from \"discovered\" to \"building\"\n Then the transition should succeed\n And the tracker state should be \"building\"\n\n Scenario: Active transition after starting \n Given a lifecycle tracker in \"building\" state for resource \"01TESTLIFECYCLE0000000002\"\n When I transition from \"building\" to \"running\"\n Then the transition should succeed\n And the tracker state should be \"running\"\n\n Scenario: Invalid transition is rejected \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000003\"\n When I attempt to transition from \"discovered\" to \"running\"\n Then the transition should raise ValueError\n\n Scenario: Stopping to error transition is valid \n Given a lifecycle tracker in \"stopping\" state for resource \"01TESTLIFECYCLE0000000004\"\n When I transition from \"stopping\" to \"failed\"\n Then the transition should succeed\n And the tracker state should be \"failed\"\n\n Scenario: Error to starting transition is valid for retry \n Given a lifecycle tracker in \"failed\" state for resource \"01TESTLIFECYCLE0000000005\"\n When I transition from \"failed\" to \"building\"\n Then the transition should succeed\n And the tracker state should be \"building\"\n\n Scenario: Stopped to starting transition is valid for rebuild \n Given a lifecycle tracker in \"stopped\" state for resource \"01TESTLIFECYCLE0000000006\"\n When I transition from \"stopped\" to \"building\"\n Then the transition should succeed\n\n Scenario: Transition history is recorded \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000007\"\n When I transition from \"discovered\" to \"building\"\n Then the tracker should have 1 transition in history\n\n Scenario: Lifecycle tracker persists state across calls \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000060\"\n When I transition from \"discovered\" to \"building\"\n And I retrieve the tracker for \"01TESTLIFECYCLE0000000060\"\n Then the retrieved tracker state should be \"building\"\n\n Scenario: List active containers returns only active ones \n Given a mock devcontainer CLI runner\n And the runner configured for successful activation\n And an active container \"01TESTLIFECYCLE0000000070\" with container ID \"ctr-x\"\n And a lifecycle tracker for resource \"01TESTLIFECYCLE0000000071\"\n When I list active containers\n Then the active list should contain \"01TESTLIFECYCLE0000000070\"\n And the active list should not contain \"01TESTLIFECYCLE0000000071\"\n\n Scenario: Parse valid devcontainer up JSON output \n When I parse devcontainer up output with containerId \"abcdef123456\" and workspace \"/ws\"\n Then the parsed container ID should be \"abcdef123456\"\n And the parsed workspace path should be \"/ws\"\n\n Scenario: Parse invalid devcontainer up JSON output gracefully \n When I parse devcontainer up output with invalid JSON\n Then the parsed container ID should be None\n And the parsed workspace path should be None\n\n Scenario: validate_transition rejects wrong types \n When I call validate_transition with non-enum arguments\n Then it should raise TypeError\n\n Scenario: validate_transition rejects wrong to_state type \n When I call validate_transition with non-enum to_state\n Then it should raise TypeError\n\n Scenario: transition_state rejects wrong tracker type \n When I call transition_state with non-tracker argument\n Then it should raise TypeError\n\n Scenario: transition_state rejects wrong to_state type \n When I call transition_state with non-enum to_state argument\n Then it should raise TypeError\nFeature: agents resource list shows devcontainer lifecycle state column\n As a CleverAgents user\n I want the resource list to show the lifecycle state for devcontainer-instance resources\n So that I can see whether a devcontainer is discovered, running, stopped, or failed\n Feature: agents resource list shows devcontainer lifecycle state column \n\n Scenario: resource list shows \"Status\" column header \n Given a fresh in-memory resource registry\n\n Scenario: get_lifecycle_tracker rejects empty resource_id \n When I attempt to get tracker with empty resource_id\n Then the get tracker should raise ValueError\n\n Scenario: set_lifecycle_tracker rejects wrong type \n When I attempt to set tracker with wrong type\n Then the set tracker should raise TypeError\n\n Scenario: Invalid transition running to building is rejected \n Given a lifecycle tracker in \"running\" state for resource \"01TESTLIFECYCLE0000000240\"\n When I attempt to transition from \"running\" to \"building\"\n Then the transition should raise ValueError\n\n Scenario: Invalid transition stopped to running is rejected \n Given a lifecycle tracker in \"stopped\" state for resource \"01TESTLIFECYCLE0000000241\"\n When I attempt to transition from \"stopped\" to \"running\"\n Then the transition should raise ValueError\n\n Scenario: Invalid transition building to stopped is rejected \n Given a lifecycle tracker in \"building\" state for resource \"01TESTLIFECYCLE0000000242\"\n When I attempt to transition from \"building\" to \"stopped\"\n Then the transition should raise ValueError\n\n Scenario: Invalid transition failed to running is rejected \n Given a lifecycle tracker in \"failed\" state for resource \"01TESTLIFECYCLE0000000243\"\n When I attempt to transition from \"failed\" to \"running\"\n Then the transition should raise ValueError\n\n Scenario: Invalid transition discovered to stopping is rejected \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000244\"\n When I attempt to transition from \"discovered\" to \"stopping\"\n Then the transition should raise ValueError\n\n Scenario: Invalid transition building to discovered is rejected \n Given a lifecycle tracker in \"building\" state for resource \"01TESTLIFECYCLE0000000245\"\n When I attempt to transition from \"building\" to \"discovered\"\n Then the transition should raise ValueError\n\n Scenario: Parse devcontainer up output with log lines before JSON \n When I parse devcontainer up output with log lines before JSON\n Then the parsed container ID should be \"aabbccddee0099887766\"\n And the parsed workspace path should be \"/workspaces/multi\"\n\n Scenario: Transition history is capped at 100 entries \n Given a lifecycle tracker for resource \"01TESTLIFECYCLE0000000300\"\n When I perform 105 transitions cycling through valid states\n Then the tracker should have at most 100 transitions\n\n Scenario: Invalid container ID format is rejected during parsing \n When I parse devcontainer up output with invalid container ID \"not-a-hex-id!\"\n Then the parsed container ID should be empty\n And built-in types are bootstrapped\n\n Scenario: Parse devcontainer up output with relative workspace path \n When I parse devcontainer up output with relative workspace \"relative/ws\"\n Then the parsed container ID should be \"aabbccddee0011223344\"\n Given a devcontainer-instance resource is registered\n And the parsed workspace path should be None\n When I run resource list with all flag\n\n Scenario: Terminal tracker eviction removes oldest stopped trackers \n Given 210 stopped container trackers in the registry\n When I run terminal tracker eviction\n Then the registry should have at most 200 terminal trackers\n\n Scenario: evict_terminal_trackers returns 0 when below threshold \n Given 50 stopped container trackers in the registry\n When I run terminal tracker eviction\n Then the eviction count should be 0\n\n Scenario: get_lifecycle_tracker auto-creates tracker for new resource \n When I get tracker for new resource \"01TESTLIFECYCLE0000000730\"\n Then the auto-created tracker state should be \"discovered\"\n And the auto-created tracker resource_id should be \"01TESTLIFECYCLE0000000730\"\n Then the resource output should contain \"Status\"\n\n Scenario: clear_lifecycle_registry stops health check threads \n Given a mock devcontainer CLI runner\n And the runner configured for successful health check\n And an active container \"01TESTLIFECYCLE0000000740\" with container ID \"ctr-clr\"\n\n Scenario: resource list shows \"discovered (not built)\" for a new devcontainer-instance \n Given a fresh in-memory resource registry\n And a running health check for \"01TESTLIFECYCLE0000000740\"\n When I clear the lifecycle registry\n Then the registry should be empty\n And the health check for \"01TESTLIFECYCLE0000000740\" should be unregistered\n\n1 feature passed, 0 failed, 0 skipped\n32 scenarios passed, 0 failed, 0 skipped\n106 steps passed, 0 failed, 0 skipped\nTook 0min 0.037s\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n When I run resource list with all flag\n Then the resource output should contain \"discovered (not built)\"\n\n Scenario: resource list shows \"running\" state for a running devcontainer \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"running\"\n When I run resource list with all flag\n Then the resource output should contain \"running\"\n\n Scenario: resource list shows \"stopped\" state for a stopped devcontainer \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"stopped\"\n When I run resource list with all flag\n Then the resource output should contain \"stopped\"\n\n Scenario: resource list shows \"failed\" state for a failed devcontainer \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"failed\"\n When I run resource list with all flag\n Then the resource output should contain \"failed\"\n\n Scenario: resource list shows empty state for non-container resources \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given I run resource add \"git-checkout\" \"local/my-repo\" with path \"/tmp/repo\"\n When I run resource list\n Then the resource output should contain \"local/my-repo\"\n And the resource output should contain \"git-checkout\"\n\n Scenario: resource list shows warning banner when devcontainer is in detected state \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n When I run resource list with all flag\n Then the resource output should contain \"Devcontainer detected\"\n ASSERT FAILED: Expected 'Devcontainer detected' in output, got:\n Resources (1 total) \n ┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n ┃ ID ┃ Name ┃ Type ┃ Status ┃ Kind ┃ Location ┃ Description ┃\n ┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n │ 01KP2TDV4GAR... │ (unnamed) │ devcontainer-instance │ discovered (not built) │ physical │ /tmp/test-project │ Test devcontainer │\n └─────────────────┴───────────┴───────────────────────┴────────────────────────┴──────────┴───────────────────┴───────────────────┘\n\n\n Scenario: resource list does not show warning banner when devcontainer is running \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n And the devcontainer lifecycle state is \"running\"\n When I run resource list with all flag\n Then the resource output should not contain \"Devcontainer detected\"\n\n @tdd_issue @tdd_issue_4263 @tdd_expected_fail\n Scenario: resource list JSON output includes lifecycle_state for devcontainer-instance \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a devcontainer-instance resource is registered\n When I run resource list with all flag and format \"json\"\n Then the resource output should be valid JSON\n And the resource JSON output should contain key \"lifecycle_state\"\n ASSERT FAILED: Key 'lifecycle_state' not found in JSON output\n\n\n Scenario: resource list JSON output has null lifecycle_state for non-container resources \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given I run resource add \"git-checkout\" \"local/my-repo\" with path \"/tmp/repo\"\n When I run resource list with format \"json\"\n Then the resource output should be valid JSON\n And the resource JSON lifecycle_state should be null for non-container resources\n\n Scenario: resource list shows lifecycle state for container-instance resources \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\n Given a container-instance resource is registered\n When I run resource list with all flag\n Then the resource output should contain \"Status\"\n And the resource output should contain \"discovered (not built)\"\n\n Scenario: resource list succeeds gracefully when lifecycle tracker raises an error \n Given a fresh in-memory resource registry\n And built-in types are bootstrapped\nFeature: Devcontainer Resource Handler\n As a CleverAgents developer\n I want devcontainer resources to be auto-discovered and manually registered\n So that devcontainer environments integrate into the resource model Given a devcontainer-instance resource is registered\n\n Scenario: Register devcontainer-instance manually \n Given a temporary directory with a valid devcontainer.json\n When I create a devcontainer-instance resource at that path\n Then And the resource should have type \"the lifecycle tracker raises an error for the resourcedevcontainer-instance\"\n\n And the resource should have a non-empty resource_id\n When I run resource list with all flag\n Then the resource list command should succeed\n\n Scenario: Register container-instance manually \n When I create a container-instance resource with image \"ubuntu:latest\"\n Then the container resource should have type \"container-instance\"\n And the resource output should contain \"devcontainer-instance\"\n\n\nFailing scenarios:\n features/resource_list_lifecycle_state.feature:44 resource list shows warning banner when devcontainer is in detected state\n\n0 features passed, 1 failed, 0 skipped\n11 scenarios passed, 1 failed, 0 skipped\n69 steps passed, 1 failed, 0 skipped\nTook 0min 1.827s\n\n Scenario: Auto-discover devcontainer from git-checkout resource \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n And the discovered config path should end with \"devcontainer.json\"\n\n Scenario: Auto-discover root devcontainer.json from git-checkout \n Given a temporary directory simulating a git checkout\n And the directory has a root .devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n\n Scenario: Auto-discover both devcontainer locations \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file\n And the directory has a root .devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 2 results\n\n Scenario: Auto-discover devcontainer from fs-directory resource \n Given a temporary directory simulating a filesystem mount\n And the directory has a .devcontainer/devcontainer.json file\n When I run devcontainer discovery on the directory as \"fs-directory\"\n Then discovery should return 1 result\n\n Scenario: No discovery for non-trigger resource types \n Given a temporary directory simulating a filesystem mount\n And the directory has a .devcontainer/devcontainer.json file\n When I run devcontainer discovery on the directory as \"fs-file\"\n Then discovery should return 0 results\n\n Scenario: Skip invalid JSON in devcontainer.json \n Given a temporary directory with an invalid devcontainer.json\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results\n\n Scenario: Skip non-object JSON in devcontainer.json \n Given a temporary directory with a non-object devcontainer.json\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results\n\n Scenario: Handle missing devcontainer directory gracefully \n Given a temporary directory with no devcontainer configuration\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results\n@clone-into\nFeature: container-instance --clone-into argument\n As a CleverAgents user\n I want to clone a git repository into a running container\n So that I can work with the repository inside the container environment\n Scenario: Devcontainer types appear in resource type list \n Given the built-in resource type registry\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.1 \n When I validate clone-into URL \"https://github.com/org/repo.git\"\n When I list all built-in type names\n Then the clone-into URL should be valid\n Then the type list should contain \"devcontainer-instance\"\n And the type list should contain \"devcontainer-file\"\n And the type list should contain \"container-instance\"\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.2 \n When I validate clone-into URL \"http://internal.example.com/repo.git\"\n Then the clone-into URL should be valid\n\n Scenario: DevcontainerHandler satisfies ResourceHandler protocol \n When I instantiate DevcontainerHandler\n Then it should satisfy the ResourceHandler protocol\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.3 \n When I validate clone-into URL \"git@github.com:org/repo.git\"\n Then the clone-into URL should be valid\n\n Scenario: DevcontainerHandler has correct default strategy \n When I instantiate DevcontainerHandler\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.4 \n When I validate clone-into URL \"ssh://git@bitbucket.org/org/repo.git\"\n Then the clone-into URL should be valid\n Then its default strategy should be \"snapshot\"\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.5 \n When I validate clone-into URL \"git://github.com/org/repo.git\"\n\n Scenario: DevcontainerHandler has correct type label \n When I instantiate DevcontainerHandler\n Then the clone-into URL should be valid\n Then its type label should be \"devcontainer\"\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.6 \n When I validate clone-into URL \"/local/path/to/repo\"\n Then the clone-into URL should be valid\n\n Scenario: Discovery result requires valid config_path \n When I create a discovery result with valid parameters\n Then the result should have a config_path attribute\n\n Scenario Outline: validate_clone_into_url accepts valid git URLs -- @1.7 \n When I validate clone-into URL \"./relative/repo\"\n Then the clone-into URL should be valid\n\n Scenario: Discovery result rejects empty parent_location \n When I create a discovery result with empty parent_location\n\n Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.1 \n When I validate clone-into URL \"not-a-url\"\n Then it should raise a ValueError\n Then the clone-into URL should be invalid\n\n Scenario Outline: validate_clone_into_url rejects invalid URLs -- @1.2 \n When I validate clone-into URL \"ftp://example.com\"\n\n Scenario: Auto-discover named devcontainer configuration \n Given a temporary directory simulating a git checkout\n Then the clone-into URL should be invalid\n And the directory has a named devcontainer configuration \"api\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n And the first result should have config name \"api\"\n\n Scenario: clone_repo_into_container rejects empty container_id \n When I call clone_repo_into_container with empty container_id\n Then it should raise ValueError mentioning \"container_id\"\n\n Scenario: Auto-discover multiple named devcontainer configurations \n Given a temporary directory simulating a git checkout\n And the directory has a named devcontainer configuration \"api\"\n\n Scenario: clone_repo_into_container rejects empty repo_url \n When I call clone_repo_into_container with empty repo_url\n And the directory has a named devcontainer configuration \"frontend\"\n Then it should raise ValueError mentioning \"repo_url\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 2 results\n And the result config names should include \"api\"\n\n Scenario: clone_repo_into_container succeeds when docker exec returns 0 \n Given a mock docker exec that succeeds for clone\n And the result config names should include \"frontend\"\n When I clone \"https://github.com/org/repo.git\" into container \"abc123def456\"\n Then the clone should succeed\n And the clone target should be \"/workspace\"\n\n Scenario: Auto-discover mixed root and named devcontainer configurations \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file\n\n Scenario: clone_repo_into_container uses custom target directory \n Given a mock docker exec that succeeds for clone\n And the directory has a named devcontainer configuration \"api\"\n When I clone repo \"https://github.com/org/repo.git\" into container \"abc123def456\" with target \"/custom/dir\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then the clone should succeed\n And the clone target should be \"/custom/dir\"\n Then discovery should return 2 results\n\n Scenario: Root devcontainer.json has no config name \n Given a temporary directory simulating a git checkout\n And the directory has a .devcontainer/devcontainer.json file\n\n Scenario: clone_repo_into_container raises CloneIntoError when docker exec fails \n Given a mock docker exec that fails for clone with stderr \"fatal: repository not found\"\n When I clone \"https://github.com/org/missing.git\" into container \"abc123def456\"\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then the clone should raise CloneIntoError\n And the CloneIntoError should mention \"repository not found\"\n Then discovery should return 1 result\n And the first result should have no config name\n\n Scenario: CloneIntoError stores repo_url, container_id, and stderr \n Given a CloneIntoError with repo \"https://example.com/repo.git\" container \"ctr-001\" stderr \"auth failed\"\n Then the CloneIntoError repo_url should be \"https://example.com/repo.git\"\n And the CloneIntoError container_id should be \"ctr-001\"\n And the CloneIntoError stderr should be \"auth failed\"\n\n Scenario: Root .devcontainer.json has no config name \n Given a temporary directory simulating a git checkout\n And the directory has a root .devcontainer.json file\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 1 result\n And \nthe first result should have no config name Scenario: container-instance resource type has clone-into CLI argument \n\n When I look up the \"container-instance\" resource type spec\n Then the spec should have a CLI argument named \"clone-into\"\n And the clone-into argument should be of type \"string\"\n And the clone-into argument should not be required\n\n Scenario: Named config with invalid JSON is skipped \n Given a temporary directory simulating a git checkout\n And the directory has a named devcontainer configuration \"broken\" with invalid JSON\n\n Scenario: validate_clone_into_url rejects whitespace-only string \n When I validate clone-into URL with whitespace only\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then the clone-into URL should be invalid\n\n1 feature passed, 0 failed, 0 skipped\n17 scenarios passed, 0 failed, 0 skipped\n44 steps passed, 0 failed, 0 skipped\nTook 0min 0.008s\n Then discovery should return 0 results\n\n Scenario: Empty .devcontainer directory returns no results \n Given a temporary directory simulating a git checkout\n And the directory has an empty .devcontainer directory\n When I run devcontainer discovery on the directory as \"git-checkout\"\n Then discovery should return 0 results\n\n Scenario: git-checkout is a trigger type \n Then \"git-checkout\" should be a trigger type\n\n Scenario: fs-directory is a trigger type \n Then \"fs-directory\" should be a trigger type\n\n Scenario: devcontainer-instance is not a trigger type \n Then \"devcontainer-instance\" should not be a trigger type\n\n1 feature passed, 0 failed, 0 skipped\n26 scenarios passed, 0 failed, 0 skipped\n90 steps passed, 0 failed, 0 skipped\nTook 0min 0.026s\nFeature: Devcontainer Session Cleanup and CLI Commands\n As a CleverAgents developer\n I want session-scoped container cleanup and CLI stop/rebuild commands\n So that containers are cleaned up when sessions end and can be managed via CLI\n Scenario: Active containers stopped on session cleanup \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000040\" with container ID \"ctr-a\"\n And an active container \"01TESTLIFECYCLE0000000041\" with container ID \"ctr-b\"\n When I run session cleanup for session \"session-001\"\n Then the container state for \"01TESTLIFECYCLE0000000040\" should be \"stopped\"\n And the container state for \"01TESTLIFECYCLE0000000041\" should be \"stopped\"\n\n Scenario: CleanupService stop_active_devcontainers is callable and returns list \n When I call CleanupService stop_active_devcontainers with no active containers\n Then the cleanup result should be an empty list\n And CleanupService should have a stop_active_devcontainers method\n\n Scenario: CleanupService stop_active_devcontainers calls handler cleanup \n When I call CleanupService stop_active_devcontainers with no active containers\n Then the cleanup result should be an empty list\n\n Scenario: Session cleanup handles stop failure gracefully \n Given a mock devcontainer CLI runner\n And the runner configured to raise exception on stop\n And an active container \"01TESTLIFECYCLE0000000130\" with container ID \"ctr-fail\"\n When I run session cleanup for session \"session-err\"\n Then the cleanup should return 0 stopped containers\n\n Scenario: CLI stop succeeds for active devcontainer-instance \n Given a mock resource service with devcontainer \"local/test-dc\" id \"01TESTLIFECYCLE0000000200\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000200\" with container ID \"ctr-cli-stop\"\n When I invoke CLI resource stop \"local/test-dc\"\nFeature: DevcontainerHandler missing protocol methods\n As a developer using DevcontainerHandler\n I want delete(), list_children(), diff(), and create_sandbox() to be implemented\n So that the handler satisfies the full ResourceHandler protocol (issue #1242)\n Scenario: dcproto delete file successfully from devcontainer \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful rm output\n When dcproto I delete path \"src/old_file.py\" from the resource\n Then dcproto the delete should succeed\n And dcproto the delete message should contain \"src/old_file.py\"\n And dcproto the subprocess should have been called with \"rm\" and \"src/old_file.py\"\n\n Scenario: dcproto delete with empty path targets workspace root \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful rm output\n When dcproto I delete with empty path from the resource\n Then dcproto the delete should succeed\n And dcproto the subprocess should have been called with \"rm\" and \".\"\n\n Scenario: dcproto delete fails when container is stopped \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns failed rm output with stderr \"container not running\"\n When dcproto I delete path \"file.txt\" from the resource\n Then the CLI exit code should be 0\n And the CLI output should contain \"Stopped\"\n Then dcproto the delete should fail\n And dcproto the delete failure message should contain \"container not running\"\n\n Scenario: CLI stop rejects non-devcontainer resource type \n Given a mock resource service with git-checkout \"local/my-repo\" id \"01TESTLIFECYCLE0000000201\"\n When I invoke CLI resource stop \"local/my-repo\"\n\n Scenario: dcproto delete from resource with no location raises ValueError \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n When dcproto I delete path \"any/file.txt\" from the resource\n Then dcproto the delete should raise ValueError containing \"no location\"\n\n Scenario: dcproto list_children returns sorted names from devcontainer \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful ls listing \"src\\ntests\\nREADME.md\"\n When dcproto I list children of the resource\n Then dcproto the children list should have 3 entries\n And dcproto the children list should be \"README.md,src,tests\"\n\n Scenario: dcproto list_children returns empty list when container is stopped \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns failed ls output\n When dcproto I list children of the resource\n Then dcproto the children list should have 0 entries\n\n Scenario: dcproto list_children filters blank lines from ls output \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful ls listing \"alpha\\n\\n\\nbeta\\n\"\n When dcproto I list children of the resource\n Then dcproto the children list should have 2 entries\n And dcproto the children list should be \"alpha,beta\"\n\n Scenario: dcproto list_children from resource with no location raises ValueError \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n When dcproto I list children of the resource\n Then dcproto the list children should raise ValueError containing \"no location\"\n\n Scenario: dcproto list_children uses devcontainer exec ls command \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto subprocess returns successful ls listing \"main.py\"\n When dcproto I list children of the resource\n Then dcproto the subprocess should have been called with \"ls\" and \"--workspace-folder\"\n\n Scenario: dcproto diff detects changes when hashes differ \n Given dcproto a devcontainer handler\n Then the devcontainer CLI exit code should be non-zero\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And the CLI output should contain \"not a stoppable container type\"\n And dcproto the container content hash is \"aabbccdd\"\n And dcproto a temporary directory with a different file\n When dcproto I diff the resource against the temporary directory\n Then dcproto the diff should report has_changes true\n And dcproto the diff files_changed should be 1\n\n Scenario: CLI rebuild succeeds for stopped devcontainer-instance \n Given a mock resource service with devcontainer \"local/test-dc-rb\" id \"01TESTLIFECYCLE0000000210\" at \"/workspace/project\"\n And a stopped container \"01TESTLIFECYCLE0000000210\"\n When I invoke CLI resource rebuild \"local/test-dc-rb\"\n\n Scenario: dcproto diff reports no changes when hashes match \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container content hash matches the other location\n When dcproto I diff the resource against the same location\n Then dcproto the diff should report has_changes false\n And dcproto the diff files_changed should be 0\n Then the CLI exit code should be 0\n And the CLI output should contain \"Rebuilt\"\n\n Scenario: dcproto diff reports no changes when both sides are absent \n Given dcproto a devcontainer handler\n\n Scenario: CLI rebuild rejects resource with no location \n Given a mock resource service with devcontainer \"local/dc-no-loc\" id \"01TESTLIFECYCLE0000000211\" with no location\n And dcproto a devcontainer-instance resource with location \"/nonexistent/path\"\n And a stopped container \"01TESTLIFECYCLE0000000211\"\n When dcproto I diff the resource against \"/another/nonexistent/path\"\n When I invoke CLI resource rebuild \"local/dc-no-loc\"\n Then dcproto the diff should report has_changes false\n\n Scenario: dcproto diff from resource with no location raises ValueError \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n When dcproto I diff the resource against \"/some/path\"\n Then the devcontainer CLI exit code should be non-zero\n Then dcproto the diff should raise ValueError containing \"no location\"\n And the CLI output should contain \"no location\"\n\n Scenario: dcproto diff unified_diff is always empty string \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n\n Scenario: CLI rebuild rejects non-devcontainer resource type \n Given a mock resource service with git-checkout \"local/git-rb\" id \"01TESTLIFECYCLE0000000212\"\n And dcproto the container content hash is \"aabbccdd\"\n And dcproto a temporary directory with a different file\n When I invoke CLI resource rebuild \"local/git-rb\"\n When dcproto I diff the resource against the temporary directory\n Then dcproto the diff unified_diff should be empty\n\n Scenario: dcproto create_sandbox delegates to base class for running container \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container is in RUNNING state\n And dcproto a mock sandbox manager that returns a valid sandbox\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"rebuild requires devcontainer\"\n When dcproto I create a sandbox for the resource with plan \"plan-001\"\n Then dcproto the sandbox result should have strategy \"snapshot\"\n And dcproto the sandbox result should have a sandbox path\n\n Scenario: CLI stop calls stop_container with correct resource_id \n Given a mock resource service with devcontainer \"local/test-dc-r7\" id \"01TESTLIFECYCLE0000000220\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000220\" with container ID \"ctr-r7\"\n When I invoke CLI resource stop \"local/test-dc-r7\"\n\n Scenario: dcproto create_sandbox activates container when in DETECTED state \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container is in DETECTED state\n And dcproto a mock sandbox manager that returns a valid sandbox\n And dcproto activate_container is mocked to succeed\n When dcproto I create a sandbox for the resource with plan \"plan-002\"\n Then dcproto activate_container should have been called\n Then the CLI exit code should be 0\n And the CLI stop mock should have been called with \"01TESTLIFECYCLE0000000220\"\n\n Scenario: dcproto create_sandbox activates container when in STOPPED state \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with location \"/ws/project\"\n And dcproto the container is in STOPPED state\n And dcproto a mock sandbox manager that returns a valid sandbox\n And dcproto activate_container is mocked to succeed\n When dcproto I create a sandbox for the resource with plan \"plan-003\"\n\n Scenario: CLI rebuild calls rebuild_container with correct args \n Given a mock resource service with devcontainer \"local/test-dc-r7rb\" id \"01TESTLIFECYCLE0000000221\" at \"/workspace/project\"\n And a stopped container \"01TESTLIFECYCLE0000000221\"\n Then dcproto activate_container should have been called\n When I invoke CLI resource rebuild \"local/test-dc-r7rb\"\n\n Scenario: dcproto create_sandbox raises ValueError for resource with no location \n Given dcproto a devcontainer handler\n And dcproto a devcontainer-instance resource with no location\n And dcproto a mock sandbox manager that returns a valid sandbox\n When dcproto I create a sandbox for the resource with plan \"plan-004\"\n Then dcproto the create_sandbox should raise ValueError containing \"no location\"\n\n1 feature passed, 0 failed, 0 skipped\n18 scenarios passed, 0 failed, 0 skipped\n102 steps passed, 0 failed, 0 skipped\nTook 0min 0.028s\n Then the CLI exit code should be 0\n And the CLI rebuild mock should have been called with \"01TESTLIFECYCLE0000000221\" and \"/workspace/project\"\n\n Scenario: DevcontainerHandler has expected class attributes and is instantiable \n Then DevcontainerHandler should have _default_strategy \"snapshot\"\n And DevcontainerHandler should have _type_label \"devcontainer\"\n And DevcontainerHandler should be instantiable\n\n Scenario: DevcontainerHandler extends BaseResourceHandler and inherits resolve interface \n Then DevcontainerHandler should be a subclass of BaseResourceHandler\n And DevcontainerHandler instance should have a resolve method\n\n Scenario: CLI stop rejects container not in running state \n Given a mock resource service with devcontainer \"local/dc-det\" id \"01TESTLIFECYCLE0000000230\" at \"/workspace/project\"\n And a lifecycle tracker for resource \"01TESTLIFECYCLE0000000230\"\n When I invoke CLI resource stop \"local/dc-det\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Cannot stop\"\n\n Scenario: CLI rebuild rejects container in running state \n Given a mock resource service with devcontainer \"local/dc-run\" id \"01TESTLIFECYCLE0000000231\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000231\" with container ID \"ctr-rb-state\"\n When I invoke CLI resource rebuild \"local/dc-run\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Cannot rebuild\"\n\n Scenario: Session cleanup returns list of stopped resource IDs \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000250\" with container ID \"ctr-r14a\"\n And an active container \"01TESTLIFECYCLE0000000251\" with container ID \"ctr-r14b\"\n When I run session cleanup for session \"session-r14\"\n Then the cleanup stopped list should contain \"01TESTLIFECYCLE0000000250\"\n And the cleanup stopped list should contain \"01TESTLIFECYCLE0000000251\"\n\n Scenario: CLI stop with --yes skips confirmation and calls stop_container \n Given a CLI-mockable running devcontainer resource \"test-dc-yes-stop\"\n When I invoke CLI resource stop \"test-dc-yes-stop\"\n Then the devcontainer CLI exit code should be 0\n And the CLI stop mock should have been called once\n\n Scenario: CLI rebuild with --yes skips confirmation and calls rebuild_container \n Given a CLI-mockable stopped devcontainer resource \"test-dc-yes-rebuild\"\n When I invoke CLI resource rebuild \"test-dc-yes-rebuild\"\n Then the devcontainer CLI exit code should be 0\n And the CLI rebuild mock should have been called once\n\n Scenario: CLI stop accepts container-instance type (issue #2588 fix) \n Given a mock resource service with container-instance \"local/ctr-stop\" id \"01TESTLIFECYCLE0000000370\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000370\" with container ID \"ctr-ci-stop\"\n When I invoke CLI resource stop \"local/ctr-stop\"\n Then the CLI exit code should be 0\n And the CLI output should contain \"Stopped\"\n\n Scenario: CLI stop handles NotFoundError from show_resource \n Given a mock resource service that raises NotFoundError for \"local/missing\"\n When I invoke CLI resource stop \"local/missing\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Resource not found\"\n\n Scenario: CLI rebuild handles NotFoundError from show_resource \n Given a mock resource service that raises NotFoundError for \"local/missing-rb\"\n When I invoke CLI resource rebuild \"local/missing-rb\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Resource not found\"\n\n Scenario: CLI stop handles RuntimeError from stop_container \n Given a mock resource service with devcontainer \"local/dc-rterr\" id \"01TESTLIFECYCLE0000000500\" at \"/workspace/project\"\n And an active container \"01TESTLIFECYCLE0000000500\" with container ID \"ctr-rterr\"\n And CLI stop_container mock that raises RuntimeError\n When I invoke CLI resource stop with error mock \"local/dc-rterr\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Stop failed\"\n\n Scenario: CLI rebuild handles RuntimeError from rebuild_container \n Given a mock resource service with devcontainer \"local/dc-rberr\" id \"01TESTLIFECYCLE0000000501\" at \"/workspace/project\"\n And a stopped container \"01TESTLIFECYCLE0000000501\"\n And CLI rebuild_container mock that raises RuntimeError\n When I invoke CLI resource rebuild with error mock \"local/dc-rberr\"\n Then the devcontainer CLI exit code should be non-zero\n And the CLI output should contain \"Rebuild failed\"\n\n Scenario: Session cleanup only stops containers belonging to that session \n Given a mock devcontainer CLI runner\n And a session-scoped active container \"01TESTLIFECYCLE0000000600\" with ID \"ctr-s1\" session \"sess-A\"\n And a session-scoped active container \"01TESTLIFECYCLE0000000601\" with ID \"ctr-s2\" session \"sess-B\"\n When I run session cleanup for session \"sess-A\"\n Then the container state for \"01TESTLIFECYCLE0000000600\" should be \"stopped\"\n And the container state for \"01TESTLIFECYCLE0000000601\" should be \"running\"\n\n Scenario: Session cleanup with no session_id stops all containers \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000610\" with container ID \"ctr-all1\"\n And an active container \"01TESTLIFECYCLE0000000611\" with container ID \"ctr-all2\"\n When I run session cleanup with no session filter\n Then the container state for \"01TESTLIFECYCLE0000000610\" should be \"stopped\"\n And the container state for \"01TESTLIFECYCLE0000000611\" should be \"stopped\"\n\n Scenario: Session cleanup triggers terminal tracker eviction \n Given a mock devcontainer CLI runner\n And 210 stopped container trackers in the registry\n And an active container \"01TESTLIFECYCLE0000000650\" with container ID \"ctr-evict\"\n When I run session cleanup for session \"session-evict\"\n Then the container state for \"01TESTLIFECYCLE0000000650\" should be \"stopped\"\n And the registry should have at most 200 terminal trackers\n\n Scenario: list_active_containers_for_session returns only matching session \n Given a mock devcontainer CLI runner\n And a session-scoped active container \"01TESTLIFECYCLE0000000700\" with ID \"ctr-ts3a\" session \"sess-X\"\n And a session-scoped active container \"01TESTLIFECYCLE0000000701\" with ID \"ctr-ts3b\" session \"sess-Y\"\n When I list active containers for session \"sess-X\"\n Then the session container list should contain \"01TESTLIFECYCLE0000000700\"\n And the session container list should not contain \"01TESTLIFECYCLE0000000701\"\n\n Scenario: list_active_containers_for_session with empty session returns all \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000710\" with container ID \"ctr-ts3c\"\n And an active container \"01TESTLIFECYCLE0000000711\" with container ID \"ctr-ts3d\"\n When I list active containers for an empty session\n Then the session container list should contain \"01TESTLIFECYCLE0000000710\"\n And the session container list should contain \"01TESTLIFECYCLE0000000711\"\n\n Scenario: list_active_containers_for_session includes unscoped containers \n Given a mock devcontainer CLI runner\n And an active container \"01TESTLIFECYCLE0000000720\" with container ID \"ctr-unscoped\"\n And a session-scoped active container \"01TESTLIFECYCLE0000000721\" with ID \"ctr-scoped\" session \"sess-Z\"\n When I list active containers for session \"sess-Z\"\n Then the session container list should contain \"01TESTLIFECYCLE0000000720\"\n And the session container list should contain \"01TESTLIFECYCLE0000000721\"\n\n Scenario: Session close cleans up containers even without session service \n Given a facade with no session service\n And a session-scoped active container \"01TESTLIFECYCLE0000000630\" with no docker ID session \"sess-f4\"\n When I close session \"sess-f4\" via the facade\n Then the container state for \"01TESTLIFECYCLE0000000630\" should be \"stopped\"\n\n1 feature passed, 0 failed, 0 skipped\n30 scenarios passed, 0 failed, 0 skipped\n143 steps passed, 0 failed, 0 skipped\nTook 0min 0.436s\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:42 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n\u001b[1mIncluding unscoped container 01TESTLIFECYCLE0000000040 in session 'session-001' cleanup (container has no session_id set)\u001b[0m\n\u001b[1mIncluding unscoped container 01TESTLIFECYCLE0000000041 in session 'session-001' cleanup (container has no session_id set)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000040: running -> stopping (manual stop)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000040: stopping -> stopped (container stopped)\u001b[0m\n\u001b[1mStopped container 01TESTLIFECYCLE0000000040 (session=session-001)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000041: running -> stopping (manual stop)\u001b[0m\n\u001b[1mContainer 01TESTLIFECYCLE0000000041: stopping -> stopped (container stopped)\u001b[0m\n\u001b[1mStopped container 01TESTLIFECYCLE0000000041 (session=session-001)\u001b[0m\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n\u001b[1mRegistered built-in resource type: fs-mount\u001b[0m\n\u001b[1mRegistered built-in resource type: git-checkout\u001b[0m\n\u001b[1mRegistered built-in resource type: fs-directory\u001b[0m\n\u001b[1mRegistered built-in resource type: container-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: devcontainer-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: devcontainer-file\u001b[0m\n\u001b[1mRegistered built-in resource type: git\u001b[0m\n\u001b[1mRegistered built-in resource type: git-remote\u001b[0m\n\u001b[1mRegistered built-in resource type: git-branch\u001b[0m\n\u001b[1mRegistered built-in resource type: git-tag\u001b[0m\n\u001b[1mRegistered built-in resource type: git-commit\u001b[0m\n\u001b[1mRegistered built-in resource type: git-tree\u001b[0m\n\u001b[1mRegistered built-in resource type: git-tree-entry\u001b[0m\n\u001b[1mRegistered built-in resource type: git-stash\u001b[0m\n\u001b[1mRegistered built-in resource type: git-submodule\u001b[0m\n\u001b[1mRegistered built-in resource type: fs-symlink\u001b[0m\n\u001b[1mRegistered built-in resource type: fs-hardlink\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-account\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-region\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-network\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-subnet\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-security-group\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-load-balancer\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-compute-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-object-store\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-block-storage\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-identity-principal\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-role\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-policy\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-log-group\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-alarm\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-queue\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-topic\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-container-repo\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-container-cluster\u001b[0m\n\u001b[1mRegistered built-in resource type: cloud-container-service\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-account\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-region\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-vpc\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-subnet\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-igw\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-nat-gw\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-route-table\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-nacl\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-security-group\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-alb\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-nlb\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-target-group\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-listener\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ec2-instance\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ami\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-launch-template\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-asg\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-s3-bucket\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ebs-volume\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-efs-filesystem\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-user\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-role\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-policy\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-iam-instance-profile\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-cloudwatch-log-group\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-cloudwatch-alarm\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-cloudwatch-metric\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eventbridge-bus\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eventbridge-rule\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eventbridge-target\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-sqs-queue\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-sns-topic\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-sns-subscription\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecr-repo\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecs-cluster\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecs-service\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-ecs-task-def\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eks-cluster\u001b[0m\n\u001b[1mRegistered built-in resource type: aws-eks-nodegroup\u001b[0m\n\u001b[1mRegistered built-in resource type: gcp\u001b[0m\n\u001b[1mRegistered built-in resource type: azure\u001b[0m\n\u001b[1mRegistered built-in resource type: container-runtime\u001b[0m\n\u001b[1mRegistered built-in resource type: container-image\u001b[0m\n\u001b[1mRegistered built-in resource type: container-mount\u001b[0m\n\u001b[1mRegistered built-in resource type: container-exec-env\u001b[0m\n\u001b[1mRegistered built-in resource type: container-port\u001b[0m\n\u001b[1mRegistered built-in resource type: container-volume\u001b[0m\n\u001b[1mRegistered built-in resource type: container-network\u001b[0m\n\u001b[1mRegistered built-in resource type: postgres\u001b[0m\n\u001b[1mRegistered built-in resource type: mysql\u001b[0m\n\u001b[1mRegistered built-in resource type: sqlite\u001b[0m\n\u001b[1mRegistered built-in resource type: duckdb\u001b[0m\n\u001b[1mRegistered built-in resource type: file\u001b[0m\n\u001b[1mRegistered built-in resource type: directory\u001b[0m\n\u001b[1mRegistered built-in resource type: commit\u001b[0m\n\u001b[1mRegistered built-in resource type: branch\u001b[0m\n\u001b[1mRegistered built-in resource type: tag\u001b[0m\n\u001b[1mRegistered built-in resource type: tree\u001b[0m\n\u001b[1mRegistered built-in resource type: remote\u001b[0m\n\u001b[1mRegistered built-in resource type: submodule\u001b[0m\n\u001b[1mRegistered built-in resource type: symlink\u001b[0m\n\u001b[1mRegistered built-in resource type: executable\u001b[0m\n\u001b[1mRegistered built-in resource type: lsp-server\u001b[0m\n\u001b[1mRegistered built-in resource type: lsp-workspace\u001b[0m\n\u001b[1mRegistered built-in resource type: lsp-document\u001b[0m\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.created child_domain=uko-oo: parent_domain=uko-code:\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=MEMBER_LISTING domain=uko-oo: new_level=CLASS_HIERARCHY\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.insert_after after_level=SIGNATURES_WITH_DOCS domain=uko-oo: new_level=VISIBILITY_ANNOTATED\n2026-04-13 07:00:43 [debug ] detail_level_map_builder.built domain=uko-oo: max_depth=11 num_levels=12\n\nOverall summary:\n6 features passed, 1 failed, 0 errored, 0 skipped\n144 scenarios passed, 1 failed, 0 errored, 0 skipped\n553 steps passed, 1 failed, 0 errored, 0 skipped\nTook 2.366s\nWall time: 2m 47.786s\n\nnox > Running session unit_tests-3.13\nnox > Reusing existing virtual environment at .nox/unit_tests-3-13.\nnox > uv pip install -e '.[tests]'\nnox > uv pip install setuptools wheel\nnox > uv pip install .nox/unit_tests-3-13/tmp/behave-parallel-inprocess\nnox > python scripts/create_template_db.py /tmp/impl-worker-7555-20260413/build/.template-migrated.db\nnox > python -m compileall -q features/\nnox > /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature\nnox > Command /tmp/impl-worker-7555-20260413/.nox/unit_tests-3-13/bin/behave-parallel -q --processes 32 features/container_clone_into.feature features/devcontainer_sandbox_strategy.feature features/devcontainer_state.feature features/devcontainer_handler.feature features/devcontainer_cleanup.feature features/resource_list_lifecycle_state.feature features/devcontainer_handler_protocol_methods.feature failed with exit code 1\nnox > Session unit_tests-3.13 failed." -} \ No newline at end of file