UAT: PluginState.EXECUTING state defined but never set by PluginManager — lifecycle state machine incomplete #5691

Open
opened 2026-04-09 08:37:53 +00:00 by HAL9000 · 2 comments
Owner

Bug Report

Feature Area: Plugin Architecture — Plugin Lifecycle
Milestone: v3.6.0
Severity: Critical (incomplete lifecycle implementation)

What Was Tested

Analyzed src/cleveragents/infrastructure/plugins/types.py and src/cleveragents/infrastructure/plugins/manager.py for the EXECUTING lifecycle state.

Expected Behavior (from spec)

The PluginState enum in types.py defines the following lifecycle state machine:

DISCOVERED ──► ACTIVATED ──► EXECUTING ──► ACTIVATED
     │              │                          │
     │              └──► DEACTIVATED            └──► ERRORED
     │                                               │
     └──► ERRORED                                    └──► DEACTIVATED

The EXECUTING state is supposed to be set when a plugin is actively executing (i.e., when a plugin method is being called), and the plugin should transition back to ACTIVATED after execution completes, or to ERRORED if execution fails.

Actual Behavior

The EXECUTING state is defined in PluginState but is never set anywhere in the entire codebase:

# types.py — EXECUTING is defined:
class PluginState(StrEnum):
    DISCOVERED = "discovered"
    ACTIVATED = "activated"
    EXECUTING = "executing"   # ← defined but never used
    DEACTIVATED = "deactivated"
    ERRORED = "errored"

Searching the entire codebase for PluginState.EXECUTING returns zero results in the plugin infrastructure. The PluginManager.activate_plugin() sets ACTIVATED, deactivate_plugin() sets DEACTIVATED, and error paths set ERRORED, but no code ever sets EXECUTING.

Code Location

  • src/cleveragents/infrastructure/plugins/types.pyPluginState enum (lines 25–41)
  • src/cleveragents/infrastructure/plugins/manager.pyactivate_plugin() (line 222), deactivate_plugin() (line 279) — neither transitions through EXECUTING

Impact

  1. Observability gap: There is no way to distinguish a plugin that is actively executing from one that is idle but activated. This makes debugging plugin hangs or slow plugins impossible.
  2. Incomplete lifecycle: The spec-defined lifecycle state machine is not fully implemented. The EXECUTINGERRORED transition path (for catching plugin execution errors) is entirely missing.
  3. Thread safety gap: Without EXECUTING state, concurrent calls to the same plugin cannot be detected or prevented.

Steps to Reproduce

  1. Inspect src/cleveragents/infrastructure/plugins/manager.py — no PluginState.EXECUTING assignment
  2. Search codebase: grep -r "PluginState.EXECUTING" src/ — returns no results in plugin infrastructure

Suggested Fix

Add an execute_plugin() method to PluginManager that:

  1. Sets plugin state to EXECUTING before calling the plugin method
  2. Sets state back to ACTIVATED on success
  3. Sets state to ERRORED on exception
def execute_plugin(self, name: str, method: str, *args, **kwargs) -> Any:
    with self._lock:
        descriptor = self.get_plugin(name)
        if descriptor.state != PluginState.ACTIVATED:
            raise PluginError(f"Plugin '{name}' is not activated")
        descriptor.state = PluginState.EXECUTING
    try:
        instance = self._instances[name]
        result = getattr(instance, method)(*args, **kwargs)
        with self._lock:
            descriptor.state = PluginState.ACTIVATED
        return result
    except Exception as exc:
        with self._lock:
            descriptor.state = PluginState.ERRORED
        raise PluginError(f"Plugin '{name}' execution failed: {exc}") from exc

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

