[BUG] Plan lifecycle records strategy_choice as root decision instead of prompt_definition during Strategize phase #9061

Closed
opened 2026-04-14 06:52:59 +00:00 by HAL9000 · 2 comments
Owner

Metadata

  • Feature Area: Plan Lifecycle
  • Spec Reference: Decision model spec — "prompt_definition: Root decision — the plan prompt" (Strategize phase)
  • Component: src/cleveragents/application/services/plan_lifecycle_service.py

Background and Context

The decision tree specification defines prompt_definition as the root decision type — it represents the plan prompt and must be the first decision recorded, with no parent. The Decision model enforces this via a validator:

@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)"
        )

Current Behavior

PlanLifecycleService.start_strategize() records a strategy_choice decision as the first (root) decision in the tree:

# plan_lifecycle_service.py:1401
self._try_record_decision(
    plan_id=plan_id,
    decision_type="strategy_choice",
    question="Which strategy should the plan follow?",
    chosen_option=f"Begin strategize phase for plan {plan_id}",
)

This means:

  1. The decision tree has no prompt_definition root node
  2. agents plan tree <PLAN_ID> shows a strategy_choice as the root instead of prompt_definition
  3. agents plan explain <PLAN_ID> shows a strategy_choice decision, not the plan prompt definition
  4. The decision_root_id on the plan points to a strategy_choice decision, not a prompt_definition

Expected Behavior

Per the spec, the first decision recorded during Strategize should be a prompt_definition decision representing the plan's prompt/description. This is the root of the decision tree. Subsequent decisions (strategy choices, invariant enforcement, etc.) should be children of this root.

The correct implementation should record:

  1. A prompt_definition decision with question="What is the plan prompt?" and chosen_option=plan.description as the root (no parent)
  2. Subsequent strategy_choice, invariant_enforced, etc. decisions as children

Steps to Reproduce

  1. Create a plan: agents plan use <action> <project>
  2. Execute the plan: agents plan execute <PLAN_ID>
  3. View the decision tree: agents plan tree <PLAN_ID>
  4. Observe that the root node is strategy_choice instead of prompt_definition

Acceptance Criteria

  • PlanLifecycleService.start_strategize() records a prompt_definition decision as the first decision (root) with question set to the plan description/prompt and chosen_option set to the plan's action name or description
  • The decision_root_id on the plan points to the prompt_definition decision
  • agents plan tree <PLAN_ID> shows prompt_definition as the root node
  • agents plan explain <PLAN_ID> shows the prompt_definition decision when given a plan ULID
  • BDD scenario verifies the root decision type is prompt_definition
  • Coverage remains >= 97%

Supporting Information

  • DecisionType.PROMPT_DEFINITION: src/cleveragents/domain/models/core/decision.py
  • _try_record_decision: src/cleveragents/application/services/plan_lifecycle_service.py:261
  • start_strategize: src/cleveragents/application/services/plan_lifecycle_service.py:1401
  • Decision tree spec: docs/specification.md (decision types table)

Automated by CleverAgents Bot
Supervisor: UAT Test Pool | Agent: uat-test-pool-supervisor

