Files
cleveragents-core/docs/reference/plan_lifecycle_service.md
T
2026-02-17 00:38:33 +00:00

6.0 KiB

Plan Lifecycle Service Reference

Source: src/cleveragents/application/services/plan_lifecycle_service.py

Overview

The PlanLifecycleService manages the v3 plan lifecycle:

Action -> Strategize -> Execute -> Apply

Plans are instantiated from Action templates. Terminal outcomes live in the Apply phase's processing state: applied, constrained, errored, or cancelled.

Action Management

Method Description
create_action(...) Create a new action (defaults to available state)
get_action(name) Get action by namespaced name
get_action_by_name(name) Alias for get_action with partial name resolution
list_actions(namespace, state) List actions with optional filtering
make_action_available(name) No-op (actions are available by default)
archive_action(name) Set action state to archived

Plan Creation

Uses an action on projects to create a plan in Strategize phase.

  • Validates action is in available state
  • Validates required arguments
  • Resolves automation level (explicit > global default)
  • Merges invariants (plan > action)
  • Creates plan with phase=STRATEGIZE, processing_state=QUEUED
  • Archives non-reusable actions after use

Phase Transitions

Method From To Description
execute_plan(plan_id) Strategize/COMPLETE Execute/QUEUED Transition to Execute phase
apply_plan(plan_id) Execute/COMPLETE Apply/QUEUED Transition to Apply phase

Processing State Methods

Strategize Phase

Method State Transition Description
start_strategize(plan_id) QUEUED -> PROCESSING Begin strategize work
complete_strategize(plan_id) PROCESSING -> COMPLETE Finish strategize, may auto-progress
fail_strategize(plan_id, error) * -> ERRORED Mark strategize as failed

Execute Phase

Method State Transition Description
start_execute(plan_id) QUEUED -> PROCESSING Begin execute work
complete_execute(plan_id) PROCESSING -> COMPLETE Finish execute, may auto-progress
fail_execute(plan_id, error) * -> ERRORED Mark execute as failed

Apply Phase

Method State Transition Description
start_apply(plan_id) QUEUED -> PROCESSING Begin apply work
complete_apply(plan_id) PROCESSING -> APPLIED Terminal success — changes committed
constrain_apply(plan_id, reason) * -> CONSTRAINED Cannot complete within constraints; may revert to Strategize
fail_apply(plan_id, error) * -> ERRORED Mark apply as failed

Apply Terminal Outcomes

The Apply phase has four terminal outcomes, modeled as ProcessingState values:

Processing State Meaning Next Step
APPLIED Success — changes committed Done
CONSTRAINED Cannot proceed within strategy constraints May revert to Strategize
ERRORED Failed May retry or abandon
CANCELLED User/system cancelled Done

Cancellation

cancel_plan(plan_id, reason=None)

Cancel any non-terminal plan. Sets processing_state=CANCELLED.

Automation

should_auto_progress(plan)

Pure query — checks if the plan should automatically advance:

  • Strategize/COMPLETE with REVIEW_BEFORE_APPLY or FULL_AUTOMATION: auto-execute
  • Execute/COMPLETE with FULL_AUTOMATION: auto-apply

auto_progress(plan_id)

Idempotent — advances to next phase if automation permits.

pause_plan(plan_id) / resume_plan(plan_id, level)

Pause halts auto-progression (sets MANUAL). Resume restores level and triggers immediate auto-progress if ready.

set_plan_automation_level(plan_id, level)

Change automation level for non-terminal plans.

Persistence

The service accepts an optional UnitOfWork at construction time. When provided, every mutation (action create/archive, plan create, phase transitions, state changes) is persisted through ActionRepository and LifecyclePlanRepository inside a database transaction.

When no UnitOfWork is supplied the service falls back to pure in-memory storage, preserving backward compatibility with tests that do not need a database.

from cleveragents.infrastructure.database.unit_of_work import UnitOfWork

uow = UnitOfWork("sqlite:///my.db")
uow.init_database()

service = PlanLifecycleService(settings=settings, unit_of_work=uow)
action = service.create_action(...)  # persisted
plan = service.use_action(...)       # persisted
service.execute_plan(plan.identity.plan_id)  # phase change persisted

Dual-mode design

Mode UnitOfWork Storage
In-memory None self._actions / self._plans dicts
Persisted provided DB via repositories plus in-memory cache

In persisted mode the in-memory dicts act as a write-through cache: mutations are written to DB first, then the cache is updated. Reads check the cache before hitting the database.

Error mapping

Repository error Surfaced as
DuplicateActionError propagated directly
PlanNotFoundError propagated directly
DatabaseError propagated directly

Custom Exceptions

Exception Description
InvalidPhaseTransitionError Attempted invalid phase transition
ActionNotAvailableError Action not in available state
PlanNotReadyError Plan not in expected state for transition

Legacy Plan Service

The previous PlanService (src/cleveragents/application/services/plan_service.py) is deprecated and emits DeprecationWarning on instantiation. All new plan workflows should use PlanLifecycleService.

Similarly, PlanRepository and ChangeRepository are deprecated; use LifecyclePlanRepository and ActionRepository instead.