# 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/]`) | 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: ```yaml 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: 1. Missing required arguments 2. Unknown argument names 3. Type mismatches (including `min_value`/`max_value` for integers) Convenience properties: - `action.required_arguments` -- list of arguments where requirement is `REQUIRED` - `action.optional_arguments` -- list of arguments where requirement is `OPTIONAL` ## 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"`): 1. **Trim** -- leading/trailing whitespace stripped from each entry 2. **Blank rejection** -- empty strings after trimming are dropped 3. **Deduplication** -- duplicate entries removed while preserving insertion order 4. **None coercion** -- `None` input 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: 1. `name`, `description`, `state` 2. `strategy_actor`, `execution_actor` 3. `long_description` (if set) 4. `definition_of_done` 5. Optional actors: `review_actor`, `apply_actor`, `estimation_actor`, `invariant_actor` (if set) 6. `arguments` (if non-empty) -- each as `{name, type, required, description}` 7. `reusable`, `read_only` 8. `automation_profile` (if set), `invariants` (if non-empty) 9. `created_at` 10. `tags` (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: ```yaml 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`