diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7c258a04f..8b384231f 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -130,4 +130,4 @@ Below are some specific details of individual PR contributions. * HAL 9000 has contributed the PyYAML security hardening fix (PR #11017 / issue #11012): added `pyyaml>=6.0.3` as an explicit runtime dependency in `pyproject.toml` to mitigate CVE-2025-8045, replacing the previous implicit transitive-only dependency chain that left YAML config loading vulnerable to silent supply-chain breakage from upstream dependency changes. * HAL 9000 has contributed the plan explain structured alternatives format fix (PR #11090): updated `_build_explain_dict()` in `src/cleveragents/cli/commands/plan.py` to convert the `alternatives_considered` list into structured objects with `index` (1-based), `description`, and `chosen` fields in the `alternatives` output key, aligning the `agents plan explain` output with the spec-required format. * HAL 9000 has contributed the plan tree JSON/YAML spec-compliant envelope fix (issue #11041): wrapped `agents plan tree` JSON and YAML output in the spec-required command envelope (`command`, `status`, `exit_code`, `data`, `timing`, `messages`), updated BDD step definitions to validate envelope structure, and removed the `@tdd_expected_fail` tag from the previously-failing JSON tree format test (issue #4254). -* HAL 9000 has contributed the a2a session_id validation fix (PR #11053 / issue #9094): moved the session_id validation guard to the top of `_handle_session_close()` in `A2aLocalFacade`, closing the validation bypass path where empty or null session IDs could slip through to devcontainer cleanup when `SessionService` was not wired. +* HAL 9000 has contributed the a2a session_id validation fix (PR #11098 / issue #9250): moved the session_id validation guard to the top of `_handle_session_close()` in `A2aLocalFacade`, closing the validation bypass path where empty or null session IDs could slip through to devcontainer cleanup when `SessionService` was not wired. diff --git a/features/a2a_facade_coverage.feature b/features/a2a_facade_coverage.feature index 2c6bc2439..9ca9287ae 100644 --- a/features/a2a_facade_coverage.feature +++ b/features/a2a_facade_coverage.feature @@ -24,16 +24,19 @@ Feature: A2A local facade coverage — uncovered handler and edge-case paths # Session close — session_id validation guard (lines 321-324) # ------------------------------------------------------------------- + @tdd_issue @tdd_issue_9250 Scenario: Session close with empty session_id and no service raises ValueError error Given a facade-cov facade with no services When I dispatch facade-cov operation "session.close" with params {"session_id": ""} Then the facade-cov response status should be "error" + @tdd_issue @tdd_issue_9250 Scenario: Session close with missing session_id key and no service raises ValueError error Given a facade-cov facade with no services When I dispatch facade-cov operation "session.close" with params {} Then the facade-cov response status should be "error" + @tdd_issue @tdd_issue_9250 Scenario: Session close with empty session_id and wired service raises ValueError error Given a facade-cov facade with a mock SessionService When I dispatch facade-cov operation "session.close" with params {"session_id": ""} diff --git a/src/cleveragents/a2a/facade.py b/src/cleveragents/a2a/facade.py index 1519c6c35..46d385860 100644 --- a/src/cleveragents/a2a/facade.py +++ b/src/cleveragents/a2a/facade.py @@ -361,7 +361,7 @@ class A2aLocalFacade: session = svc.create(actor_name=actor_name) return {"session_id": session.session_id, "status": "created"} - def _handle_session_close(self, params: dict[str, Any]) -> dict[str, Any]: + def _handle_session_close(self, params: dict[str, Any]) -> dict[str, Any]: session_id = params.get("session_id", "") # Validate session_id before any cleanup or service operations.