@feature921 Feature: v3_plans table schema alignment with spec DDL As a database administrator I want the v3_plans table schema to match the specification DDL So that nullability, defaults, and columns are correct Background: Given a schema-aligned fresh in-memory database And a schema-aligned prerequisite action "local/schema-test" exists @feature921 Scenario: Plan creation includes effective_profile_snapshot Given a schema-aligned plan with ID "01HV000000000000000000SA01" And the plan effective_profile_snapshot is '{"profile":"balanced","thresholds":{}}' When I persist the schema-aligned plan Then the retrieved plan effective_profile_snapshot should be '{"profile":"balanced","thresholds":{}}' @feature921 Scenario: Plan creation with default effective_profile_snapshot Given a schema-aligned plan with ID "01HV000000000000000000SA02" When I persist the schema-aligned plan Then the retrieved plan effective_profile_snapshot should be '{}' @feature921 Scenario: Root plan has self-referencing root_plan_id Given a schema-aligned root plan with ID "01HV000000000000000000SA03" When I persist the schema-aligned plan Then the plan root_plan_id should equal the plan_id "01HV000000000000000000SA03" @feature921 Scenario: Child plan has parent root_plan_id Given a schema-aligned root plan with ID "01HV000000000000000000SA04" And a schema-aligned child plan with ID "01HV000000000000000000SA05" parent "01HV000000000000000000SA04" root "01HV000000000000000000SA04" When I persist both schema-aligned plans Then the child plan root_plan_id should be "01HV000000000000000000SA04" And the child plan parent_plan_id should be "01HV000000000000000000SA04" @feature921 Scenario: automation_profile defaults to balanced for plans without profile Given a schema-aligned plan with ID "01HV000000000000000000SA06" and no automation profile When I persist the schema-aligned plan Then the persisted automation_profile column should be "balanced" @feature921 Scenario: Bare-string automation_profile deserializes gracefully Given a schema-aligned plan with ID "01HV000000000000000000SA07" And the plan automation_profile column is set to bare string "full-auto" When I load the plan from the database Then the plan automation_profile ref should be None @feature921 Scenario: Invalid provenance in automation_profile JSON deserializes gracefully Given a schema-aligned plan with ID "01HV000000000000000000SA08" And the plan automation_profile column is set to '{"profile_name":"test","provenance":"bogus"}' When I load the plan from the database Then the plan automation_profile ref should be None @feature921 Scenario: Grandchild plan carries root ancestor plan_id Given a schema-aligned root plan with ID "01HV000000000000000000SA10" And a schema-aligned child plan with ID "01HV000000000000000000SA11" parent "01HV000000000000000000SA10" root "01HV000000000000000000SA10" And a schema-aligned grandchild plan with ID "01HV000000000000000000SA12" parent "01HV000000000000000000SA11" root "01HV000000000000000000SA10" When I persist root, child, and grandchild schema-aligned plans Then the grandchild plan root_plan_id should be "01HV000000000000000000SA10" And the grandchild plan parent_plan_id should be "01HV000000000000000000SA11" @feature921 Scenario: automation_profile None roundtrips as None through domain model Given a schema-aligned plan with ID "01HV000000000000000000SA13" and no automation profile When I persist the schema-aligned plan Then the persisted automation_profile column should be "balanced" And the plan automation_profile ref should be None @feature921 Scenario: Truncated JSON in automation_profile deserializes gracefully Given a schema-aligned plan with ID "01HV000000000000000000SA14" And the plan automation_profile column is set to '{"profile_name":"test"' When I load the plan from the database Then the plan automation_profile ref should be None @feature921 Scenario: Updating effective_profile_snapshot persists correctly Given a schema-aligned plan with ID "01HV000000000000000000SA15" And the plan effective_profile_snapshot is '{"profile":"balanced","thresholds":{}}' When I persist the schema-aligned plan And I update the plan effective_profile_snapshot to '{"profile":"full-auto","thresholds":{"strategy":0.5}}' Then the retrieved plan effective_profile_snapshot should be '{"profile":"full-auto","thresholds":{"strategy":0.5}}' @feature921 Scenario: AutomationProfileRef round-trips through persistence Given a schema-aligned plan "01HV000000000000000000SA16" with profile "supervised" and provenance "plan" When I persist the schema-aligned plan Then the plan automation_profile name should be "supervised" And the plan automation_profile provenance should be "plan" @feature921 Scenario: NULL root_plan_id is rejected by the database Given a schema-aligned plan with ID "01HV000000000000000000SA09" forced NULL root_plan_id When I attempt to persist the plan with NULL root_plan_id Then the database should reject the insert with an integrity error @feature921 Scenario: NULL effective_profile_snapshot is rejected by the database Given a schema-aligned plan with ID "01HV000000000000000000SA17" forced NULL effective_profile_snapshot When I attempt to persist the plan with NULL effective_profile_snapshot Then the database should reject the snapshot insert with an integrity error @feature921 Scenario: PlanIdentity resolves None root_plan_id to plan_id at construction Given a schema-aligned plan with ID "01HV000000000000000000SA18" and None root_plan_id Then the domain plan root_plan_id should already equal "01HV000000000000000000SA18" When I convert the plan via from_domain Then the ORM model root_plan_id should equal "01HV000000000000000000SA18" @feature921 Scenario: Valid JSON missing profile_name key deserializes gracefully Given a schema-aligned plan with ID "01HV000000000000000000SA19" And the plan automation_profile column is set to '{"provenance":"plan"}' When I load the plan from the database Then the plan automation_profile ref should be None @feature921 Scenario: Corrupted effective_profile_snapshot in DB falls back to empty JSON Given a schema-aligned plan with ID "01HV000000000000000000SA20" And the plan effective_profile_snapshot is '{"profile":"balanced"}' When I persist the schema-aligned plan And the effective_profile_snapshot column is corrupted to "not-valid-json{" And I reload the plan from the database Then the retrieved plan effective_profile_snapshot should be '{}' @feature921 Scenario: Invalid JSON in effective_profile_snapshot is rejected by Plan model When I attempt to construct a Plan with effective_profile_snapshot "not-valid-json" Then the Plan construction should raise a validation error for effective_profile_snapshot @feature921 Scenario: Empty string effective_profile_snapshot is rejected by Plan model When I attempt to construct a Plan with an empty effective_profile_snapshot Then the Plan construction should raise a validation error for effective_profile_snapshot