0125c15039
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
109 lines
5.4 KiB
Gherkin
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
|