Skip to content

Commit e838117

Browse files
committed
refactor: execution modes
Signed-off-by: Frederico Araujo <frederico.araujo@ibm.com>
1 parent 399f050 commit e838117

20 files changed

Lines changed: 555 additions & 224 deletions

README.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,26 @@ A plugin method can:
164164

165165
### Execution Modes
166166

167-
Plugins run in phases in this order: `sequential``audit``concurrent``fire_and_forget`.
167+
Plugins run in phases in this order:
168168

169-
| Mode | Execution | Can block? | State merged? | Use case |
170-
|------|-----------|:-----------:|:-------------:|---------|
171-
| `sequential` | One at a time, chained | Yes | Yes | Enforcement pipelines |
172-
| `audit` | One at a time, chained | No | No | Logging, monitoring |
173-
| `concurrent` | Parallel, fail-fast | Yes | Yes | Independent validations |
174-
| `fire_and_forget` | Background, after all phases | No | No | Telemetry, audit logs |
175-
| `disabled` | Not loaded ||| Plugin off |
169+
```
170+
sequential → transform → audit → concurrent → fire_and_forget
171+
```
172+
173+
| Mode | Execution | Can block? | Can modify? | State merged? | Use case |
174+
|------|-----------|:-----------:|:-----------:|:-------------:|---------|
175+
| `sequential` | Serial, chained | Yes | Yes | Yes | Policy enforcement + transformation |
176+
| `transform` | Serial, chained | No | Yes | Yes | Data transformation (redaction, rewriting) |
177+
| `audit` | Serial | No | No | No | Logging, monitoring, metrics |
178+
| `concurrent` | Parallel, fail-fast | Yes | No | Yes | Independent policy gates |
179+
| `fire_and_forget` | Background, after all phases | No | No | No | Telemetry, audit logs |
180+
| `disabled` | Not loaded |||| Plugin off |
181+
182+
- **`sequential`** plugins are awaited one at a time in priority order. Each receives the chained output of the previous plugin. Can halt the pipeline and modify payloads. Use for enforcement + transformation.
183+
- **`transform`** plugins are awaited one at a time after all sequential plugins. Can modify payloads but blocking attempts are suppressed. Use for data transformation pipelines (PII redaction, prompt rewriting) that should not have policy-enforcement power.
184+
- **`audit`** plugins are awaited one at a time after transform. Observe-only: payload modifications are discarded and violations are logged but do not block. Use for monitoring, auditing, and gradual rollout of policies.
185+
- **`concurrent`** plugins are dispatched in parallel after audit. Can halt the pipeline (fail-fast on first blocking result) but payload modifications are discarded to avoid non-deterministic last-writer-wins races. Use for independent policy gates.
186+
- **`fire_and_forget`** plugins are dispatched as background tasks after all other phases. They receive an isolated snapshot. Cannot block or modify. Use for telemetry and async side effects.
176187

177188
Error handling is configured separately with `on_error`, independent of mode:
178189

@@ -230,17 +241,17 @@ plugins:
230241
231242
### Priority
232243
233-
Plugins are scheduled by mode, and execute in priority order within sequential bands (lower number = higher priority). Use this to ensure validation runs before transformation, and transformation runs before logging.
244+
Plugins are scheduled by mode, and execute in priority order within each phase (lower number = higher priority). Use this to ensure enforcement runs before transformation, and transformation runs before logging.
234245
235246
**Plugin Scheduling**
236247
237-
At each hook invocation, plugins are grouped and scheduled by execution modes, following a strict group order:
248+
At each hook invocation, plugins are grouped and scheduled by execution mode, following a strict phase order:
238249
239250
```
240-
sequential → audit → concurrent → fire_and_forget
251+
sequential → transform → audit → concurrent → fire_and_forget
241252
```
242253

243-
Within sequential and audit groups, plugins execute in **priority order** (lower number = higher priority, e.g., `10` runs before `20`).
254+
Within `sequential`, `transform`, and `audit` phases, plugins execute in **priority order** (lower number = higher priority, e.g., `10` runs before `20`).
244255

245256
### Conditions
246257

cpex/framework/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# First-Party
2020
from cpex.framework.base import Plugin
2121
from cpex.framework.decorator import hook
22-
from cpex.framework.errors import PluginError, PluginFrameworkError, PluginViolationError
22+
from cpex.framework.errors import PluginError, PluginViolationError
2323
from cpex.framework.external.mcp.server import ExternalPluginServer
2424
from cpex.framework.hooks.agents import (
2525
AgentHookType,
@@ -163,7 +163,6 @@ def get_plugin_manager(
163163
"PluginContextTable",
164164
"PluginError",
165165
"PluginErrorModel",
166-
"PluginFrameworkError",
167166
"PluginLoader",
168167
"PluginManager",
169168
"PluginMode",

cpex/framework/errors.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,6 @@
1313
from cpex.framework.models import PluginErrorModel, PluginViolation
1414

1515

16-
class PluginFrameworkError(Exception):
17-
"""An error originating from the plugin framework itself (not from a plugin).
18-
19-
Raised when an internal framework operation fails — for example, when
20-
payload isolation cannot deep-copy a value.
21-
22-
Attributes:
23-
message (str): Description of the framework error.
24-
"""
25-
26-
def __init__(self, message: str):
27-
"""Initialize a plugin framework error.
28-
29-
Args:
30-
message: Description of what went wrong.
31-
32-
Examples:
33-
>>> from cpex.framework.errors import PluginFrameworkError
34-
>>> err = PluginFrameworkError("cannot isolate payload")
35-
>>> str(err)
36-
'cannot isolate payload'
37-
"""
38-
self.message = message
39-
super().__init__(self.message)
40-
41-
4216
class PluginViolationError(Exception):
4317
"""A plugin violation error.
4418

0 commit comments

Comments
 (0)