UAT: _cleveragents/plan/tree A2A handler always returns empty decision tree — DecisionService is never called #2482

Open
opened 2026-04-03 18:37:36 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/a2a-plan-tree-decision-service
  • Commit Message: fix(a2a): call DecisionService in _handle_plan_tree to return full decision tree
  • Milestone: v3.8.0
  • Parent Epic: #399

Background

The _handle_plan_tree method in src/cleveragents/a2a/facade.py (lines 506–516) always returns "tree": [] even when a PlanLifecycleService is available. It fetches the plan to obtain decision_root_id but never calls DecisionService to retrieve the actual decisions.

Per spec §43266, the _cleveragents/plan/tree A2A extension method must map to PlanService.get_tree() and return the full decision tree for the plan. The CLI agents plan tree command already implements this correctly by calling decision_service.list_decisions(plan_id) and building a nested tree structure via build_decision_tree() in src/cleveragents/cli/commands/plan.py.

Faulty code (src/cleveragents/a2a/facade.py, _handle_plan_tree, lines 506–516):

def _handle_plan_tree(self, params: dict[str, Any]) -> dict[str, Any]:
    plan_id = params.get("plan_id", "")
    svc = self._plan_lifecycle_service
    if svc is None or not plan_id:
        return {"plan_id": plan_id, "tree": [], "stub": True}
    plan = svc.get_plan(plan_id)
    return {
        "plan_id": plan_id,
        "decision_root_id": plan.decision_root_id if plan else None,
        "tree": [],  # Always empty — DecisionService never called
    }

Expected Behavior

_handle_plan_tree calls DecisionService.list_decisions(plan_id), builds the nested decision tree (mirroring build_decision_tree() in the CLI), and returns it in the "tree" field.

Actual Behavior

The handler returns {"plan_id": ..., "decision_root_id": ..., "tree": []} — the tree is always empty regardless of how many decisions exist for the plan.

Subtasks

  • TDD — reproduce: Write a failing Behave scenario in features/ that calls _handle_plan_tree with a plan that has existing decisions and asserts the returned tree is non-empty
  • Fix: Update _handle_plan_tree in src/cleveragents/a2a/facade.py to inject/resolve DecisionService, call list_decisions(plan_id), and invoke build_decision_tree() (or equivalent) to populate the "tree" field
  • Refactor: Extract shared build_decision_tree() logic from src/cleveragents/cli/commands/plan.py into a shared utility (e.g., src/cleveragents/services/decision_tree_builder.py) so both the CLI and A2A handler use the same implementation
  • Tests (Behave): Add/update unit test scenarios covering: plan with no decisions, plan with a flat list of decisions, plan with a nested decision tree, missing plan_id param, unavailable PlanLifecycleService
  • Tests (Robot): Add an integration test that exercises the _cleveragents/plan/tree A2A endpoint end-to-end and validates the returned tree structure
  • Type checking: Ensure all new/modified code passes nox -e typecheck (Pyright, no # type: ignore)
  • Verify coverage ≥ 97% via nox -s coverage_report
  • Run nox (all default sessions) and fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(a2a): call DecisionService in _handle_plan_tree to return full decision tree), followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly (fix/a2a-plan-tree-decision-service).
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage >= 97%.

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/a2a-plan-tree-decision-service` - **Commit Message**: `fix(a2a): call DecisionService in _handle_plan_tree to return full decision tree` - **Milestone**: v3.8.0 - **Parent Epic**: #399 ## Background The `_handle_plan_tree` method in `src/cleveragents/a2a/facade.py` (lines 506–516) always returns `"tree": []` even when a `PlanLifecycleService` is available. It fetches the plan to obtain `decision_root_id` but never calls `DecisionService` to retrieve the actual decisions. Per spec §43266, the `_cleveragents/plan/tree` A2A extension method must map to `PlanService.get_tree()` and return the full decision tree for the plan. The CLI `agents plan tree` command already implements this correctly by calling `decision_service.list_decisions(plan_id)` and building a nested tree structure via `build_decision_tree()` in `src/cleveragents/cli/commands/plan.py`. **Faulty code** (`src/cleveragents/a2a/facade.py`, `_handle_plan_tree`, lines 506–516): ```python def _handle_plan_tree(self, params: dict[str, Any]) -> dict[str, Any]: plan_id = params.get("plan_id", "") svc = self._plan_lifecycle_service if svc is None or not plan_id: return {"plan_id": plan_id, "tree": [], "stub": True} plan = svc.get_plan(plan_id) return { "plan_id": plan_id, "decision_root_id": plan.decision_root_id if plan else None, "tree": [], # Always empty — DecisionService never called } ``` ## Expected Behavior `_handle_plan_tree` calls `DecisionService.list_decisions(plan_id)`, builds the nested decision tree (mirroring `build_decision_tree()` in the CLI), and returns it in the `"tree"` field. ## Actual Behavior The handler returns `{"plan_id": ..., "decision_root_id": ..., "tree": []}` — the tree is always empty regardless of how many decisions exist for the plan. ## Subtasks - [ ] **TDD — reproduce**: Write a failing Behave scenario in `features/` that calls `_handle_plan_tree` with a plan that has existing decisions and asserts the returned `tree` is non-empty - [ ] **Fix**: Update `_handle_plan_tree` in `src/cleveragents/a2a/facade.py` to inject/resolve `DecisionService`, call `list_decisions(plan_id)`, and invoke `build_decision_tree()` (or equivalent) to populate the `"tree"` field - [ ] **Refactor**: Extract shared `build_decision_tree()` logic from `src/cleveragents/cli/commands/plan.py` into a shared utility (e.g., `src/cleveragents/services/decision_tree_builder.py`) so both the CLI and A2A handler use the same implementation - [ ] **Tests (Behave)**: Add/update unit test scenarios covering: plan with no decisions, plan with a flat list of decisions, plan with a nested decision tree, missing `plan_id` param, unavailable `PlanLifecycleService` - [ ] **Tests (Robot)**: Add an integration test that exercises the `_cleveragents/plan/tree` A2A endpoint end-to-end and validates the returned tree structure - [ ] **Type checking**: Ensure all new/modified code passes `nox -e typecheck` (Pyright, no `# type: ignore`) - [ ] **Verify coverage ≥ 97%** via `nox -s coverage_report` - [ ] **Run `nox`** (all default sessions) and fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(a2a): call DecisionService in _handle_plan_tree to return full decision tree`), followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly (`fix/a2a-plan-tree-decision-service`). - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage >= 97%. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.8.0 milestone 2026-04-03 18:37:42 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • MoSCoW: Should Have — Spec compliance or quality improvement that should be included in the milestone.

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **MoSCoW**: Should Have — Spec compliance or quality improvement that should be included in the milestone. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
freemo removed this from the v3.8.0 milestone 2026-04-07 00:50:53 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#399 Epic: Post-MVP Server & Clients
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2482
No description provided.