UAT: Advisory locking (LockService) not integrated into PlanLifecycleService phase transitions #6258

Open
opened 2026-04-09 18:19:17 +00:00 by HAL9000 · 0 comments
Owner

Background and Context

The CleverAgents specification (§Plan Lifecycle) and the task description state that phase transitions are "gated by advisory locking." The LockService (src/cleveragents/application/services/lock_service.py) exists and is fully implemented with plan-level and project-level mutual exclusion, TTL, re-entrancy, and conflict detection — but it is never injected into or used by PlanLifecycleService.

Current Behavior

PlanLifecycleService.__init__ does not accept a lock_service parameter, and the DI container (application/container.py) does not wire LockService into plan_lifecycle_service. Phase transitions (execute_plan, apply_plan, start_strategize, etc.) proceed without acquiring any advisory lock on the plan resource.

The only code that uses LockService is src/cleveragents/cli/commands/system.py (for diagnostic listing of stale locks), which is unrelated to plan execution.

Evidence:

  • grep -rn "LockService|lock_service" src/cleveragents/ | grep -v "lock_service.py" → only system.py
  • PlanLifecycleService.__init__ signature at line 183: no lock_service parameter
  • Container wiring at lines 661–668: no lock_service argument passed

Expected Behavior

Per the spec, before each phase transition (Strategize → Execute, Execute → Apply), PlanLifecycleService should:

  1. Acquire an advisory lock on the plan resource (via LockService.acquire) before processing begins.
  2. Release the lock after the transition completes or fails.
  3. Raise LockConflictError (already defined) if another process holds the lock.

This prevents race conditions when multiple CLI processes or async workers attempt concurrent transitions on the same plan.

Acceptance Criteria

  • PlanLifecycleService accepts a lock_service: LockService | None constructor parameter.
  • Phase transition methods (execute_plan, apply_plan, start_strategize, start_execute, start_apply) acquire and release plan-level advisory locks.
  • The DI container wires LockService into PlanLifecycleService.
  • Unit tests (Behave) cover lock acquisition, release, and conflict detection during transitions.
  • Coverage remains ≥ 97%.

Code Location

  • src/cleveragents/application/services/plan_lifecycle_service.pyPlanLifecycleService.__init__ (line 183), phase transition methods (lines 1300, 1495, 1572, 1679, 1730)
  • src/cleveragents/application/services/lock_service.py — fully implemented but unused in lifecycle
  • src/cleveragents/application/container.py — lines 661–668: missing lock_service wiring

Metadata

  • Commit Message: fix(plan-lifecycle): wire LockService advisory locking into PlanLifecycleService phase transitions
  • Branch: fix/plan-lifecycle-advisory-locking

Subtasks

  • Add lock_service: LockService | None to PlanLifecycleService.__init__
  • Acquire/release plan lock in start_strategize, execute_plan, apply_plan, start_execute, start_apply
  • Wire LockService into plan_lifecycle_service provider in container
  • Tests (Behave): concurrent transition scenarios with lock conflict
  • Run nox -s coverage_report, verify ≥ 97%
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line matches the Commit Message in Metadata exactly.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Background and Context The CleverAgents specification (§Plan Lifecycle) and the task description state that phase transitions are "gated by advisory locking." The `LockService` (`src/cleveragents/application/services/lock_service.py`) exists and is fully implemented with plan-level and project-level mutual exclusion, TTL, re-entrancy, and conflict detection — but it is **never injected into or used by `PlanLifecycleService`**. ## Current Behavior `PlanLifecycleService.__init__` does not accept a `lock_service` parameter, and the DI container (`application/container.py`) does not wire `LockService` into `plan_lifecycle_service`. Phase transitions (`execute_plan`, `apply_plan`, `start_strategize`, etc.) proceed without acquiring any advisory lock on the plan resource. The only code that uses `LockService` is `src/cleveragents/cli/commands/system.py` (for diagnostic listing of stale locks), which is unrelated to plan execution. **Evidence:** - `grep -rn "LockService|lock_service" src/cleveragents/ | grep -v "lock_service.py"` → only `system.py` - `PlanLifecycleService.__init__` signature at line 183: no `lock_service` parameter - Container wiring at lines 661–668: no `lock_service` argument passed ## Expected Behavior Per the spec, before each phase transition (Strategize → Execute, Execute → Apply), `PlanLifecycleService` should: 1. Acquire an advisory lock on the plan resource (via `LockService.acquire`) before processing begins. 2. Release the lock after the transition completes or fails. 3. Raise `LockConflictError` (already defined) if another process holds the lock. This prevents race conditions when multiple CLI processes or async workers attempt concurrent transitions on the same plan. ## Acceptance Criteria - `PlanLifecycleService` accepts a `lock_service: LockService | None` constructor parameter. - Phase transition methods (`execute_plan`, `apply_plan`, `start_strategize`, `start_execute`, `start_apply`) acquire and release plan-level advisory locks. - The DI container wires `LockService` into `PlanLifecycleService`. - Unit tests (Behave) cover lock acquisition, release, and conflict detection during transitions. - Coverage remains ≥ 97%. ## Code Location - `src/cleveragents/application/services/plan_lifecycle_service.py` — `PlanLifecycleService.__init__` (line 183), phase transition methods (lines 1300, 1495, 1572, 1679, 1730) - `src/cleveragents/application/services/lock_service.py` — fully implemented but unused in lifecycle - `src/cleveragents/application/container.py` — lines 661–668: missing `lock_service` wiring ## Metadata - **Commit Message**: `fix(plan-lifecycle): wire LockService advisory locking into PlanLifecycleService phase transitions` - **Branch**: `fix/plan-lifecycle-advisory-locking` ## Subtasks - [ ] Add `lock_service: LockService | None` to `PlanLifecycleService.__init__` - [ ] Acquire/release plan lock in `start_strategize`, `execute_plan`, `apply_plan`, `start_execute`, `start_apply` - [ ] Wire `LockService` into `plan_lifecycle_service` provider in container - [ ] Tests (Behave): concurrent transition scenarios with lock conflict - [ ] Run `nox -s coverage_report`, verify ≥ 97% - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the first line matches the Commit Message in Metadata exactly. - The commit is pushed to the remote on the branch matching the Branch in Metadata exactly. - The commit is submitted as a pull request to `master`, reviewed, and merged before this issue is marked done. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
Sign in to join this conversation.
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#6258
No description provided.