12 KiB
Action Domain Model
The Action is a YAML-defined, reusable plan template in CleverAgents.
It specifies actors, typed arguments, completion criteria, and optional
invariants. Actions are project-agnostic until bound to one or more
projects via agents plan use, which instantiates a Plan in Strategize phase.
Actions are created via CLI with a required --config YAML file:
agents action create --config ./actions/code-coverage.yaml
State Lifecycle
Actions have only two states with no draft phase:
| State | Description |
|---|---|
| AVAILABLE | Default state; action can be used to create plans |
| ARCHIVED | Action is retired and cannot create new plans |
There is no draft state. Actions are created directly in available state
from a validated YAML config file.
Fields Reference
Identity
| Field | Type | Required | Description |
|---|---|---|---|
namespaced_name |
NamespacedName |
Yes | Unique identifier ([server:][namespace/]<name>) |
The namespaced name is the sole identity for an action -- there is no separate ULID. This enables cross-server action references.
Descriptions
| Field | Type | Required | Description |
|---|---|---|---|
description |
str |
Yes | Short description (min 1 char) |
long_description |
str | None |
No | Detailed description for reusable actions |
definition_of_done |
str |
Yes | Explicit, testable completion criteria |
Actor References
| Field | Type | Required | Description |
|---|---|---|---|
strategy_actor |
str |
Yes | Actor for the Strategize phase |
execution_actor |
str |
Yes | Actor for the Execute phase |
review_actor |
str | None |
No | Actor for reviewing results |
apply_actor |
str | None |
No | Actor for the Apply phase |
estimation_actor |
str | None |
No | Actor for effort/cost estimation |
invariant_actor |
str | None |
No | Actor for invariant reconciliation |
strategy_actor and execution_actor are required. All actor fields accept
namespaced names.
Behavior Flags
| Field | Type | Default | Description |
|---|---|---|---|
reusable |
bool |
True |
If true, action remains available after use |
read_only |
bool |
False |
If true, action only performs read operations |
Metadata
| Field | Type | Description |
|---|---|---|
created_at |
datetime |
Creation timestamp |
updated_at |
datetime |
Last update timestamp |
created_by |
str | None |
User/session that created the action |
tags |
list[str] |
Tags for organization |
Arguments System
Actions accept typed arguments defined as ActionArgument instances.
Arguments are injected into description/definition-of-done templates and
passed into actor context. Users supply values via --arg name=value.
ActionArgument Fields
| Field | Type | Default | Description |
|---|---|---|---|
name |
str |
-- | Valid Python identifier (1-64 chars) |
arg_type |
ArgumentType |
STRING |
Type of the argument |
requirement |
ArgumentRequirement |
REQUIRED |
Required or optional |
description |
str |
"" |
Human-readable description (max 500) |
default_value |
str|int|float|bool|list|None |
None |
Default for optional arguments |
validation_pattern |
str | None |
None |
Regex pattern for string validation |
min_value |
float | None |
None |
Minimum value for numeric arguments |
max_value |
float | None |
None |
Maximum value for numeric arguments |
Argument Types
| Type | Python Type | Description |
|---|---|---|
string |
str |
Text value |
integer |
int |
Whole number |
float |
float |
Decimal number |
boolean |
bool |
True/false value |
list |
list[str] |
Comma-separated values |
Legacy short names (str, int, bool) are accepted and mapped to their
full equivalents via ArgumentType._missing_().
Argument Requirement
| Value | Description |
|---|---|
required |
Must be provided when using the action |
optional |
May be omitted; default_value used if set |
Parsing: CLI String Format
ActionArgument.parse() accepts colon-delimited strings:
name:type:required|optional[:description]
Examples:
target_coverage:integer:required:Target coverage percentage
test_framework:string:optional:Test framework to use
Parsing: YAML Mapping
ActionArgument.from_mapping() builds an argument from a YAML dict:
name: target_coverage
type: integer
required: true
description: Target coverage percentage
default: 80
min_value: 0
max_value: 100
The required key is a boolean (default false). The type key is
case-insensitive and supports legacy short names.
Type Coercion: CLI Values
ActionArgument.coerce_value(raw) converts a raw CLI string to the
declared type:
| Type | Coercion Behavior |
|---|---|
string |
Returned as-is |
integer |
int(raw); raises ValueError on failure |
float |
float(raw); raises ValueError on failure |
boolean |
Truthy: true, 1, yes, on. Falsy: false, 0, no, off |
list |
Split on ,, strip whitespace, drop empty items |
Argument Validation
Action.validate_arguments(provided_args) checks provided values against
the action's argument schema and returns a list of error messages (empty
if valid). Checks performed:
- Missing required arguments
- Unknown argument names
- Type mismatches (including
min_value/max_valuefor integers)
Convenience properties:
action.required_arguments-- list of arguments where requirement isREQUIREDaction.optional_arguments-- list of arguments where requirement isOPTIONAL
YAML-First Configuration
Actions are loaded from YAML config dicts via Action.from_config(config).
Required Config Keys
| Key | Description |
|---|---|
name |
Namespaced name (parsed via NamespacedName.parse()) |
description |
Short description |
definition_of_done |
Completion criteria |
strategy_actor |
Strategize phase actor |
execution_actor |
Execute phase actor |
Missing any of these raises ValueError.
Optional Config Keys
| Key | Default | Description |
|---|---|---|
long_description |
None |
Detailed description |
review_actor |
None |
Review actor |
apply_actor |
None |
Apply phase actor |
estimation_actor |
None |
Estimation actor |
invariant_actor |
None |
Invariant reconciliation actor |
arguments |
[] |
List of argument mappings |
inputs_schema |
None |
JSON Schema dict |
reusable |
True |
Whether action persists after use |
read_only |
False |
Read-only mode |
state |
"available" |
Initial state |
automation_profile |
None |
Default automation profile name |
invariants |
[] |
List of invariant strings |
tags |
[] |
Organization tags |
created_by |
None |
Creator identifier |
Automation Profile
Actions can specify a default automation profile via the automation_profile
field. This is a namespaced name string resolved at plan-use time.
Cross-field validation trims the value and converts empty/whitespace-only
strings to None.
Invariants
Actions carry a list of invariant constraint strings (invariants: list[str]).
When the action is used to create a plan, these are carried forward as
plan-level invariants with ACTION scope.
Sanitization
The invariants field is sanitized on assignment via a Pydantic
field_validator (mode "before"):
- Trim -- leading/trailing whitespace stripped from each entry
- Blank rejection -- empty strings after trimming are dropped
- Deduplication -- duplicate entries removed while preserving insertion order
- None coercion --
Noneinput is normalized to an empty list
inputs_schema
An optional dict[str, Any] field for advanced input validation via
JSON Schema. Validated on assignment to ensure the value is a dict
(or None). This provides a schema-based alternative to the typed
arguments list for complex input structures.
CLI Rendering
Action.as_cli_dict() returns a stable-ordered dict for deterministic
CLI output. Key ordering:
name,description,statestrategy_actor,execution_actorlong_description(if set)definition_of_done- Optional actors:
review_actor,apply_actor,estimation_actor,invariant_actor(if set) arguments(if non-empty) -- each as{name, type, required, description}reusable,read_onlyautomation_profile(if set),invariants(if non-empty)created_attags(if non-empty)
Templating
Actions support ${placeholder} syntax (Python string.Template) for
injecting argument values into text fields.
render_template(template_text, args)
Core method. Scans for ${name} and $name placeholders, verifies all
are present in the args dict, and substitutes using safe_substitute.
Raises ValueError if any placeholder is missing from args.
render_description(args)
Shorthand for render_template(self.description, args).
render_definition_of_done(args)
Shorthand for render_template(self.definition_of_done, args).
Example
Given an action with:
description: "Increase test coverage to ${target_coverage}%"
definition_of_done: "All modules have >= ${target_coverage}% line coverage"
Calling render_description({"target_coverage": "90"}) produces:
Increase test coverage to 90%
Source Location
- Model:
src/cleveragents/domain/models/core/action.py - Plan model:
src/cleveragents/domain/models/core/plan.py - Plan lifecycle service:
src/cleveragents/application/services/plan_lifecycle_service.py