Commit Graph

8 Commits

Author SHA1 Message Date
Luis Mendes 9e316b1a3e fix(domain): align plan lifecycle model validation with specification
Aligned the plan lifecycle model with the specification:

1. ERRORED is now treated as terminal in is_terminal property,
   matching the spec table where errored is marked "Terminal? Yes"
   for all processing phases.

2. Added per-phase state validation via model_validator: APPLIED
   and CONSTRAINED are only valid in APPLY phase; COMPLETE is only
   valid in STRATEGIZE or EXECUTE phases. Invalid combinations
   now raise ValueError at construction time.

3. Updated ProcessingState.COMPLETE docstring to clarify phase-level
   terminality semantics.

4. Fixed assignment ordering in execute_plan() to set
   processing_state before phase, consistent with the state-first
   pattern used in apply_plan() and _perform_reversion().

5. Added defensive coercion in LifecyclePlanModel.to_domain() to
   handle legacy DB rows with invalid phase/state combinations
   (e.g. APPLY/COMPLETE -> APPLY/APPLIED) with warning-level
   logging for observability.

6. Updated module docstrings: ERRORED description now reflects
   terminal semantics, terminal outcomes location clarified for
   all phases, can_revert_to docstring notes ERRORED/CONSTRAINED
   are terminal but revertable, is_terminal docstring explains
   the distinction between terminal and permanently irrecoverable
   and documents why COMPLETE is not plan-terminal despite the
   spec marking it "Terminal? Yes" (phase-level vs plan-level).

7. Updated PlanResumeService.validate_eligibility() docstring to
   reflect that ERRORED is now terminal but still eligible for
   resume.

8. Added CHANGELOG entry.