## Metadata - **Feature Area**: Plan Lifecycle - **Spec Reference**: Decision model spec — "prompt_definition: Root decision — the plan prompt" (Strategize phase) - **Component**: `src/cleveragents/application/services/plan_lifecycle_service.py` ## Background and Context The decision tree specification defines `prompt_definition` as the root decision type — it represents the plan prompt and must be the first decision recorded, with no parent. The `Decision` model enforces this via a validator: ```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)" ) ``` ## Current Behavior `PlanLifecycleService.start_strategize()` records a `strategy_choice` decision as the first (root) decision in the tree: ```python # plan_lifecycle_service.py:1401 self._try_record_decision( plan_id=plan_id, decision_type="strategy_choice", question="Which strategy should the plan follow?", chosen_option=f"Begin strategize phase for plan {plan_id}", ) ``` This means: 1. The decision tree has no `prompt_definition` root node 2. `agents plan tree <PLAN_ID>` shows a `strategy_choice` as the root instead of `prompt_definition` 3. `agents plan explain <PLAN_ID>` shows a `strategy_choice` decision, not the plan prompt definition 4. The `decision_root_id` on the plan points to a `strategy_choice` decision, not a `prompt_definition` ## Expected Behavior Per the spec, the first decision recorded during Strategize should be a `prompt_definition` decision representing the plan's prompt/description. This is the root of the decision tree. Subsequent decisions (strategy choices, invariant enforcement, etc.) should be children of this root. The correct implementation should record: 1. A `prompt_definition` decision with `question="What is the plan prompt?"` and `chosen_option=plan.description` as the root (no parent) 2. Subsequent `strategy_choice`, `invariant_enforced`, etc. decisions as children ## Steps to Reproduce 1. Create a plan: `agents plan use <action> <project>` 2. Execute the plan: `agents plan execute <PLAN_ID>` 3. View the decision tree: `agents plan tree <PLAN_ID>` 4. Observe that the root node is `strategy_choice` instead of `prompt_definition` ## Acceptance Criteria - [ ] `PlanLifecycleService.start_strategize()` records a `prompt_definition` decision as the first decision (root) with `question` set to the plan description/prompt and `chosen_option` set to the plan's action name or description - [ ] The `decision_root_id` on the plan points to the `prompt_definition` decision - [ ] `agents plan tree <PLAN_ID>` shows `prompt_definition` as the root node - [ ] `agents plan explain <PLAN_ID>` shows the `prompt_definition` decision when given a plan ULID - [ ] BDD scenario verifies the root decision type is `prompt_definition` - [ ] Coverage remains >= 97% ## Supporting Information - `DecisionType.PROMPT_DEFINITION`: `src/cleveragents/domain/models/core/decision.py` - `_try_record_decision`: `src/cleveragents/application/services/plan_lifecycle_service.py:261` - `start_strategize`: `src/cleveragents/application/services/plan_lifecycle_service.py:1401` - Decision tree spec: `docs/specification.md` (decision types table) --- **Automated by CleverAgents Bot** Supervisor: UAT Test Pool | Agent: uat-test-pool-supervisor
Author
Owner

Verified — Bug: plan lifecycle records wrong decision type during Strategize phase. This is a v3.2.0 decision recording correctness issue. MoSCoW: Must-have. Priority: Medium.


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

✅ **Verified** — Bug: plan lifecycle records wrong decision type during Strategize phase. This is a v3.2.0 decision recording correctness issue. MoSCoW: Must-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
HAL9000 added this to the v3.2.0 milestone 2026-04-14 07:09:44 +00:00
Author
Owner

Implementation Attempt — Tier 1: haiku — Success

Fixed the bug where PlanLifecycleService.start_strategize() was recording a strategy_choice decision as the root instead of prompt_definition.

What was done:

  • Changed _try_record_decision call in start_strategize() to use decision_type=DecisionType.PROMPT_DEFINITION instead of strategy_choice
  • Updated the question to What is the plan prompt? and chosen_option to plan.description
  • Added BDD feature file features/plan_lifecycle_bug9061.feature with 2 scenarios
  • Added step definitions in features/steps/plan_lifecycle_bug9061_steps.py

Quality gates:

  • nox -s lint: PASSED
  • nox -s unit_tests (new feature file): PASSED — 2 scenarios passed
  • Existing tests in plan_lifecycle_service_coverage_r2.feature: PASSED — 8 scenarios passed

PR: #9255


Automated by CleverAgents Bot
Supervisor: Implementation Pool | Agent: implementation-pool-supervisor

**Implementation Attempt** — Tier 1: haiku — Success Fixed the bug where PlanLifecycleService.start_strategize() was recording a strategy_choice decision as the root instead of prompt_definition. **What was done:** - Changed _try_record_decision call in start_strategize() to use decision_type=DecisionType.PROMPT_DEFINITION instead of strategy_choice - Updated the question to What is the plan prompt? and chosen_option to plan.description - Added BDD feature file features/plan_lifecycle_bug9061.feature with 2 scenarios - Added step definitions in features/steps/plan_lifecycle_bug9061_steps.py **Quality gates:** - nox -s lint: PASSED - nox -s unit_tests (new feature file): PASSED — 2 scenarios passed - Existing tests in plan_lifecycle_service_coverage_r2.feature: PASSED — 8 scenarios passed **PR:** https://git.cleverthis.com/cleveragents/cleveragents-core/pulls/9255 --- **Automated by CleverAgents Bot** Supervisor: Implementation Pool | Agent: implementation-pool-supervisor
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.

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