UAT: _cleveragents/plan/explain A2A handler is a stub — always returns "Not yet implemented" instead of calling DecisionService #2522

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

Metadata

  • Branch: fix/a2a-plan-explain-stub
  • Commit Message: fix(a2a): implement _cleveragents/plan/explain handler via DecisionService
  • Milestone: v3.8.0
  • Parent Epic: #399

Description

The _handle_plan_explain method in src/cleveragents/a2a/facade.py (lines 518–526) is a complete stub that always returns "explanation": "Not yet implemented" regardless of whether a DecisionService is available or whether valid plan_id/decision_id parameters are supplied.

What was tested:
Code analysis of src/cleveragents/a2a/facade.py lines 518–526.

Expected behavior (from spec §43267):
The _cleveragents/plan/explain A2A extension method should map to PlanService.explain_decision(). The CLI agents plan explain command correctly calls DecisionService.get_decision(identifier) and DecisionService.list_decisions(identifier) to retrieve and format decision details. The A2A handler must return the full decision explanation including question, chosen, confidence, rationale, alternatives_considered, parent, is_correction, superseded, and created_at fields — matching the output of the CLI agents plan explain command.

Actual behavior:
The handler always returns:

{
  "plan_id": "...",
  "decision_id": "...",
  "explanation": "Not yet implemented",
  "stub": true
}

Code location:
src/cleveragents/a2a/facade.py, method _handle_plan_explain (lines 518–526):

def _handle_plan_explain(self, params: dict[str, Any]) -> dict[str, Any]:
    plan_id = params.get("plan_id", "")
    decision_id = params.get("decision_id", "")
    return {
        "plan_id": plan_id,
        "decision_id": decision_id,
        "explanation": "Not yet implemented",
        "stub": True,
    }

Fix required:
The handler must call DecisionService.get_decision(decision_id) (or list_decisions(plan_id) to find the root decision) and return the full decision explanation including question, chosen, confidence, rationale, alternatives_considered, parent, is_correction, superseded, and created_at fields — matching the output of the CLI agents plan explain command.

Subtasks

  • Write TDD Behave scenario: _cleveragents/plan/explain with a valid decision_id returns full decision fields (red test)
  • Write TDD Behave scenario: _cleveragents/plan/explain with only plan_id resolves root decision via list_decisions (red test)
  • Write TDD Behave scenario: _cleveragents/plan/explain with unknown decision_id returns a proper JSON-RPC error (red test)
  • Replace stub body in _handle_plan_explain with a call to DecisionService.get_decision(decision_id)
  • Add fallback: if decision_id is empty, call DecisionService.list_decisions(plan_id) to resolve the root decision
  • Return full decision fields: question, chosen, confidence, rationale, alternatives_considered, parent, is_correction, superseded, created_at
  • Remove "stub": True key from the response
  • Verify all TDD scenarios pass (green tests)
  • Run nox -e typecheck — confirm no Pyright errors
  • Run nox -e unit_tests — confirm all Behave scenarios pass
  • Run nox -e coverage_report — confirm coverage ≥ 97%
  • Run nox (all default sessions) — fix any errors

Definition of Done

  • _cleveragents/plan/explain A2A handler calls DecisionService.get_decision() or DecisionService.list_decisions() instead of returning a stub
  • Response includes all spec-required fields: question, chosen, confidence, rationale, alternatives_considered, parent, is_correction, superseded, created_at
  • "stub": true key is absent from all responses
  • Unknown decision_id or plan_id returns a proper JSON-RPC error (not a stub payload)
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional details about the implementation
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly
  • 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-explain-stub` - **Commit Message**: `fix(a2a): implement _cleveragents/plan/explain handler via DecisionService` - **Milestone**: v3.8.0 - **Parent Epic**: #399 ## Description The `_handle_plan_explain` method in `src/cleveragents/a2a/facade.py` (lines 518–526) is a complete stub that always returns `"explanation": "Not yet implemented"` regardless of whether a `DecisionService` is available or whether valid `plan_id`/`decision_id` parameters are supplied. **What was tested:** Code analysis of `src/cleveragents/a2a/facade.py` lines 518–526. **Expected behavior (from spec §43267):** The `_cleveragents/plan/explain` A2A extension method should map to `PlanService.explain_decision()`. The CLI `agents plan explain` command correctly calls `DecisionService.get_decision(identifier)` and `DecisionService.list_decisions(identifier)` to retrieve and format decision details. The A2A handler must return the full decision explanation including `question`, `chosen`, `confidence`, `rationale`, `alternatives_considered`, `parent`, `is_correction`, `superseded`, and `created_at` fields — matching the output of the CLI `agents plan explain` command. **Actual behavior:** The handler always returns: ```json { "plan_id": "...", "decision_id": "...", "explanation": "Not yet implemented", "stub": true } ``` **Code location:** `src/cleveragents/a2a/facade.py`, method `_handle_plan_explain` (lines 518–526): ```python def _handle_plan_explain(self, params: dict[str, Any]) -> dict[str, Any]: plan_id = params.get("plan_id", "") decision_id = params.get("decision_id", "") return { "plan_id": plan_id, "decision_id": decision_id, "explanation": "Not yet implemented", "stub": True, } ``` **Fix required:** The handler must call `DecisionService.get_decision(decision_id)` (or `list_decisions(plan_id)` to find the root decision) and return the full decision explanation including `question`, `chosen`, `confidence`, `rationale`, `alternatives_considered`, `parent`, `is_correction`, `superseded`, and `created_at` fields — matching the output of the CLI `agents plan explain` command. ## Subtasks - [ ] Write TDD Behave scenario: `_cleveragents/plan/explain` with a valid `decision_id` returns full decision fields (red test) - [ ] Write TDD Behave scenario: `_cleveragents/plan/explain` with only `plan_id` resolves root decision via `list_decisions` (red test) - [ ] Write TDD Behave scenario: `_cleveragents/plan/explain` with unknown `decision_id` returns a proper JSON-RPC error (red test) - [ ] Replace stub body in `_handle_plan_explain` with a call to `DecisionService.get_decision(decision_id)` - [ ] Add fallback: if `decision_id` is empty, call `DecisionService.list_decisions(plan_id)` to resolve the root decision - [ ] Return full decision fields: `question`, `chosen`, `confidence`, `rationale`, `alternatives_considered`, `parent`, `is_correction`, `superseded`, `created_at` - [ ] Remove `"stub": True` key from the response - [ ] Verify all TDD scenarios pass (green tests) - [ ] Run `nox -e typecheck` — confirm no Pyright errors - [ ] Run `nox -e unit_tests` — confirm all Behave scenarios pass - [ ] Run `nox -e coverage_report` — confirm coverage ≥ 97% - [ ] Run `nox` (all default sessions) — fix any errors ## Definition of Done - [ ] `_cleveragents/plan/explain` A2A handler calls `DecisionService.get_decision()` or `DecisionService.list_decisions()` instead of returning a stub - [ ] Response includes all spec-required fields: `question`, `chosen`, `confidence`, `rationale`, `alternatives_considered`, `parent`, `is_correction`, `superseded`, `created_at` - [ ] `"stub": true` key is absent from all responses - [ ] Unknown `decision_id` or `plan_id` returns a proper JSON-RPC error (not a stub payload) - [ ] A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional details about the implementation - [ ] The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly - [ ] 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:45:12 +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
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#2522
No description provided.