ISSUES CLOSED: #918
2026-03-23 23:33:33 +00:00
hurui200320 48ecf4c00c fix(cli): add --execution-env-priority flag to plan use (#972)
## Summary

Adds the missing `--execution-env-priority` flag to the `agents plan use` command, aligning the CLI with the specification (spec line 12501). The flag accepts `fallback` (default) or `override` and controls execution environment routing precedence per ADR-043:

- **`override`**: The specified execution environment always wins, bypassing devcontainer auto-detection.
- **`fallback`**: The specified environment defers to auto-detected devcontainers or project-level overrides.

### Changes

- **Domain model** (`cleveragents.domain.models.core.plan`):
  - Added `ExecutionEnvPriority` StrEnum with `FALLBACK`/`OVERRIDE` values.
  - Changed `execution_env_priority` field type to `ExecutionEnvPriority | None` (leverages Pydantic enum validation).
  - Added `@model_validator` enforcing that `execution_env_priority` requires `execution_environment` (domain-level fail-fast invariant). Verified `validate_assignment=True` is set on `Plan.model_config`.
  - Updated `Plan.as_cli_dict()` to include `execution_environment` and `execution_env_priority`, with fallback default of `"fallback"` for pre-migration data where `execution_env_priority` is `None`.
- **CLI** (`cleveragents.cli.commands.plan`):
  - Added `--execution-env-priority` parameter to `use_action`.
  - Validation: priority requires `--execution-environment`, enum value validation, case-insensitive input.
  - Defaults to `"fallback"` when `--execution-environment` is set without explicit priority.
  - Updated `_print_lifecycle_plan` and `_plan_spec_dict` to display the priority, defaulting to `"fallback"` for pre-migration data.
  - Updated `_plan_spec_dict` docstring to mention new keys.
  - Hoisted `ExecutionEnvPriority` import to function-entry deferred imports in both `_plan_spec_dict` and `_print_lifecycle_plan` (no longer conditional on execution environment being set).
  - Guarded `service.save_plan(plan)` with `has_overrides` flag so it is only called when CLI overrides were actually applied.
- **Persistence** (`cleveragents.infrastructure.database`):
  - Added `execution_environment` (`String(255)`, nullable) and `execution_env_priority` (`String(20)`, nullable) columns to `LifecyclePlanModel`.
  - Updated `from_domain()`/`to_domain()` for round-trip serialization including `ExecutionEnvPriority` enum reconstruction. Uses direct attribute access (`plan.execution_environment`) instead of defensive `getattr` — Plan fields always exist on the Pydantic BaseModel.
  - Updated `LifecyclePlanRepository.update()` to persist both fields using direct attribute access.
  - Added Alembic migration `m4_003_plan_env_columns` adding both columns to the `v3_plans` table. Uses `String(255)` for `execution_environment` to accommodate namespaced resource names. Descends from `m6_005_profile_guards_json`.
- **Service** (`cleveragents.application.services.plan_lifecycle_service`):
  - Added `save_plan()` public convenience method for callers that need to re-persist after post-creation mutations.
- **Tests**:
  - 18 Behave scenarios covering:
    - CLI acceptance criteria (valid values, defaults, validation errors, output display, case-insensitive input, service invocation with `call_args` verification).
    - Domain model validator invariant: construction with priority but no environment raises `ValueError`; construction with both fields succeeds.
    - `ExecutionEnvPriority` enum: values verification, `StrEnum` subclass assertion.
    - `Plan.as_cli_dict()`: includes both fields when set, omits both when `None`, defaults priority to `"fallback"` for pre-migration data.
    - DB round-trip serialization: `from_domain()` → `to_domain()` preserves both fields; preserves `None` values.
  - 5 Robot Framework integration tests.
  - Updated pre-existing `SimpleNamespace`-based plan test fixtures in `database_models_lifecycle_coverage_steps`, `database_models_new_coverage_steps`, `database_models_coverage_r2_steps`, and `repositories_error_handling_coverage_steps` to include `execution_environment` and `execution_env_priority` attributes.
  - Simplified Robot helper `sys.path` pattern to standard approach.
- **Changelog**: Updated per CONTRIBUTING.md requirements.

### Review Fixes (Brent Edwards, Review #2384)

- **P2 #1 — Defensive `getattr`**: Replaced `getattr(plan, "execution_environment", None)` with direct `plan.execution_environment` access in both `LifecyclePlanModel.from_domain()` and `LifecyclePlanRepository.update()`. Plan is a Pydantic BaseModel with `default=None`, so the field always exists. Updated 4 pre-existing `SimpleNamespace`-based test fixtures to include the new attributes.
- **P2 #2 — Late conditional import**: Hoisted `ExecutionEnvPriority` import from inside conditional blocks to function-entry deferred imports in both `_plan_spec_dict` and `_print_lifecycle_plan`.
- **P3 — Migration naming**: Acknowledged as deferred (cosmetic only). Updated `m4_003` to descend from `m6_005_profile_guards_json` (post-rebase chain fix).
- **Rebase**: Branch rebased onto latest `master` with merge conflict in `CHANGELOG.md` resolved.

### Deferred Items

- **Partial failure atomicity** (#8 from review): If `save_plan()` fails after `use_action()` succeeds, the plan exists in the DB without CLI overrides. This requires service-layer restructuring beyond the scope of this ticket.
- **Alembic migration naming** (#11 from review): Migration `m4_003` depends on `m6_005`, creating non-sequential naming. Renaming an existing migration risks breaking the chain for anyone who has already applied it.

### Quality Gates

| Session | Result |
|---------|--------|
| lint | PASS |
| typecheck | PASS (0 errors) |
| unit_tests | PASS (11,125 scenarios, 0 failures) |
| integration_tests | PASS (1,562 tests, 0 failures) |
| coverage_report | 97% (threshold: 97%) |

Closes #886

Reviewed-on: cleveragents/cleveragents-core#972
Reviewed-by: Brent Edwards <brent.edwards@cleverthis.com>
Co-authored-by: Rui Hu <rui.hu@cleverthis.com>
Co-committed-by: Rui Hu <rui.hu@cleverthis.com>
2026-03-18 08:13:56 +00:00
freemo 174e117d8e refactor(automation): remove automation_level legacy fields 2026-02-20 15:57:21 +00:00
CoreRasurae f528d6c3a8 feat(domain): align plan model with spec
Step A2.beta
2026-02-13 20:34:57 +00:00
freemo 9b30421b34 feat(db): add spec-aligned action and plan tables with migrations, ORM models, and benchmarks 2026-02-13 13:05:20 -05:00
freemo fd6d41b371 feat(domain): align action model with spec 2026-02-13 09:41:28 -05:00
freemo 36b4ec2b8d feat(domain): align plan model with spec 2026-02-12 22:58:15 -05:00
CoreRasurae f2f7aa5dc9 feat(core): add v3 lifecycle models, automation levels, subplan support, and security hardening
Implement multiple Stage A/B/E/SEC milestones for the v3 lifecycle system:
- Stage A5.3+A5.4: Add LifecycleActionModel and LifecyclePlanModel SQLAlchemy
  models with to_domain()/from_domain() conversion methods
- Stage A5.6: Implement ActionRepository with full CRUD, namespace/state
  queries, referential integrity checks, and retry decorator
- Stage E1: Add subplan domain models (ExecutionMode, SubplanMergeStrategy,
  SubplanConfig, SubplanStatus, SubplanAttempt, SubplanFailureHandler) with
  computed properties on Plan (is_subplan, is_root_plan, depth, has_subplans)
- Stage A6: Add AutomationLevel enum (MANUAL, REVIEW_BEFORE_APPLY,
  FULL_AUTOMATION), settings integration, PlanLifecycleService auto-progression,
  pause/resume, and CLI commands (--automation-level, set-automation-level)
- Stage SEC1: Remove eval()/exec() from stream_router.py, replace with named
  operation and transform registries; code blocks and unregistered transforms
  now raise StreamRoutingError
- Add langchain-anthropic dependency
- Update BDD tests for security changes and relax ADR directory requirement
2026-02-12 20:19:42 +00:00