Files
cleveragents-core/features/domain_model_immutability.feature
HAL9000 0125c15039 fix(domain): enforce immutability on Plan and Action identity fields
Freeze PlanIdentity (plan_id, parent_plan_id, root_plan_id) and
NamespacedName (name, namespace) using Pydantic frozen=True.
Block PlanTimestamps.created_at reassignment via __setattr__ override.
Mutable state fields (phase, processing_state, updated_at, etc.) remain
fully assignable. Add 17 Behave scenarios verifying all invariants.

ISSUES CLOSED: #7553
2026-04-20 06:08:50 +00:00

109 lines
5.4 KiB
Gherkin

Feature: Domain Model Immutability — Plan and Action Identity Fields
As a developer working with the CleverAgents domain model
I want Plan and Action identity fields to be read-only after construction
So that core identity invariants cannot be accidentally violated
# ============================================================
# Plan.identity.plan_id read-only after construction
# ============================================================
Scenario: Plan identity plan_id is set correctly at construction
Given I create a Plan with a known ULID plan_id
Then the plan identity plan_id should match the known ULID
Scenario: Plan identity plan_id cannot be reassigned after construction
Given I create a Plan with a known ULID plan_id
When I attempt to reassign the plan identity plan_id
Then a frozen model error should be raised for plan_id
Scenario: Plan identity root_plan_id is auto-resolved to plan_id when not provided
Given I create a Plan without specifying root_plan_id
Then the plan identity root_plan_id should equal the plan_id
Scenario: Plan identity root_plan_id cannot be reassigned after construction
Given I create a Plan with a known ULID plan_id
When I attempt to reassign the plan identity root_plan_id
Then a frozen model error should be raised for root_plan_id
# ============================================================
# Plan.timestamps.created_at — read-only after construction
# ============================================================
Scenario: Plan timestamps created_at is set at construction
Given I create a Plan with a specific created_at timestamp
Then the plan timestamps created_at should match the specified timestamp
Scenario: Plan timestamps created_at cannot be reassigned after construction
Given I create a Plan with a specific created_at timestamp
When I attempt to reassign the plan timestamps created_at
Then an AttributeError should be raised for created_at
Scenario: Plan timestamps updated_at remains mutable after construction
Given I create a Plan with a specific created_at timestamp
When I update the plan timestamps updated_at to a new datetime
Then the plan timestamps updated_at should reflect the new datetime
Scenario: Plan timestamps strategize_started_at remains mutable after construction
Given I create a Plan with a specific created_at timestamp
When I set the plan timestamps strategize_started_at to a new datetime
Then the plan timestamps strategize_started_at should reflect the new datetime
# ============================================================
# Action.namespaced_name.name — read-only after construction
# ============================================================
Scenario: Action namespaced_name name is set correctly at construction
Given I create an Action with namespaced name "myorg/my-action"
Then the action namespaced_name name should be "my-action"
Scenario: Action namespaced_name name cannot be reassigned after construction
Given I create an Action with namespaced name "myorg/my-action"
When I attempt to reassign the action namespaced_name name
Then a frozen model error should be raised for action name
# ============================================================
# Action.namespaced_name.namespace — read-only after construction
# ============================================================
Scenario: Action namespaced_name namespace is set correctly at construction
Given I create an Action with namespaced name "myorg/my-action"
Then the action namespaced_name namespace should be "myorg"
Scenario: Action namespaced_name namespace cannot be reassigned after construction
Given I create an Action with namespaced name "myorg/my-action"
When I attempt to reassign the action namespaced_name namespace
Then a frozen model error should be raised for action namespace
# ============================================================
# Mutable state fields remain mutable
# ============================================================
Scenario: Plan phase remains mutable after construction
Given I create a Plan in STRATEGIZE phase
When I update the plan phase to EXECUTE
Then the plan phase should be EXECUTE
Scenario: Plan processing_state remains mutable after construction
Given I create a Plan in STRATEGIZE phase
When I update the plan processing_state to PROCESSING
Then the plan processing_state should be PROCESSING
Scenario: Action state remains mutable after construction
Given I create an Action with namespaced name "local/test-action"
When I update the action state to archived
Then the action state should be archived
# ============================================================
# NamespacedName frozen model — Plan context
# ============================================================
Scenario: Plan namespaced_name name cannot be reassigned after construction
Given I create a Plan with namespaced name "local/my-plan"
When I attempt to reassign the plan namespaced_name name
Then a frozen model error should be raised for plan namespaced name
Scenario: Plan namespaced_name namespace cannot be reassigned after construction
Given I create a Plan with namespaced name "local/my-plan"
When I attempt to reassign the plan namespaced_name namespace
Then a frozen model error should be raised for plan namespaced namespace