Feature: Plan lifecycle repository and service coverage Additional scenarios to cover untested paths in LifecyclePlanRepository, ActionRepository, PlanLifecycleService, and UnitOfWork. Background: Given a coverage test service backed by SQLite # ── LifecyclePlanRepository direct tests ── Scenario: Get plan by namespaced name Given a coverage plan exists via the service When I retrieve the plan by its namespaced name from the repository Then the plan retrieved by name should match the original Scenario: Get plan by name returns None for unknown When I retrieve a plan by name "local/nonexistent-plan-xyz" from the repository Then the plan-by-name result should be None Scenario: Update plan persists child project links, arguments, and invariants Given a coverage plan with project links and invariants exists When I update the plan description and phase through the repository Then the updated plan should have the new description in the DB And the updated plan should retain project links And the updated plan should retain arguments And the updated plan should retain invariants Scenario: Delete plan removes it from the database Given a coverage plan exists via the service When I delete the plan from the repository Then the plan should no longer be retrievable from the DB Scenario: Delete returns false for non-existent plan When I delete a non-existent plan "01NONEXISTENT000000000000" from the repository Then the plan delete result should be false Scenario: List plans with phase filter Given a coverage plan exists via the service When I list plans filtered by phase "strategize" Then the listed plans should include the coverage plan Scenario: List plans with namespace filter Given a coverage plan exists via the service When I list plans filtered by namespace "local" Then the listed plans should include the coverage plan Scenario: List plans with action_name filter Given a coverage plan exists via the service When plcov I list plans filtered by action_name Then the listed plans should include the coverage plan Scenario: Count plans with no filters Given a coverage plan exists via the service When I count plans with no filters Then the count should be at least 1 Scenario: Count plans with phase filter Given a coverage plan exists via the service When I count plans filtered by phase "strategize" Then the filtered count should be at least 1 Scenario: Count plans with processing_state filter Given a coverage plan exists via the service When I count plans filtered by processing_state "queued" Then the filtered count should be at least 1 Scenario: Create duplicate plan raises DuplicatePlanError Given a coverage plan exists via the service When I try to create a duplicate plan with the same ID Then a DuplicatePlanError should be raised Scenario: Update non-existent plan raises PlanNotFoundError When I try to update a plan that does not exist in the DB Then a PlanNotFoundError should be raised # ── ActionRepository update path ── Scenario: Archive action triggers action update in repository Given a coverage action "local/cov-archive" exists When I archive the coverage action "local/cov-archive" Then the action "local/cov-archive" should be archived in the DB Scenario: Action update persists inputs_schema and arguments with defaults Given a coverage action with inputs_schema and arguments exists When I update the coverage action with new description Then the action should retain its inputs_schema in the DB And the action should retain its arguments with defaults in the DB And the action should retain its invariants in the DB # ── PlanLifecycleService persistence fallback ── Scenario: Get plan falls back to persistence layer when not in memory Given a coverage plan exists via the service When I clear the in-memory plan cache And I retrieve the plan by ID through the service Then the plan should be loaded from the persistence layer # ── PlanLifecycleService constrain_apply ── Scenario: Constrain apply marks plan as constrained Given a coverage plan in apply-queued state When I constrain the apply with reason "Resource limit exceeded" Then the coverage plan processing state should be "constrained" And the coverage plan error message should be "Resource limit exceeded" # ── PlanLifecycleService auto_progress no-op ── Scenario: Auto progress returns plan unchanged when not auto-progressable Given a coverage plan exists via the service When I call auto_progress on the plan Then the plan should be returned unchanged # ── UnitOfWork lifecycle_plans lazy property ── Scenario: UnitOfWork context exposes lifecycle_plans repository When I open a UoW transaction and access lifecycle_plans Then the lifecycle_plans property should return a LifecyclePlanRepository # ── UnitOfWork add, flush, refresh ── Scenario: UnitOfWork context supports add and flush When I use UoW context to add a raw model entity and flush Then the entity should be queryable in the same session