Implemented Robot Framework E2E test suite validating Specification
Workflow Example 7 (CI/CD Integration). Tests exercise the real
CleverAgents CLI with zero mocking, covering:
- ci-profile configuration with JSON output format and WARN log level
(spec Step 1)
- Idempotent resource and project registration with resource linking,
verified via strict occurrence-count assertions
- Three-validation registration (lint, typecheck, tests) with project
attachment and tool-list verification
- CI plan launch with action args (pr_branch, base_branch), explicit
plan execute for lifecycle progression, and terminal-state assertion
- JSON output verification via json.loads() with raw_decode fallback
for mixed log/JSON CLI output
- Graceful degradation via Skip If No LLM Keys when API keys are
unavailable
Resource/project naming follows spec convention (local/ci-workspace
project, local/ci-main resource). Entity creation commands tolerate
"already exists" for CI re-runnability. Config assertions use
stdout-only matching and exact equality. Validation naming aligned
with spec (local/ci-lint per §Example 7, line 39130).
Added robot/common_vars.py module placeholder for shared Robot
Framework variables.
ISSUES CLOSED: #753
Updated automation_levels.feature to expect "applied" processing state
instead of "queued" after completing execute on a full_automation plan,
matching the new auto_progress() behavior that drives Apply to terminal
state.
Updated plan_cli_coverage_boost_steps.py to properly mock the full apply
lifecycle (get_plan → apply_plan → start_apply → complete_apply) instead
of returning a single plan from apply_plan, matching the updated
lifecycle_apply_plan command handler that now drives plans through to the
terminal applied state.
Refs: #753
Modified auto_progress() to complete the Apply phase immediately after
transitioning from Execute to Apply, since Apply is a metadata transition
with no LLM processing. This ensures `plan execute` drives the plan to
the terminal `applied` state when the automation profile permits (ci,
full-auto profiles with auto_apply < 1.0).
Extracted `_complete_apply_if_queued()` helper that consolidates the
Apply-completion pattern (start_apply + complete_apply) into a single
method with error recovery (calls `fail_apply` on failure) and async-job
guard (skips inline completion when async execution is enabled to avoid
orphaning enqueued jobs). Used by `auto_progress()`,
`lifecycle_apply_plan()`, and `try_auto_run()`.
Added PlanLifecycleService.try_auto_run() that drives plans through all
lifecycle phases (strategize → execute → apply) when automation-profile
thresholds allow automatic progression. Each phase checks the profile's
auto_* threshold before proceeding; a threshold of 1.0 stops the plan at
that phase boundary for human approval.
Fixed `lifecycle-apply` CLI leaving plans stuck in `apply/queued` without
completing. The command now calls `_complete_apply_if_queued()` when the
plan is in Apply/queued, driving it to the terminal `applied` state.
Fixed stale RICH output in `lifecycle_apply_plan` that printed
"Plan is now in Apply phase (queued)" after the plan had already reached
terminal `applied` state; now branches on `plan.is_terminal`.
Additional fixes:
- SQLite UNIQUE constraint violation in LifecyclePlanRepository.update():
added session.flush() after clear() on child collections (project_links,
arguments, invariants) before re-inserting rows
- Added 'state' alias in _plan_spec_dict() JSON output for spec §Example 7
jq compatibility
- Updated plan execute and lifecycle-apply reference documentation
Refs: #753