172 lines
6.2 KiB
Markdown
172 lines
6.2 KiB
Markdown
# 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.
|
|
|
|
## Project Links
|
|
|
|
Plans target one or more projects via `project_links: list[ProjectLink]`:
|
|
|
|
```python
|
|
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:
|
|
|
|
```python
|
|
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`
|