Files
cleveragents-core/features/decision_persistence.feature
T
khyari hamza 27bef69ddd feat(decision): add decision persistence
Add decision persistence layer with DecisionRepository, DecisionModel,
and Alembic migration. Includes tree queries (BFS traversal via deque,
path-to-root), superseded lookup, ordered decision path retrieval,
concrete Decision type annotations (via TYPE_CHECKING), and comprehensive
test coverage (Behave BDD, Robot Framework, ASV benchmarks). Updated
database_schema.md, CHANGELOG.md, and CONTRIBUTORS.md.

ISSUES CLOSED: #171
2026-02-26 13:40:07 +00:00

150 lines
6.3 KiB
Gherkin

Feature: Decision persistence via DecisionRepository
As a developer
I want decisions to persist correctly through the DecisionRepository
So that the decision tree is durable across operations
Background:
Given a fresh in-memory decision persistence database
And a prerequisite action "local/decision-action" exists for decisions
And a prerequisite plan exists for decisions
# ------------------------------------------------------------------
# Create and retrieve
# ------------------------------------------------------------------
Scenario: Create a root decision and retrieve it by ID
Given a new root decision with sequence 0
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision type should be "prompt_definition"
And the persisted decision should be a root
Scenario: Create a child decision and retrieve it
Given a persisted root decision
And a new child decision of type "strategy_choice" with sequence 1
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision should not be a root
And the persisted decision parent should match the root
Scenario: Persisted decision preserves all scalar fields
Given a new root decision with all fields populated
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision question should match
And the persisted decision chosen_option should match
And the persisted decision confidence_score should be 0.85
And the persisted decision rationale should match
# ------------------------------------------------------------------
# JSON round-trip
# ------------------------------------------------------------------
Scenario: Alternatives considered round-trip through JSON
Given a new decision with 3 alternatives
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision should have 3 alternatives
Scenario: Context snapshot round-trip through JSON
Given a new decision with a populated context snapshot
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision context hash should be "sha256:persist-test"
And the persisted decision context should have 2 resources
Scenario: Artifacts produced round-trip through JSON
Given a new decision with 2 artifacts
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision should have 2 artifacts
Scenario: Downstream IDs round-trip through JSON
Given a new decision with downstream IDs
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision should have downstream decision IDs
And the persisted decision should have downstream plan IDs
# ------------------------------------------------------------------
# Get by plan
# ------------------------------------------------------------------
Scenario: Get decisions by plan returns ordered results
Given 3 persisted decisions for the same plan
When I get decisions by plan ID
Then I should get 3 decisions in sequence order
# ------------------------------------------------------------------
# Get tree (BFS)
# ------------------------------------------------------------------
Scenario: Get tree returns root and descendants in BFS order
Given a persisted decision tree with 3 levels
When I get the decision tree from the root
Then the tree should have 4 decisions
And the first decision in the tree should be the root
# ------------------------------------------------------------------
# Get path to root
# ------------------------------------------------------------------
Scenario: Get path to root walks from leaf to root
Given a persisted decision tree with 3 levels
When I get the path from a leaf to root
Then the path should start with the leaf
And the path should end with the root
# ------------------------------------------------------------------
# Correction and superseded
# ------------------------------------------------------------------
Scenario: Create a correction decision
Given a persisted root decision
And a correction decision that corrects the root
When I persist the decision via the decision repository
Then I can retrieve the decision by its ID
And the persisted decision is_correction should be true
Scenario: Update superseded_by on an existing decision
Given a persisted root decision
When I update the root decision superseded_by to a new ULID
Then the root decision should be marked as superseded
Scenario: Get superseded decisions for a plan
Given a persisted root decision that is superseded
When I get superseded decisions for the plan
Then I should get 1 superseded decision
# ------------------------------------------------------------------
# List by type
# ------------------------------------------------------------------
Scenario: List decisions by type filters correctly
Given 2 persisted decisions of type "strategy_choice"
And 1 persisted decision of type "implementation_choice"
When I list decisions by type "strategy_choice"
Then I should get 2 decisions of that type
# ------------------------------------------------------------------
# Delete
# ------------------------------------------------------------------
Scenario: Delete a decision by ID
Given a persisted root decision
When I delete the root decision
Then the root decision should no longer exist
Scenario: Delete a non-existent decision returns false
When I try to delete a non-existent decision
Then the decision delete result should be false
# ------------------------------------------------------------------
# Duplicate detection
# ------------------------------------------------------------------
Scenario: Creating a duplicate decision raises DuplicateDecisionError
Given a persisted root decision
When I try to persist the same decision again
Then a DuplicateDecisionError should be raised