You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+26Lines changed: 26 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
---
9
9
10
+
## [0.17.0] - 2026-04-04
11
+
12
+
### Added
13
+
14
+
#### Pipeline v2 — Declarative Step Metadata
15
+
-**4 new BaseStep fields** — `match_modules` (glob patterns for selective step execution), `ignore_errors` (fault-tolerant continuation on step failure), `pure` (no side effects, safe for dry-run/validate mode), `timeout_ms` (per-step timeout in milliseconds). Implemented across all three SDKs (Python, TypeScript, Rust).
16
+
-**`PipelineContext.dry_run`** — When `true`, PipelineEngine skips steps with `pure=false`, enabling `validate()` to run user-defined pure steps automatically.
17
+
-**`PipelineContext.version_hint`** — Passed through to module_lookup for version negotiation.
18
+
-**`PipelineContext.executed_middlewares`** — Tracks which middleware ran for on_error recovery chain.
19
+
-**`StepTrace.skip_reason`** — Records why a step was skipped: `"no_match"`, `"dry_run"`, or `"error_ignored"`.
20
+
-**YAML pipeline configuration** (Python) — `pipeline` section in `apcore.yaml` with `remove`, `configure`, and `steps` directives. Step resolution via `type` (registry) and `handler` (import path).
21
+
22
+
### Changed
23
+
24
+
#### Pipeline Step Rename
25
+
-**`safety_check` → `call_chain_guard`** — Renamed across all SDKs to accurately describe the step's purpose (call chain depth/cycle/repeat checks, not transport-level rate limiting).
26
+
-**TypeScript `builtin.` prefix removed** — All built-in step names in the TypeScript SDK dropped the `builtin.` prefix for cross-SDK consistency (e.g., `builtin.context_creation` → `context_creation`).
27
+
28
+
#### Pipeline Step Order
29
+
-**Steps 6 and 7 swapped** — `middleware_before` now executes before `input_validation` (was the reverse). Middleware transforms are now validated by the subsequent input_validation step, aligning with the Kubernetes Mutating → Validating admission order.
30
+
31
+
### Fixed
32
+
-**Middleware transforms now validated** — Previously, middleware modifications to inputs were either never re-validated (production code) or silently discarded (pipeline abstraction). The step order swap ensures transformed inputs pass schema validation.
Each step in the pipeline now supports four declarative metadata fields: `match_modules` (glob patterns for selective execution), `ignore_errors` (fault-tolerant continuation), `pure` (dry-run safety marker), and `timeout_ms` (per-step timeout). See [Core Executor](../features/core-executor.md) for details.
658
+
656
659
### 6.2 Automatic Context Handling
657
660
658
661
When modules internally call other modules, Executor automatically handles Context:
@@ -682,7 +685,7 @@ result = context.executor.call(
Copy file name to clipboardExpand all lines: docs/features/core-executor.md
+15-3Lines changed: 15 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ The executor processes every module call through the following pipeline:
22
22
23
23
1.**Context Creation** -- A `Context` object is constructed carrying the caller identity, call metadata, and any propagated state from parent calls. This context flows through every subsequent step.
24
24
25
-
2.**Safety Checks** -- Three safety mechanisms are evaluated before proceeding:
25
+
2.**Call Chain Guard** -- Three safety mechanisms are evaluated before proceeding:
26
26
-*Call depth check*: Rejects calls that exceed the configured maximum nesting depth, preventing unbounded recursion.
27
27
-*Circular call detection*: Inspects the call chain recorded in the context to detect and reject circular module invocations.
28
28
-*Frequency throttling*: Tracks call frequency per module and rejects calls that exceed the configured rate, protecting against tight-loop abuse.
@@ -33,9 +33,9 @@ The executor processes every module call through the following pipeline:
33
33
34
34
5.**Approval Gate** -- If an `ApprovalHandler` is configured and the module declares `requires_approval=true`, the handler is invoked to obtain approval before proceeding. The handler may block for human input or return immediately. Rejected, timed-out, or still-pending approvals raise `ApprovalDeniedError`, `ApprovalTimeoutError`, or `ApprovalPendingError` respectively. Skipped entirely when no handler is configured or the module does not require approval. See [Approval System](./approval-system.md).
35
35
36
-
6.**Input Validation with Pydantic + Sensitive Field Redaction** -- The call's input payload is validated against the module's input schema (a dynamically generated Pydantic model). Fields annotated with `x-sensitive` are redacted from logs and error messages using the `redact_sensitive` utility.
36
+
6.**Middleware Before Chain** -- All registered "before" middleware functions are executed in order. Each middleware receives the context and input, and may modify or enrich them before validation runs.
37
37
38
-
7.**Middleware Before Chain** -- All registered "before" middleware functions are executed in order. Each middleware receives the context and validated input, and may modify or enrich them before the module runs.
38
+
7.**Input Validation with Pydantic + Sensitive Field Redaction** -- The call's input payload (including any modifications from middleware) is validated against the module's input schema (a dynamically generated Pydantic model). Fields annotated with `x-sensitive` are redacted from logs and error messages using the `redact_sensitive` utility.
39
39
40
40
8.**Module Execution with Timeout (Dual-Timeout Model)** -- The module's handler is invoked with dual-timeout enforcement: both a per-module timeout (`resources.timeout`, default 30s) and a global deadline (`executor.global_timeout`, default 60s). The shorter of the two is applied, preventing nested call chains from exceeding the global budget. The global deadline is set on the root call and propagated to child contexts via `Context._global_deadline`.
41
41
@@ -47,6 +47,18 @@ The executor processes every module call through the following pipeline:
47
47
48
48
11.**Result Return** -- The final validated output (or error) is packaged into a structured result and returned to the caller.
49
49
50
+
!!! info "Step Metadata"
51
+
Each pipeline step declares four metadata fields:
52
+
53
+
| Field | Type | Default | Purpose |
54
+
|-------|------|---------|---------|
55
+
| `match_modules` | glob patterns or null | `null` (all) | Only run this step for matching module IDs |
56
+
| `ignore_errors` | bool | `false` | If true, step failure logs warning and continues |
57
+
| `pure` | bool | `false` | If true, safe to run during `validate()` dry-run mode |
58
+
| `timeout_ms` | int | `0` | Per-step timeout in milliseconds (0 = no limit) |
59
+
60
+
These fields enable targeted step application, fault-tolerant pipelines, and dry-run validation without code changes.
61
+
50
62
### Key Classes
51
63
52
64
-**Executor** -- The main engine class that implements the execution pipeline. Manages middleware registration, timeout configuration, and the execution loop.
0 commit comments