Files
cleveragents-core/docs/reference/plan_model.md
T

6.2 KiB

Plan Domain Model

The Plan is the fundamental unit of orchestration in CleverAgents. It is instantiated from an Action via agents plan use and follows a three-phase lifecycle.

Phase Lifecycle

Plans progress through four phases in strict order:

Strategize -> Execute -> Apply -> Applied (terminal)
Phase Description
STRATEGIZE Generating the execution strategy
EXECUTE Carrying out the planned changes
APPLY Applying the changeset to the target project(s)
APPLIED Terminal state; plan is complete

The Action entity is a separate domain object. There is no ACTION phase within the Plan lifecycle. Actions are resolved before plan creation.

Phase Transitions

Valid transitions:

  • strategize -> execute
  • execute -> apply
  • apply -> applied

No backward transitions or phase-skipping is allowed. APPLIED is terminal.

Transitions are validated by can_transition(from_phase, to_phase) and require the plan's processing state to be COMPLETE before advancing.

Processing State

Plans use a single unified state field (type: ProcessingState):

State Description
QUEUED Waiting for compute/worker
PROCESSING Currently running
ERRORED Failed; includes error metadata
COMPLETE Finished successfully
CANCELLED User/system cancelled

The state field replaces the former dual action_state / processing_state fields. All phases use the same ProcessingState enum.

Action Linkage

Plans reference their originating action by namespaced name (not ULID):

  • action_name: str -- required, e.g. "local/code-review", "org/deploy"

This decouples the plan from the action's database identity and enables cross-server action references.

Plans target one or more projects via project_links: list[ProjectLink]:

class ProjectLink(BaseModel):
    project_name: str       # Namespaced project name (required)
    alias: str | None       # Optional short alias for plan context
    read_only: bool = False # Whether project is read-only for this plan

Alias Validation

  • Lowercase alphanumeric with hyphens or underscores
  • Must start with a letter or digit
  • Aliases are auto-lowercased
  • Duplicate aliases within a plan are rejected

A computed property plan.project_names returns [link.project_name for link in plan.project_links] for backward compatibility.

Automation Profile

Plans store automation configuration:

Field Type Description
automation_level AutomationLevel MANUAL, REVIEW_BEFORE_APPLY, or FULL_AUTOMATION
automation_profile_name str | None Namespaced name of the resolved profile
effective_profile_snapshot dict | None Frozen profile thresholds at creation

The profile snapshot is immutable after plan creation, ensuring reproducibility.

Automation Levels

Level Behavior
MANUAL User triggers each phase transition
REVIEW_BEFORE_APPLY Auto strategize + execute, pause before apply
FULL_AUTOMATION All phases run automatically

Invariants

Plans carry a list of PlanInvariant constraints:

class PlanInvariant(BaseModel):
    text: str                    # The invariant constraint text (non-empty)
    scope: InvariantScope        # Where it originated
    source_name: str | None      # Name of the source entity

Invariant Scope Precedence

Scopes (highest to lowest precedence):

  1. PLAN -- plan-level constraints
  2. ACTION -- action-level constraints
  3. PROJECT -- project-level constraints
  4. GLOBAL -- system-wide constraints

Invariants preserve insertion order for stable CLI rendering.

Arguments

Plans store resolved action arguments:

  • arguments: dict[str, Any] -- resolved argument values (JSON-serializable)
  • arguments_order: list[str] -- ordered list of argument names for CLI rendering

Actor References

Field Description
strategy_actor Actor for Strategize phase
execution_actor Actor for Execute phase
estimation_actor Actor for cost/risk estimation
invariant_actor Actor for invariant reconciliation

Execution Placeholders

Field Description
changeset_id ID of the change set produced during Execute
sandbox_refs References to sandbox instances
validation_summary Summary of validation results at Apply time
decision_root_id ULID of the root decision in the decision tree

CLI Rendering

Plan.as_cli_dict() returns a stable-ordered OrderedDict suitable for CLI output. Key ordering:

  1. plan_id, name, action_name
  2. phase, state, description
  3. definition_of_done (if set)
  4. projects, automation_profile (if set), automation_level
  5. Actor references (if set)
  6. arguments (if non-empty), invariants (if non-empty)
  7. Execution fields (if set)
  8. Error fields (if set)
  9. tags (if non-empty)
  10. Timestamps
  11. Hierarchy fields (if set)

Source Location

  • Model: src/cleveragents/domain/models/core/plan.py
  • Action model: src/cleveragents/domain/models/core/action.py
  • Lifecycle service: src/cleveragents/application/services/plan_lifecycle_service.py