## Bug Report **Feature Area**: Plugin Architecture — Plugin Lifecycle **Milestone**: v3.6.0 **Severity**: Critical (incomplete lifecycle implementation) ### What Was Tested Analyzed `src/cleveragents/infrastructure/plugins/types.py` and `src/cleveragents/infrastructure/plugins/manager.py` for the `EXECUTING` lifecycle state. ### Expected Behavior (from spec) The `PluginState` enum in `types.py` defines the following lifecycle state machine: ``` DISCOVERED ──► ACTIVATED ──► EXECUTING ──► ACTIVATED │ │ │ │ └──► DEACTIVATED └──► ERRORED │ │ └──► ERRORED └──► DEACTIVATED ``` The `EXECUTING` state is supposed to be set when a plugin is actively executing (i.e., when a plugin method is being called), and the plugin should transition back to `ACTIVATED` after execution completes, or to `ERRORED` if execution fails. ### Actual Behavior The `EXECUTING` state is defined in `PluginState` but is **never set anywhere** in the entire codebase: ```python # types.py — EXECUTING is defined: class PluginState(StrEnum): DISCOVERED = "discovered" ACTIVATED = "activated" EXECUTING = "executing" # ← defined but never used DEACTIVATED = "deactivated" ERRORED = "errored" ``` Searching the entire codebase for `PluginState.EXECUTING` returns zero results in the plugin infrastructure. The `PluginManager.activate_plugin()` sets `ACTIVATED`, `deactivate_plugin()` sets `DEACTIVATED`, and error paths set `ERRORED`, but no code ever sets `EXECUTING`. ### Code Location - `src/cleveragents/infrastructure/plugins/types.py` — `PluginState` enum (lines 25–41) - `src/cleveragents/infrastructure/plugins/manager.py` — `activate_plugin()` (line 222), `deactivate_plugin()` (line 279) — neither transitions through `EXECUTING` ### Impact 1. **Observability gap**: There is no way to distinguish a plugin that is actively executing from one that is idle but activated. This makes debugging plugin hangs or slow plugins impossible. 2. **Incomplete lifecycle**: The spec-defined lifecycle state machine is not fully implemented. The `EXECUTING` → `ERRORED` transition path (for catching plugin execution errors) is entirely missing. 3. **Thread safety gap**: Without `EXECUTING` state, concurrent calls to the same plugin cannot be detected or prevented. ### Steps to Reproduce 1. Inspect `src/cleveragents/infrastructure/plugins/manager.py` — no `PluginState.EXECUTING` assignment 2. Search codebase: `grep -r "PluginState.EXECUTING" src/` — returns no results in plugin infrastructure ### Suggested Fix Add an `execute_plugin()` method to `PluginManager` that: 1. Sets plugin state to `EXECUTING` before calling the plugin method 2. Sets state back to `ACTIVATED` on success 3. Sets state to `ERRORED` on exception ```python def execute_plugin(self, name: str, method: str, *args, **kwargs) -> Any: with self._lock: descriptor = self.get_plugin(name) if descriptor.state != PluginState.ACTIVATED: raise PluginError(f"Plugin '{name}' is not activated") descriptor.state = PluginState.EXECUTING try: instance = self._instances[name] result = getattr(instance, method)(*args, **kwargs) with self._lock: descriptor.state = PluginState.ACTIVATED return result except Exception as exc: with self._lock: descriptor.state = PluginState.ERRORED raise PluginError(f"Plugin '{name}' execution failed: {exc}") from exc ``` --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.6.0 milestone 2026-04-09 08:38:56 +00:00
Author
Owner

Implementation Attempt — Tier 3: sonnet — Success

Implemented the PluginState.EXECUTING state in the plugin lifecycle state machine.

What was done:

  • Added execute_plugin() method to PluginManager in src/cleveragents/infrastructure/plugins/manager.py
    • Validates plugin is in ACTIVATED state before execution
    • Sets plugin state to PluginState.EXECUTING before invoking the plugin method
    • Transitions state back to ACTIVATED on successful execution
    • Transitions state to ERRORED on exception
    • Thread-safe implementation using threading.RLock
  • Created features/plugin_executing_state.feature with 10 BDD scenarios covering state transitions, error handling, and thread safety
  • Created features/steps/plugin_executing_state_steps.py with step definitions

