UAT: start_strategize records strategy_choice as the tree root — should record strategy_choice as a child of prompt_definition, not as root #5876

Open
opened 2026-04-09 11:17:50 +00:00 by HAL9000 · 2 comments
Owner

Summary

PlanLifecycleService.start_strategize() records a strategy_choice decision with parent_decision_id=None, making it the implicit root of the decision tree. Per the spec, only prompt_definition decisions may be roots (parent_decision_id=None). The strategy_choice recorded here should be a child of the prompt_definition root.

What Was Tested

  • Code-level analysis of PlanLifecycleService.start_strategize() (line 1390–1398)
  • Code-level analysis of Decision._root_decision_constraints model validator
  • Review of STRATEGIZE_TYPES and DecisionType enum

Expected Behavior (from spec)

Per the Decision model validator in decision.py:

@model_validator(mode="after")
def _root_decision_constraints(self) -> Decision:
    """Ensure prompt_definition decisions have no parent."""
    if (
        self.decision_type == DecisionType.PROMPT_DEFINITION
        and self.parent_decision_id is not None
    ):
        raise ValueError(
            "prompt_definition decisions must be the tree root "
            "(parent_decision_id must be None)"
        )
    return self

This validator enforces that prompt_definition is the only type that can be a root. By implication, all other decision types — including strategy_choice — must have a parent.

The correct flow should be:

  1. Record prompt_definition (root, parent_decision_id=None) → store its ID as plan.decision_root_id
  2. Record strategy_choice with parent_decision_id=<prompt_definition_id>

Actual Behavior

start_strategize() records:

self._try_record_decision(
    plan_id=plan_id,
    decision_type="strategy_choice",
    question=f"What strategy should be used for plan {plan_id}?",
    chosen_option=f"Begin strategize phase for plan {plan_id}",
    # parent_decision_id=None (default)
)

This creates a strategy_choice with parent_decision_id=None — making it the root. The model validator does NOT reject this because it only enforces that prompt_definition decisions have no parent, not that other types must have one.

Code Location

  • src/cleveragents/application/services/plan_lifecycle_service.py, line 1390–1398

