fix: wire DI persistence and plan execute/apply for M1 lifecycle #957

Merged
freemo merged 2 commits from fix/m1-e2e-plan-execute-apply into master 2026-03-15 21:07:33 +00:00
Owner

Summary

Fixes 5 bugs preventing the M1 E2E acceptance test (PR #789) from passing, plus updates all existing test mocks to work with the new execute_plan() CLI behavior.

Root Causes & Fixes

1. DI container bypass in _get_lifecycle_service() (action.py + plan.py)

Both action.py and plan.py created PlanLifecycleService(settings=settings) directly, bypassing the container's UnitOfWork. Data was in-memory only and lost between subprocess invocations. Fix: use container.plan_lifecycle_service().

2. plan execute CLI did not process phases

Called service.execute_plan() which is a pure state transition — never invoked PlanExecutor.run_strategize() or run_execute(). Fix: rewrote to detect the plan's phase/state and dispatch synchronously through the executor.

3. plan apply CLI missing plan_id argument

Signature was apply(yes=False) with no positional. The test calls plan apply --yes ${plan_id}. Fix: added optional plan_id positional argument with _lifecycle_apply_with_id() driving through Apply/queued → Apply/processing → Apply/applied.

4. Preflight guardrail action lookup was in-memory only

start_strategize() built action_registry from self._actions dict (empty in a new subprocess). Fix: added self.get_action(plan.action_name) to load the action from DB into the in-memory cache before the guardrail check.

5. Robot Framework Create File syntax bug + branch name

Continuation lines (...) with Create File created 9 arguments instead of 1. Fixed to use Catenate SEPARATOR=\n + Create File. Also fixed --branch main--branch master.

6. Test mock updates for new execute_plan() behavior

The new execute_plan() calls _get_plan_executor() and service.get_plan(plan_id) for phase/state detection. Updated mocks in 8 Behave step files and 5 Robot helper files to:

  • Patch _get_plan_executor in all test setups
  • Set service.get_plan.return_value to real Plan objects with correct phase/state
  • Fix error-path tests to use plans in executable states so error side_effects trigger
  • Fix "Multiple plans eligible" → "Multiple plans ready" message text

Files Changed

Source code:

  • src/cleveragents/cli/commands/plan.py_get_lifecycle_service(), _get_plan_executor(), execute_plan(), apply(), message text fix
  • src/cleveragents/cli/commands/action.py_get_lifecycle_service() container fix
  • src/cleveragents/application/services/plan_lifecycle_service.py — action DB preload in start_strategize()
  • robot/e2e/m1_acceptance.robotCreate File syntax, branch name

Test mocks (Behave):

  • features/steps/cli_lifecycle_coverage_steps.py
  • features/steps/cli_lifecycle_robot_alignment_steps.py
  • features/steps/m1_sourcecode_smoke_steps.py
  • features/steps/plan_cli_commands_r2_steps.py
  • features/steps/plan_cli_coverage_boost_steps.py
  • features/steps/plan_cli_coverage_r2_steps.py
  • features/steps/plan_lifecycle_cli_steps.py
  • features/steps/plan_lifecycle_commands_coverage_steps.py

Test mocks (Robot helpers):

  • robot/helper_cli_lifecycle.py
  • robot/helper_cli_lifecycle_e2e.py
  • robot/helper_m1_sourcecode_smoke.py
  • robot/helper_m4_e2e_cli.py
  • robot/helper_m4_e2e_cli_errors.py

Test Results

M1 Full Plan Lifecycle :: Exercise the complete M1 plan lifecycle ... | PASS |
1 test, 1 passed, 0 failed

Behave unit tests: 254 scenarios passed across 9 affected feature files, 0 failed.

ISSUES CLOSED: #789

## Summary Fixes 5 bugs preventing the M1 E2E acceptance test (PR #789) from passing, plus updates all existing test mocks to work with the new `execute_plan()` CLI behavior. ## Root Causes & Fixes ### 1. DI container bypass in `_get_lifecycle_service()` (action.py + plan.py) Both `action.py` and `plan.py` created `PlanLifecycleService(settings=settings)` directly, bypassing the container's `UnitOfWork`. Data was in-memory only and lost between subprocess invocations. **Fix**: use `container.plan_lifecycle_service()`. ### 2. `plan execute` CLI did not process phases Called `service.execute_plan()` which is a pure state transition — never invoked `PlanExecutor.run_strategize()` or `run_execute()`. **Fix**: rewrote to detect the plan's phase/state and dispatch synchronously through the executor. ### 3. `plan apply` CLI missing `plan_id` argument Signature was `apply(yes=False)` with no positional. The test calls `plan apply --yes ${plan_id}`. **Fix**: added optional `plan_id` positional argument with `_lifecycle_apply_with_id()` driving through Apply/queued → Apply/processing → Apply/applied. ### 4. Preflight guardrail action lookup was in-memory only `start_strategize()` built `action_registry` from `self._actions` dict (empty in a new subprocess). **Fix**: added `self.get_action(plan.action_name)` to load the action from DB into the in-memory cache before the guardrail check. ### 5. Robot Framework `Create File` syntax bug + branch name Continuation lines (`...`) with `Create File` created 9 arguments instead of 1. Fixed to use `Catenate SEPARATOR=\n` + `Create File`. Also fixed `--branch main` → `--branch master`. ### 6. Test mock updates for new `execute_plan()` behavior The new `execute_plan()` calls `_get_plan_executor()` and `service.get_plan(plan_id)` for phase/state detection. Updated mocks in 8 Behave step files and 5 Robot helper files to: - Patch `_get_plan_executor` in all test setups - Set `service.get_plan.return_value` to real Plan objects with correct phase/state - Fix error-path tests to use plans in executable states so error side_effects trigger - Fix "Multiple plans eligible" → "Multiple plans ready" message text ## Files Changed ### Source code: - `src/cleveragents/cli/commands/plan.py` — `_get_lifecycle_service()`, `_get_plan_executor()`, `execute_plan()`, `apply()`, message text fix - `src/cleveragents/cli/commands/action.py` — `_get_lifecycle_service()` container fix - `src/cleveragents/application/services/plan_lifecycle_service.py` — action DB preload in `start_strategize()` - `robot/e2e/m1_acceptance.robot` — `Create File` syntax, branch name ### Test mocks (Behave): - `features/steps/cli_lifecycle_coverage_steps.py` - `features/steps/cli_lifecycle_robot_alignment_steps.py` - `features/steps/m1_sourcecode_smoke_steps.py` - `features/steps/plan_cli_commands_r2_steps.py` - `features/steps/plan_cli_coverage_boost_steps.py` - `features/steps/plan_cli_coverage_r2_steps.py` - `features/steps/plan_lifecycle_cli_steps.py` - `features/steps/plan_lifecycle_commands_coverage_steps.py` ### Test mocks (Robot helpers): - `robot/helper_cli_lifecycle.py` - `robot/helper_cli_lifecycle_e2e.py` - `robot/helper_m1_sourcecode_smoke.py` - `robot/helper_m4_e2e_cli.py` - `robot/helper_m4_e2e_cli_errors.py` ## Test Results ``` M1 Full Plan Lifecycle :: Exercise the complete M1 plan lifecycle ... | PASS | 1 test, 1 passed, 0 failed ``` Behave unit tests: 254 scenarios passed across 9 affected feature files, 0 failed. ISSUES CLOSED: #789
freemo changed target branch from test/e2e-m1-acceptance to master 2026-03-15 00:41:18 +00:00
freemo force-pushed fix/m1-e2e-plan-execute-apply from 9a652b9d47 to 03031375c7
Some checks failed
CI / lint (pull_request) Successful in 27s
CI / benchmark-publish (pull_request) Has been skipped
CI / quality (pull_request) Successful in 34s
CI / build (pull_request) Successful in 22s
CI / typecheck (pull_request) Successful in 49s
CI / e2e_tests (pull_request) Successful in 55s
CI / security (pull_request) Successful in 56s
CI / unit_tests (pull_request) Failing after 3m19s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Failing after 3m45s
CI / coverage (pull_request) Successful in 6m49s
CI / benchmark-regression (pull_request) Successful in 38m30s
2026-03-15 00:45:24 +00:00
Compare
freemo scheduled this pull request to auto merge when all checks succeed 2026-03-15 00:45:47 +00:00
freemo force-pushed fix/m1-e2e-plan-execute-apply from ea1bc12acf
All checks were successful
CI / lint (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 38s
CI / security (pull_request) Successful in 50s
CI / quality (pull_request) Successful in 29s
CI / e2e_tests (pull_request) Successful in 1m15s
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 26s
CI / unit_tests (pull_request) Successful in 3m19s
CI / integration_tests (pull_request) Successful in 3m39s
CI / coverage (pull_request) Successful in 5m56s
CI / docker (pull_request) Successful in 1m9s
CI / benchmark-regression (pull_request) Successful in 41m11s
to f95feb6a20
Some checks failed
CI / lint (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 43s
CI / security (pull_request) Has been cancelled
CI / unit_tests (pull_request) Has been cancelled
CI / integration_tests (pull_request) Has been cancelled
CI / quality (pull_request) Has been cancelled
CI / e2e_tests (pull_request) Has been cancelled
CI / benchmark-publish (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / benchmark-regression (pull_request) Has been cancelled
2026-03-15 20:47:28 +00:00
Compare
freemo force-pushed fix/m1-e2e-plan-execute-apply from f95feb6a20
Some checks failed
CI / lint (pull_request) Successful in 17s
CI / typecheck (pull_request) Successful in 43s
CI / security (pull_request) Has been cancelled
CI / unit_tests (pull_request) Has been cancelled
CI / integration_tests (pull_request) Has been cancelled
CI / quality (pull_request) Has been cancelled
CI / e2e_tests (pull_request) Has been cancelled
CI / benchmark-publish (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / benchmark-regression (pull_request) Has been cancelled
to 5f07316641
All checks were successful
CI / lint (pull_request) Successful in 16s
CI / typecheck (pull_request) Successful in 42s
CI / security (pull_request) Successful in 46s
CI / quality (pull_request) Successful in 27s
CI / unit_tests (pull_request) Successful in 3m16s
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 15s
CI / e2e_tests (pull_request) Successful in 1m12s
CI / integration_tests (pull_request) Successful in 4m20s
CI / docker (pull_request) Successful in 59s
CI / coverage (pull_request) Successful in 6m34s
CI / lint (push) Successful in 20s
CI / typecheck (push) Successful in 45s
CI / security (push) Successful in 46s
CI / quality (push) Successful in 37s
CI / build (push) Successful in 17s
CI / e2e_tests (push) Successful in 52s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 5m9s
CI / integration_tests (push) Successful in 5m32s
CI / docker (push) Successful in 57s
CI / coverage (push) Successful in 6m10s
CI / benchmark-publish (push) Successful in 20m11s
CI / benchmark-regression (pull_request) Successful in 38m29s
2026-03-15 20:50:04 +00:00
Compare
freemo merged commit 5f07316641 into master 2026-03-15 21:07:33 +00:00
freemo deleted branch fix/m1-e2e-plan-execute-apply 2026-03-15 21:07:33 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core!957
No description provided.