diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 62a76a4bc..1618dc65a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -14,5 +14,5 @@ Below are some of the specific details of various contributions. * Jeffrey Phillips Freeman has acted as Lead Developer, daily contributor, and Project Owner. * Brent E. Edwards has contributed quality assurance, test coverage, and CI pipeline improvements. -* HAL 9000 has contributed automated implementation, bug fixes, and feature development as part of the CleverAgents automation pool. +* HAL 9000 has contributed automated implementation, bug fixes, feature development, and TDD issue-capture test scenarios as part of the CleverAgents automation pool. * This project was made possible thanks to considerable donation of time, money, and resources by CleverThis, Inc. diff --git a/features/steps/tdd_plan_tree_correction_visual_steps.py b/features/steps/tdd_plan_tree_correction_visual_steps.py index bc2002671..fec59c260 100644 --- a/features/steps/tdd_plan_tree_correction_visual_steps.py +++ b/features/steps/tdd_plan_tree_correction_visual_steps.py @@ -7,7 +7,7 @@ where the current implementation does NOT visually distinguish corrected nodes. from __future__ import annotations -from behave import given, then, when # type: ignore[import-untyped] +from behave import given, then, when from behave.runner import Context from ulid import ULID @@ -15,28 +15,12 @@ from cleveragents.cli.commands.plan import build_decision_tree from cleveragents.domain.models.core.decision import Decision, DecisionType # --------------------------------------------------------------------------- -# Helpers +# Constants # --------------------------------------------------------------------------- _PLAN_ID = str(ULID()) -def _make_decision(**overrides: object) -> Decision: - """Build a Decision with sensible defaults.""" - defaults: dict[str, object] = { - "plan_id": _PLAN_ID, - "sequence_number": 0, - "decision_type": DecisionType.PROMPT_DEFINITION, - "question": "What should we build?", - "chosen_option": "A REST API", - } - dt = overrides.get("decision_type", defaults["decision_type"]) - if dt != DecisionType.PROMPT_DEFINITION and "parent_decision_id" not in overrides: - defaults["parent_decision_id"] = str(ULID()) - defaults.update(overrides) - return Decision(**defaults) - - # --------------------------------------------------------------------------- # Given steps # --------------------------------------------------------------------------- @@ -108,23 +92,27 @@ def step_build_tree_default(context: Context) -> None: @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_data = context.tdd_tree_data + tree_nodes: list[dict[str, object]] = context.tdd_tree_data - # The tree_data is a dict representation of the tree structure + # 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 + # and verify it has a visual marker. - def find_corrected_node(node: dict) -> dict | None: + def find_corrected_node( + nodes: list[dict[str, object]], + ) -> dict[str, object] | None: """Recursively search for the corrected decision node.""" - if node.get("decision_id") == context.tdd_corrected_id: - return node - for child in node.get("children", []): - result = find_corrected_node(child) - if result: + 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_data) + corrected_node = find_corrected_node(tree_nodes) assert corrected_node is not None, ( f"Corrected decision {context.tdd_corrected_id} not found in tree" ) @@ -137,18 +125,31 @@ def step_tree_has_correction_marker(context: Context) -> None: '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.""" + """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 or display_label field - label = corrected_node.get("label", "") + # 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]", "✎", "[correction]", "✏", "[fix]", "[amended]"] + 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"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)." )