Files
cleveragents-core/features/decision_model.feature
khyari hamza 229dbc8925 refactor(decision): address PR review feedback
- add with_superseded_by() helper for frozen model mutation
- document frozen model + superseded_by interaction in docstring
- clarify sequence_number uniqueness is a persistence concern
- add scenario for invalid corrects_decision_id ULID validation
- add scenario for with_superseded_by copy behavior
- type step helper dict as dict[str, Any]
2026-02-23 22:20:03 +00:00

247 lines
10 KiB
Gherkin

Feature: Decision domain model
Validates the Decision, DecisionType, ContextSnapshot, ResourceRef,
and ArtifactRef domain models including ULID validation, enum coverage,
tree structure helpers, correction constraints, and serialization.
# ------------------------------------------------------------------
# DecisionType enum
# ------------------------------------------------------------------
Scenario: All 11 decision types are defined
Then the DecisionType enum should have exactly 11 members
Scenario: Strategize-phase types are correctly classified
Then STRATEGIZE_TYPES should contain "prompt_definition"
And STRATEGIZE_TYPES should contain "invariant_enforced"
And STRATEGIZE_TYPES should contain "strategy_choice"
And STRATEGIZE_TYPES should contain "subplan_spawn"
And STRATEGIZE_TYPES should contain "subplan_parallel_spawn"
And STRATEGIZE_TYPES should have exactly 5 members
Scenario: Execute-phase types are correctly classified
Then EXECUTE_TYPES should contain "implementation_choice"
And EXECUTE_TYPES should contain "resource_selection"
And EXECUTE_TYPES should contain "tool_invocation"
And EXECUTE_TYPES should contain "error_recovery"
And EXECUTE_TYPES should contain "validation_response"
And EXECUTE_TYPES should have exactly 5 members
Scenario: user_intervention is not in either phase set
Then STRATEGIZE_TYPES should not contain "user_intervention"
And EXECUTE_TYPES should not contain "user_intervention"
# ------------------------------------------------------------------
# Decision creation and ULID validation
# ------------------------------------------------------------------
Scenario: Create a minimal root decision
Given a valid plan ULID
When I create a prompt_definition decision with sequence 0
Then the decision should be created successfully
And the decision should be a root decision
And the decision should have a valid ULID as decision_id
And the decision type should be "prompt_definition"
And the decision is_strategize_type should be true
Scenario: Create a non-root decision with parent
Given a valid plan ULID
And a valid parent decision ULID
When I create a strategy_choice decision with sequence 1 and a parent
Then the decision should be created successfully
And the decision should not be a root decision
And the decision is_strategize_type should be true
Scenario: Create an execute-phase decision
Given a valid plan ULID
And a valid parent decision ULID
When I create an implementation_choice decision with sequence 2 and a parent
Then the decision should be created successfully
And the decision is_execute_type should be true
And the decision is_strategize_type should be false
Scenario: user_intervention is valid in any phase
Given a valid plan ULID
When I create a user_intervention decision with sequence 3
Then the decision should be created successfully
And the decision is_any_phase_type should be true
Scenario: Invalid plan_id is rejected
When I try to create a decision with plan_id "not-a-ulid"
Then a decision validation error should be raised
And the decision error should mention "plan_id"
Scenario: Invalid parent_decision_id is rejected
Given a valid plan ULID
When I try to create a decision with parent_decision_id "bad-id"
Then a decision validation error should be raised
And the decision error should mention "parent_decision_id"
# ------------------------------------------------------------------
# prompt_definition root constraint
# ------------------------------------------------------------------
Scenario: prompt_definition with a parent is rejected
Given a valid plan ULID
And a valid parent decision ULID
When I try to create a prompt_definition with a parent
Then a decision validation error should be raised
And the decision error should mention "root"
# ------------------------------------------------------------------
# Confidence score validation
# ------------------------------------------------------------------
Scenario: Confidence score within valid range
Given a valid plan ULID
When I create a decision with confidence score 0.85
Then the decision should be created successfully
And the decision confidence score should be 0.85
Scenario: Confidence score of 0.0 is valid
Given a valid plan ULID
When I create a decision with confidence score 0.0
Then the decision should be created successfully
Scenario: Confidence score of 1.0 is valid
Given a valid plan ULID
When I create a decision with confidence score 1.0
Then the decision should be created successfully
Scenario: Confidence score above 1.0 is rejected
Given a valid plan ULID
When I try to create a decision with confidence score 1.5
Then a decision validation error should be raised
Scenario: Confidence score below 0.0 is rejected
Given a valid plan ULID
When I try to create a decision with confidence score -0.1
Then a decision validation error should be raised
Scenario: Confidence score of None is valid
Given a valid plan ULID
When I create a decision with confidence score None
Then the decision should be created successfully
And the decision confidence score should be None
# ------------------------------------------------------------------
# Correction metadata
# ------------------------------------------------------------------
Scenario: Create a correction decision
Given a valid plan ULID
And a valid corrected decision ULID
When I create a correction decision
Then the decision should be created successfully
And the decision is_correction should be true
Scenario: is_correction without corrects_decision_id is rejected
Given a valid plan ULID
When I try to create a decision with is_correction true but no corrects_decision_id
Then a decision validation error should be raised
And the decision error should mention "corrects_decision_id"
Scenario: corrects_decision_id without is_correction is rejected
Given a valid plan ULID
And a valid corrected decision ULID
When I try to create a decision with corrects_decision_id but is_correction false
Then a decision validation error should be raised
And the decision error should mention "is_correction"
Scenario: superseded_by marks decision as superseded
Given a valid plan ULID
When I create a decision that is superseded
Then the decision is_superseded should be true
Scenario: Invalid superseded_by ULID is rejected
Given a valid plan ULID
When I try to create a decision with superseded_by "invalid"
Then a decision validation error should be raised
And the decision error should mention "superseded_by"
Scenario: Invalid corrects_decision_id ULID is rejected
Given a valid plan ULID
When I try to create a decision with corrects_decision_id ULID "not-valid"
Then a decision validation error should be raised
And the decision error should mention "corrects_decision_id"
Scenario: with_superseded_by returns a new superseded copy
Given a valid plan ULID
When I create a prompt_definition decision with sequence 0
And I call with_superseded_by on the decision
Then the original decision should not be superseded
And the superseded copy should be superseded
# ------------------------------------------------------------------
# ContextSnapshot
# ------------------------------------------------------------------
Scenario: Create a decision with a populated context snapshot
Given a valid plan ULID
And a context snapshot with hash and resources
When I create a decision with the context snapshot
Then the decision should be created successfully
And the decision context snapshot hash should not be empty
And the decision context snapshot should have resources
Scenario: Default context snapshot is empty
Given a valid plan ULID
When I create a prompt_definition decision with sequence 0
Then the decision context snapshot hash should be empty
# ------------------------------------------------------------------
# ResourceRef and ArtifactRef
# ------------------------------------------------------------------
Scenario: ResourceRef requires non-empty resource_id
When I try to create a ResourceRef with empty resource_id
Then a decision validation error should be raised
Scenario: ArtifactRef requires non-empty artifact_path
When I try to create an ArtifactRef with empty artifact_path
Then a decision validation error should be raised
Scenario: Decision with artifacts_produced
Given a valid plan ULID
When I create a decision with artifacts
Then the decision should have 2 artifacts produced
# ------------------------------------------------------------------
# Serialization
# ------------------------------------------------------------------
Scenario: Decision round-trips through dict serialization
Given a valid plan ULID
When I create a fully populated decision
Then the decision should round-trip through model_dump and model_validate
Scenario: as_cli_dict returns expected keys
Given a valid plan ULID
When I create a prompt_definition decision with sequence 0
Then as_cli_dict should contain key "decision_id"
And as_cli_dict should contain key "type"
And as_cli_dict should contain key "confidence"
And as_cli_dict should contain key "parent"
# ------------------------------------------------------------------
# All 11 decision types can be instantiated
# ------------------------------------------------------------------
Scenario Outline: Each decision type can be instantiated
Given a valid plan ULID
When I create a decision of type "<dtype>"
Then the decision should be created successfully
Examples:
| dtype |
| prompt_definition |
| invariant_enforced |
| strategy_choice |
| implementation_choice |
| resource_selection |
| subplan_spawn |
| subplan_parallel_spawn |
| tool_invocation |
| error_recovery |
| validation_response |
| user_intervention |