From 9e184dae9b71569adc0b7ff6b18de02714628490 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Wed, 29 Apr 2026 02:21:38 +0000 Subject: [PATCH 1/3] fix(plan-tree): visually mark corrected nodes in build_decision_tree - Add label key to node dicts in _node_dict - Append [corrected] marker when decision.is_correction is True - Add TDD BDD scenario proving corrected nodes are visually marked --- .../tdd_plan_tree_correction_visual_steps.py | 155 ++++++++++++++++++ .../tdd_plan_tree_correction_visual.feature | 23 +++ src/cleveragents/cli/commands/plan.py | 4 + 3 files changed, 182 insertions(+) create mode 100644 features/steps/tdd_plan_tree_correction_visual_steps.py create mode 100644 features/tdd_plan_tree_correction_visual.feature diff --git a/features/steps/tdd_plan_tree_correction_visual_steps.py b/features/steps/tdd_plan_tree_correction_visual_steps.py new file mode 100644 index 000000000..fec59c260 --- /dev/null +++ b/features/steps/tdd_plan_tree_correction_visual_steps.py @@ -0,0 +1,155 @@ +"""Step definitions for tdd_plan_tree_correction_visual.feature. + +Tests that corrected nodes (decisions with is_correction=True) are visually +marked in the plan tree output. This is a TDD scenario documenting the gap +where the current implementation does NOT visually distinguish corrected nodes. +""" + +from __future__ import annotations + +from behave import given, then, when +from behave.runner import Context +from ulid import ULID + +from cleveragents.cli.commands.plan import build_decision_tree +from cleveragents.domain.models.core.decision import Decision, DecisionType + +# --------------------------------------------------------------------------- +# Constants +# --------------------------------------------------------------------------- + +_PLAN_ID = str(ULID()) + + +# --------------------------------------------------------------------------- +# Given steps +# --------------------------------------------------------------------------- + + +@given("a set of test decisions with a corrected decision") +def step_decisions_with_correction(context: Context) -> None: + """Create a set of decisions where one is marked as a correction.""" + root_id = str(ULID()) + corrected_id = str(ULID()) + corrects_id = str(ULID()) + + context.tdd_decisions = [ + # Root decision + Decision( + decision_id=root_id, + plan_id=_PLAN_ID, + sequence_number=0, + decision_type=DecisionType.PROMPT_DEFINITION, + question="What to build?", + chosen_option="REST API", + ), + # Original decision that will be corrected + Decision( + decision_id=corrects_id, + plan_id=_PLAN_ID, + parent_decision_id=root_id, + sequence_number=1, + decision_type=DecisionType.STRATEGY_CHOICE, + question="Which framework?", + chosen_option="Django", + ), + # Corrected decision (is_correction=True) + Decision( + decision_id=corrected_id, + plan_id=_PLAN_ID, + parent_decision_id=root_id, + sequence_number=2, + decision_type=DecisionType.STRATEGY_CHOICE, + question="Which framework?", + chosen_option="FastAPI", + is_correction=True, + corrects_decision_id=corrects_id, + ), + ] + context.tdd_corrected_id = corrected_id + + +# --------------------------------------------------------------------------- +# When steps +# --------------------------------------------------------------------------- + + +@when("I build the decision tree with default options") +def step_build_tree_default(context: Context) -> None: + """Build the decision tree from the test decisions.""" + context.tdd_tree_data = build_decision_tree( + context.tdd_decisions, + show_superseded=False, + max_depth=0, + ) + + +# --------------------------------------------------------------------------- +# Then steps +# --------------------------------------------------------------------------- + + +@then("the tree should include a visual marker for the corrected decision") +def step_tree_has_correction_marker(context: Context) -> None: + """Verify that the tree data includes a marker for the corrected decision.""" + tree_nodes: list[dict[str, object]] = context.tdd_tree_data + + # The tree_data is a list of root-level node dicts. + # We need to search through it to find the corrected decision node + # and verify it has a visual marker. + + def find_corrected_node( + nodes: list[dict[str, object]], + ) -> dict[str, object] | None: + """Recursively search for the corrected decision node.""" + for node in nodes: + if node.get("decision_id") == context.tdd_corrected_id: + return node + children = node.get("children", []) + assert isinstance(children, list) + result = find_corrected_node(children) + if result is not None: + return result + return None + + corrected_node = find_corrected_node(tree_nodes) + assert corrected_node is not None, ( + f"Corrected decision {context.tdd_corrected_id} not found in tree" + ) + + # Store the node for the next assertion + context.tdd_corrected_node = corrected_node + + +@then( + 'the corrected decision label should contain "[corrected]" or "✎" or similar marker' +) +def step_corrected_label_has_marker(context: Context) -> None: + """Verify that the corrected decision's label contains a visual marker. + + This assertion is expected to FAIL (via @tdd_expected_fail) because + build_decision_tree does not currently include a 'label' key in its + node dicts, and even if it did, it does not add visual markers for + corrected decisions (is_correction=True). This TDD scenario documents + the gap described in Spec Requirement #7. + """ + corrected_node = context.tdd_corrected_node + + # The label should be in the node's label field. + # build_decision_tree currently does NOT include a 'label' key in its + # node dicts -- this assertion will fail with AssertionError, proving + # the bug exists (Spec Requirement #7: corrected nodes must be visually + # marked in the plan tree output). + label = str(corrected_node.get("label", "")) + + # Check for common visual markers for corrections + markers = ["[corrected]", "\u270e", "[correction]", "\u270f", "[fix]", "[amended]"] + + has_marker = any(marker in label for marker in markers) + + assert has_marker, ( + f"Corrected decision label '{label}' does not contain any visual marker. " + f"Expected one of: {markers}. " + f"build_decision_tree does not currently add visual markers for " + f"decisions with is_correction=True (Spec Requirement #7 gap)." + ) diff --git a/features/tdd_plan_tree_correction_visual.feature b/features/tdd_plan_tree_correction_visual.feature new file mode 100644 index 000000000..200afa782 --- /dev/null +++ b/features/tdd_plan_tree_correction_visual.feature @@ -0,0 +1,23 @@ +@tdd_expected_fail +@tdd_issue +@tdd_issue_8576 +Feature: TDD: plan tree visually marks corrected nodes + Spec Requirement #7 states that `agents plan tree` should visually + distinguish corrected nodes (decisions with is_correction=True). + + This TDD scenario documents the gap: the current implementation does NOT + visually mark corrected nodes in the tree output. The tree renderer builds + node labels without checking decision.is_correction. + + Expected behavior: Corrected nodes should be marked with a visual indicator + such as [corrected], ✎, or similar annotation. + + # ------------------------------------------------------------------ + # Scenario: Corrected node is visually marked in tree output + # ------------------------------------------------------------------ + + Scenario: Corrected decision is visually marked in plan tree + Given a set of test decisions with a corrected decision + When I build the decision tree with default options + Then the tree should include a visual marker for the corrected decision + And the corrected decision label should contain "[corrected]" or "✎" or similar marker diff --git a/src/cleveragents/cli/commands/plan.py b/src/cleveragents/cli/commands/plan.py index 671b0d803..ebf897d24 100644 --- a/src/cleveragents/cli/commands/plan.py +++ b/src/cleveragents/cli/commands/plan.py @@ -4142,8 +4142,12 @@ def build_decision_tree( roots.append(d.decision_id) def _node_dict(d: Decision) -> dict[str, object]: + label = _get_decision_label(str(d.decision_type), 0) + if d.is_correction: + label = f"{label} [corrected]" return { "decision_id": d.decision_id, + "label": label, "type": str(d.decision_type), "sequence": d.sequence_number, "question": d.question, -- 2.52.0 From 7149f1b077cc339a8d7899ec95642abcf8755127 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Tue, 5 May 2026 03:20:18 +0000 Subject: [PATCH 2/3] test(plan-tree): add failing BDD scenario proving corrected nodes not visually marked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This TDD scenario documents the gap in Spec Requirement #7: the current implementation of 'agents plan tree' does not visually distinguish corrected nodes (decisions with is_correction=True). The scenario creates a plan with a corrected decision and asserts that the tree output contains a visual marker such as [corrected] or ✎. The scenario is tagged @tdd_expected_fail to allow CI to pass while the bug exists. The Rich tree renderer in tree_decisions_cmd builds node labels without checking decision.is_correction, proving the gap exists. - Revert production code change: remove label key and [corrected] marker from _node_dict in build_decision_tree (the TDD scenario must prove the bug exists, not fix it; the fix belongs in a separate PR) - Update CONTRIBUTORS.md with TDD scenario contribution entry - Add CHANGELOG.md entry for TDD scenario (#8576) - Remove dead _make_decision() helper (was already removed by prior attempt) - Remove # type: ignore[import-untyped] (was already removed by prior attempt) ISSUES CLOSED: #8576 --- CHANGELOG.md | 7 ++++++- CONTRIBUTORS.md | 1 + src/cleveragents/cli/commands/plan.py | 4 ---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7468885d2..2401e8813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -497,7 +497,12 @@ _ALL_DATA_COLUMNS + ") " "SELECT " + _ALL_DATA_COLUMNS + " FROM v3_plans"`. - **Quick Start Guide** (PR #9245): Added `docs/quickstart.md` with an end-to-end quick start guide covering prerequisites, installation, project creation, resource registration, plan/apply workflow, and troubleshooting. Updated `mkdocs.yml` navigation to include the Quick Start page. - **Plan checkpoint management CLI commands** (#8683): Added `agents plan checkpoint-list ` and `agents plan checkpoint-delete ` commands. Listing output now highlights checkpoint ID, type, created timestamp, reason, phase, and decision linkage with a concise field summary footer across rich/table/json/yaml formats. Deletion supports batch IDs, interactive confirmation (skip with `--yes`), and structured JSON/YAML responses for automation-friendly scripting. -- **Invariant Remove CLI Command** (#8530): Implemented `agents invariant remove ` command that soft-deletes an invariant by ID. The command displays a confirmation prompt before removal (bypassable with `--yes`/`-y`), outputs the removed invariant ID on success, and shows a clear error message when the invariant ID does not exist. Supports `--format` flag for JSON and YAML output. Full BDD test coverage and Robot Framework integration tests included. +- **Invariant Remove CLI Command** (#8530): Implemented `agents invariant remove ` command that soft-deletes an invariant by ID. The command displays a confirmation prompt before removal (bypassable with `--yes`/ `-y`), outputs the removed invariant ID on success, and shows a clear error message when the invariant ID does not exist. Supports `--format` flag for JSON and YAML output. Full BDD test coverage and Robot Framework integration tests included. +- **TDD: plan tree does not visually mark corrected nodes** (#8576): Added a failing + BDD scenario proving that corrected nodes (decisions with `is_correction=True`) are + not visually distinguished in the `agents plan tree` output. The scenario is tagged + `@tdd_expected_fail` and will pass (by inversion) until the underlying gap described + in Spec Requirement #7 is fixed. - **TDD: MCPToolAdapter.infer_resource_slots() TypeError with null properties** (#10470): Added a TDD issue-capture Behave scenario that reproduces the bug where `MCPToolAdapter.infer_resource_slots()` raises `TypeError` when the input schema diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3d08ce5b5..f6b1f79ff 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -68,3 +68,4 @@ Below are some of the specific details of various contributions. * HAL 9000 has contributed the plan correct JSON output envelope fix (PR #8662 / issue #8584): restructured `agents plan correct --format json` output to nest correction fields under `data.correction` and pass `command="plan correct"` to `format_output`, producing the spec-required CLI envelope. Added three BDD scenarios validating `data.correction.mode` (revert and append modes) and the `command` field. * HAL 9000 has contributed BDD feature file tag coverage improvements (#9124 / pr #9183): added required `@a2a`, `@session`, and `@cli` Gherkin tags to 30 feature files (8 A2A, 7 session, 15 CLI) to enable selective tag-based test filtering via `behave --tags=a2a,session,cli`. * HAL 9000 has contributed the plan tree JSON `decision_id` fix (#9096): updated `step_tree_json_valid` in features/steps/plan_explain_steps.py to correctly handle the {"data": [...]} envelope structure produced by format_output, and removed @tdd_expected_fail from the @tdd_issue_4254 scenario so it runs as a permanent regression guard. +* HAL 9000 has contributed the TDD scenario for plan tree correction visual marking (PR #8671 / issue #8576): added a failing BDD scenario proving that corrected nodes (decisions with is_correction=True) are not visually distinguished in the plan tree output, formalizing Spec Requirement #7 as an executable specification. diff --git a/src/cleveragents/cli/commands/plan.py b/src/cleveragents/cli/commands/plan.py index ebf897d24..671b0d803 100644 --- a/src/cleveragents/cli/commands/plan.py +++ b/src/cleveragents/cli/commands/plan.py @@ -4142,12 +4142,8 @@ def build_decision_tree( roots.append(d.decision_id) def _node_dict(d: Decision) -> dict[str, object]: - label = _get_decision_label(str(d.decision_type), 0) - if d.is_correction: - label = f"{label} [corrected]" return { "decision_id": d.decision_id, - "label": label, "type": str(d.decision_type), "sequence": d.sequence_number, "question": d.question, -- 2.52.0 From 42c83d149c1a45e60c0928c9b74007a695125692 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Tue, 2 Jun 2026 12:57:46 -0400 Subject: [PATCH 3/3] fix(test): rename ambiguous step to avoid conflict with plan_explain_steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The step "I build the decision tree with default options" was already defined in features/steps/plan_explain_steps.py:268. This caused behave.step_registry.AmbiguousStep during step loading, which crashed all 31 parallel workers before any scenario could run (0 scenarios, 31 errored at feature level). Rename the When step in the TDD feature and its step definition to "I build the correction TDD test decision tree" — unique across the entire features/steps/ directory. ISSUES CLOSED: #8576 --- features/steps/tdd_plan_tree_correction_visual_steps.py | 2 +- features/tdd_plan_tree_correction_visual.feature | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/features/steps/tdd_plan_tree_correction_visual_steps.py b/features/steps/tdd_plan_tree_correction_visual_steps.py index fec59c260..d68ea7363 100644 --- a/features/steps/tdd_plan_tree_correction_visual_steps.py +++ b/features/steps/tdd_plan_tree_correction_visual_steps.py @@ -74,7 +74,7 @@ def step_decisions_with_correction(context: Context) -> None: # --------------------------------------------------------------------------- -@when("I build the decision tree with default options") +@when("I build the correction TDD test decision tree") def step_build_tree_default(context: Context) -> None: """Build the decision tree from the test decisions.""" context.tdd_tree_data = build_decision_tree( diff --git a/features/tdd_plan_tree_correction_visual.feature b/features/tdd_plan_tree_correction_visual.feature index 200afa782..f36dac21e 100644 --- a/features/tdd_plan_tree_correction_visual.feature +++ b/features/tdd_plan_tree_correction_visual.feature @@ -18,6 +18,6 @@ Feature: TDD: plan tree visually marks corrected nodes Scenario: Corrected decision is visually marked in plan tree Given a set of test decisions with a corrected decision - When I build the decision tree with default options + When I build the correction TDD test decision tree Then the tree should include a visual marker for the corrected decision And the corrected decision label should contain "[corrected]" or "✎" or similar marker -- 2.52.0