Feature: Plan Domain Model As a developer I want a plan domain model that supports the lifecycle So that I can track plans through Strategize -> Execute -> Apply phases # NamespacedName Tests Scenario: Parse simple name defaults to local namespace When I parse the namespaced name "my-action" Then the parsed namespace should be "local" And the parsed item name should be "my-action" And the parsed server should be empty Scenario: Parse name with explicit local namespace When I parse the namespaced name "local/my-action" Then the parsed namespace should be "local" And the parsed item name should be "my-action" Scenario: Parse name with organization namespace When I parse the namespaced name "myorg/my-action" Then the parsed namespace should be "myorg" And the parsed item name should be "my-action" Scenario: Parse name with server qualifier When I parse the namespaced name "prod:myorg/my-action" Then the parsed server should be "prod" And the parsed namespace should be "myorg" And the parsed item name should be "my-action" Scenario: NamespacedName string representation Given I have a namespaced name with server "prod" namespace "myorg" and name "my-action" Then the namespaced string representation should be "prod:myorg/my-action" Scenario: NamespacedName without server Given I have a namespaced name with namespace "local" and name "test-plan" Then the namespaced string representation should be "local/test-plan" Scenario: Invalid namespace with special characters fails When I try to create a namespaced name with namespace "my@org" and name "test" Then a validation error should be raised Scenario: Empty namespace defaults to local Given I create a namespaced name with an empty namespace and name "test-plan" Then the parsed namespace should be "local" # PlanPhase Tests Scenario: Plan phases are in correct order Then the plan phases should be in order "action, strategize, execute, apply" Scenario: STRATEGIZE phase is the starting phase Given I create a new plan Then the plan phase should be "strategize" # PlanState Tests Scenario: New plan starts in STRATEGIZE with QUEUED processing state Given I create a plan in strategize phase Then the plan phase should be "strategize" And the plan processing state should be "queued" Scenario: Strategize phase uses ProcessingState Given I create a plan in strategize phase Then the plan processing state should be "queued" Scenario: Plan in strategize phase defaults to QUEUED processing state Given I create a plan in strategize phase Then the plan processing state should be "queued" And the plan state should be "queued" Scenario: Strategize phase defaults processing_state to QUEUED Given I create a plan in strategize phase Then the plan processing state should be "queued" # Plan Identity Tests Scenario: Plan requires valid ULID When I try to create a plan identity with invalid ULID "not-a-ulid" Then a validation error should be raised Scenario: Plan identity with valid ULID succeeds When I create a plan identity with ULID "01ARZ3NDEKTSV4RRFFQ69G5FAV" Then the plan identity should be valid Scenario: Plan identity supports parent and root plan IDs When I create a plan identity with parent "01ARZ3NDEKTSV4RRFFQ69G5FAV" and root "01ARZ3NDEKTSV4RRFFQ69G5FAW" Then the parent plan ID should be "01ARZ3NDEKTSV4RRFFQ69G5FAV" And the root plan ID should be "01ARZ3NDEKTSV4RRFFQ69G5FAW" # Plan Lifecycle Tests Scenario: New plan starts in STRATEGIZE phase with QUEUED state Given I create a new plan with description "Test plan" Then the plan phase should be "strategize" And the plan processing state should be "queued" And the plan should not be terminal Scenario: Plan in STRATEGIZE with QUEUED cannot transition Given I create a plan in strategize phase Then the plan cannot transition to next phase Scenario: New plan in STRATEGIZE with QUEUED cannot transition Given I create a plan in strategize phase Then the plan cannot transition to next phase Scenario: Processing complete allows transition Given I create a plan in execute phase with complete processing state Then the plan can transition to next phase Scenario: Get next phase from STRATEGIZE is EXECUTE Given I create a new plan Then the next phase should be "execute" Scenario: Get next phase from APPLY is None (terminal phase) Given I create a plan in apply phase as terminal Then the next phase should be empty Scenario: Unknown phase returns no next phase Given I create a plan with an unknown phase value Then the next phase should be empty # Phase Transition Validation Tests Scenario: Valid transition from STRATEGIZE to EXECUTE Then transition from "strategize" to "execute" should be valid Scenario: Valid transition from EXECUTE to APPLY Then transition from "execute" to "apply" should be valid Scenario: Valid transition from APPLY to STRATEGIZE (revert via constrained) Then transition from "apply" to "strategize" should be valid Scenario: Invalid transition from STRATEGIZE to APPLY Then transition from "strategize" to "apply" should be invalid Scenario: Valid transition from ACTION to STRATEGIZE Then transition from "action" to "strategize" should be valid # Error State Tests Scenario: Plan in errored state is_errored returns True Given I create a plan in strategize phase with errored state Then the plan should be errored Scenario: Plan in processing state is_errored returns False Given I create a plan in strategize phase with processing state Then the plan should not be errored Scenario: Cancelled plan is terminal Given I create a plan in strategize phase with cancelled state Then the plan should be terminal # Model Validation Tests Scenario: Plan requires description When I try to create a plan without description Then a validation error should be raised Scenario: Plan description cannot be empty When I try to create a plan with empty description Then a validation error should be raised Scenario: Invalid phase value raises validation error When I try to create a plan with invalid phase value Then a validation error should be raised Scenario: Apply phase cannot transition to next phase Given I create a plan in apply phase as terminal Then the plan cannot transition to next phase