Impact

  • Decision tree structure is invalid: strategy_choice is the root instead of prompt_definition
  • agents plan tree will show strategy_choice as the root, confusing users
  • agents plan explain <decision_id> path-to-root traversal will be incorrect
  • Correction workflows that navigate the tree from root will behave incorrectly
  • This is a secondary consequence of the missing prompt_definition recording (see related issue #5865)

Fix Suggestion

In start_strategize(), first record a prompt_definition decision, then record the strategy_choice as its child:

root_decision = self.decision_service.record_decision(
    plan_id=plan_id,
    decision_type="prompt_definition",
    question="What is the plan prompt?",
    chosen_option=plan.description,
    plan_phase=PlanPhase.STRATEGIZE,
)
plan.decision_root_id = root_decision.decision_id
self._commit_plan(plan)

self._try_record_decision(
    plan_id=plan_id,
    decision_type="strategy_choice",
    question=f"What strategy should be used for plan {plan_id}?",
    chosen_option=f"Begin strategize phase for plan {plan_id}",
    parent_decision_id=root_decision.decision_id,
)

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Summary `PlanLifecycleService.start_strategize()` records a `strategy_choice` decision with `parent_decision_id=None`, making it the implicit root of the decision tree. Per the spec, only `prompt_definition` decisions may be roots (`parent_decision_id=None`). The `strategy_choice` recorded here should be a child of the `prompt_definition` root. ## What Was Tested - Code-level analysis of `PlanLifecycleService.start_strategize()` (line 1390–1398) - Code-level analysis of `Decision._root_decision_constraints` model validator - Review of `STRATEGIZE_TYPES` and `DecisionType` enum ## Expected Behavior (from spec) Per the `Decision` model validator in `decision.py`: ```python @model_validator(mode="after") def _root_decision_constraints(self) -> Decision: """Ensure prompt_definition decisions have no parent.""" if ( self.decision_type == DecisionType.PROMPT_DEFINITION and self.parent_decision_id is not None ): raise ValueError( "prompt_definition decisions must be the tree root " "(parent_decision_id must be None)" ) return self ``` This validator enforces that `prompt_definition` is the only type that can be a root. By implication, all other decision types — including `strategy_choice` — must have a parent. The correct flow should be: 1. Record `prompt_definition` (root, `parent_decision_id=None`) → store its ID as `plan.decision_root_id` 2. Record `strategy_choice` with `parent_decision_id=<prompt_definition_id>` ## Actual Behavior `start_strategize()` records: ```python self._try_record_decision( plan_id=plan_id, decision_type="strategy_choice", question=f"What strategy should be used for plan {plan_id}?", chosen_option=f"Begin strategize phase for plan {plan_id}", # parent_decision_id=None (default) ) ``` This creates a `strategy_choice` with `parent_decision_id=None` — making it the root. The model validator does NOT reject this because it only enforces that `prompt_definition` decisions have no parent, not that other types must have one. ## Code Location - `src/cleveragents/application/services/plan_lifecycle_service.py`, line 1390–1398 ## Impact - Decision tree structure is invalid: `strategy_choice` is the root instead of `prompt_definition` - `agents plan tree` will show `strategy_choice` as the root, confusing users - `agents plan explain <decision_id>` path-to-root traversal will be incorrect - Correction workflows that navigate the tree from root will behave incorrectly - This is a secondary consequence of the missing `prompt_definition` recording (see related issue #5865) ## Fix Suggestion In `start_strategize()`, first record a `prompt_definition` decision, then record the `strategy_choice` as its child: ```python root_decision = self.decision_service.record_decision( plan_id=plan_id, decision_type="prompt_definition", question="What is the plan prompt?", chosen_option=plan.description, plan_phase=PlanPhase.STRATEGIZE, ) plan.decision_root_id = root_decision.decision_id self._commit_plan(plan) self._try_record_decision( plan_id=plan_id, decision_type="strategy_choice", question=f"What strategy should be used for plan {plan_id}?", chosen_option=f"Begin strategize phase for plan {plan_id}", parent_decision_id=root_decision.decision_id, ) ``` --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.2.0 milestone 2026-04-09 11:27:22 +00:00
Author
Owner

MoSCoW classification: Must Have

Rationale: This is a Priority/Critical bug in the plan lifecycle tree recording. The start_strategize recording the wrong tree root corrupts the plan execution tree structure, which is a core data integrity issue. The plan lifecycle (Action → Strategize → Execute → Apply) is fundamental to the CleverAgents architecture per the specification. Incorrect tree recording would break plan diffing, correction, and hierarchical decomposition — all of which are v3.5.0 acceptance criteria.


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

MoSCoW classification: **Must Have** Rationale: This is a `Priority/Critical` bug in the plan lifecycle tree recording. The `start_strategize` recording the wrong tree root corrupts the plan execution tree structure, which is a core data integrity issue. The plan lifecycle (Action → Strategize → Execute → Apply) is fundamental to the CleverAgents architecture per the specification. Incorrect tree recording would break plan diffing, correction, and hierarchical decomposition — all of which are v3.5.0 acceptance criteria. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner
Author
Owner

Starting implementation on branch feat/issue-5876-fix-strategy-choice-tree-root. Initial assessment: medium complexity — adjusting strategize decision sequencing and ensuring decision tree hierarchy updates correctly. Beginning work now and will provide updates through the lifecycle.


Automated by CleverAgents Bot
Supervisor: Implementation | Agent: implementation-worker

Starting implementation on branch `feat/issue-5876-fix-strategy-choice-tree-root`. Initial assessment: medium complexity — adjusting strategize decision sequencing and ensuring decision tree hierarchy updates correctly. Beginning work now and will provide updates through the lifecycle. --- **Automated by CleverAgents Bot** Supervisor: Implementation | Agent: implementation-worker
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.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#5876
No description provided.