Quality gates:

  • lint ✓
  • typecheck ✓ (0 errors, 3 warnings for optional ML deps)
  • unit_tests ✓ (643 scenarios passed, 0 failed)

PR: #10646


Automated by CleverAgents Bot
Supervisor: Implementation Pool | Agent: implementation-pool-supervisor

**Implementation Attempt** — Tier 3: sonnet — Success Implemented the `PluginState.EXECUTING` state in the plugin lifecycle state machine. **What was done:** - Added `execute_plugin()` method to `PluginManager` in `src/cleveragents/infrastructure/plugins/manager.py` - Validates plugin is in `ACTIVATED` state before execution - Sets plugin state to `PluginState.EXECUTING` before invoking the plugin method - Transitions state back to `ACTIVATED` on successful execution - Transitions state to `ERRORED` on exception - Thread-safe implementation using `threading.RLock` - Created `features/plugin_executing_state.feature` with 10 BDD scenarios covering state transitions, error handling, and thread safety - Created `features/steps/plugin_executing_state_steps.py` with step definitions **Quality gates:** - lint ✓ - typecheck ✓ (0 errors, 3 warnings for optional ML deps) - unit_tests ✓ (643 scenarios passed, 0 failed) **PR:** https://git.cleverthis.com/cleveragents/cleveragents-core/pulls/10646 --- **Automated by CleverAgents Bot** Supervisor: Implementation Pool | Agent: implementation-pool-supervisor
Author
Owner

Implementation Attempt — Tier 3: sonnet — Success

Implemented the PluginState.EXECUTING state in the plugin lifecycle state machine.

What was done:

  • Added execute_plugin() method to PluginManager in src/cleveragents/infrastructure/plugins/manager.py
    • Validates plugin is in ACTIVATED state before execution
    • Sets plugin state to PluginState.EXECUTING before invoking the plugin method
    • Transitions state back to ACTIVATED on successful execution
    • Transitions state to ERRORED on exception
    • Thread-safe implementation using threading.RLock
  • Created features/plugin_executing_state.feature with 10 BDD scenarios covering state transitions, error handling, and thread safety
  • Created features/steps/plugin_executing_state_steps.py with step definitions

Quality gates:

  • lint ✓
  • typecheck ✓ (0 errors, 3 warnings for optional ML deps)
  • unit_tests ✓ (643 scenarios passed, 0 failed)

PR: #10646


Automated by CleverAgents Bot
Supervisor: Implementation Pool | Agent: implementation-pool-supervisor

**Implementation Attempt** — Tier 3: sonnet — Success Implemented the `PluginState.EXECUTING` state in the plugin lifecycle state machine. **What was done:** - Added `execute_plugin()` method to `PluginManager` in `src/cleveragents/infrastructure/plugins/manager.py` - Validates plugin is in `ACTIVATED` state before execution - Sets plugin state to `PluginState.EXECUTING` before invoking the plugin method - Transitions state back to `ACTIVATED` on successful execution - Transitions state to `ERRORED` on exception - Thread-safe implementation using `threading.RLock` - Created `features/plugin_executing_state.feature` with 10 BDD scenarios covering state transitions, error handling, and thread safety - Created `features/steps/plugin_executing_state_steps.py` with step definitions **Quality gates:** - lint ✓ - typecheck ✓ (0 errors, 3 warnings for optional ML deps) - unit_tests ✓ (643 scenarios passed, 0 failed) **PR:** https://git.cleverthis.com/cleveragents/cleveragents-core/pulls/10646 --- **Automated by CleverAgents Bot** Supervisor: Implementation Pool | Agent: implementation-pool-supervisor
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.

Reference
cleveragents/cleveragents-core#5691
No description provided.