Skip to content

Commit 8add41d

Browse files
committed
feat: Refine middleware on_error return behavior and priority, and expand core scope with approval and event systems.
1 parent 3840573 commit 8add41d

File tree

5 files changed

+37
-20
lines changed

5 files changed

+37
-20
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
- **`docs/features/middleware-system.md`** — Added `retry.py` to Key Files table (was described in Components but missing from file list)
1919
- **`docs/features/observability.md`** — Added concrete metric names (`apcore_module_calls_total`, `apcore_module_errors_total`, `apcore_module_duration_seconds`) to convenience method documentation
2020

21+
#### Protocol Specification
22+
- Fixed duplicate `### 10.5` section numbering — renumbered Sensitive Data Redaction to §10.6, Sampling Strategy to §10.7, Span Naming Convention to §10.8
23+
- Fixed `### 8.1.1` misnumbered under §9.1 — corrected to §9.1.1
24+
- Fixed `### 10.8.x` misnumbered under §11.8 — corrected to §11.8.1–§11.8.4
25+
- Fixed middleware priority model contradiction between §11.2 (explicit 0-1000) and §12 (registration order) — §12 now aligns with §11.2
26+
- Fixed `on_error` examples in README.md and concepts.md — changed `raise error` to correct return-based contract (`return None` / `return dict`)
27+
- Updated "Last Updated" date to 2026-03-24
28+
29+
#### Scope Document
30+
- Added Approval System (§7) and Event System to "Core Protocol Includes" list in SCOPE.md
31+
2132
#### README
2233
- Added AI-Perceivable brand definition block to README header
2334
- Added "Perceived → Understood → Executed" progression table to "Why AI-Perceivable?" section

PROTOCOL_SPEC.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
> Version: 1.5.0-draft
66
> Status: Draft Specification (RFC 2119 Conformant)
77
> Stability: Specification content is stable, pending reference implementation verification
8-
> Last Updated: 2026-03-20
8+
> Last Updated: 2026-03-24
99
1010
---
1111

@@ -4273,7 +4273,7 @@ id_map:
42734273
overrides: {} # MAY, manual ID mapping overrides
42744274
```
42754275

4276-
#### 8.1.1 Default Values Summary
4276+
#### 9.1.1 Default Values Summary
42774277

42784278
Implementations **must** follow these default value conventions:
42794279

@@ -4474,7 +4474,7 @@ trace_id_spec:
44744474
- "MUST NOT allow externally provided unvalidated trace_id"
44754475
```
44764476

4477-
### 10.5 Sensitive Data Redaction
4477+
### 10.6 Sensitive Data Redaction
44784478

44794479
Implementations **must** redact fields marked as `x-sensitive` in logs and trace outputs.
44804480

@@ -4503,7 +4503,7 @@ Steps:
45034503
Complexity: O(n), where n is number of data fields
45044504
```
45054505
4506-
### 10.6 Sampling Strategy
4506+
### 10.7 Sampling Strategy
45074507
45084508
Implementations **should** support the following sampling strategies:
45094509
@@ -4516,7 +4516,7 @@ Implementations **should** support the following sampling strategies:
45164516
45174517
Sampling decision **must** be made at call chain root node, child calls **must** inherit parent call's sampling decision.
45184518
4519-
### 10.7 Span Naming Convention
4519+
### 10.8 Span Naming Convention
45204520
45214521
Implementations **should** follow these Span naming conventions:
45224522
@@ -4816,7 +4816,7 @@ Steps:
48164816

48174817
Implementations **must** handle middleware edge cases according to the following table:
48184818

4819-
#### 10.8.1 on_error Cascade
4819+
#### 11.8.1 on_error Cascade
48204820

48214821
| Scenario | Behavior | Level |
48224822
|------|------|------|
@@ -4825,7 +4825,7 @@ Implementations **must** handle middleware edge cases according to the following
48254825
| `on_error()` returns `None` | Continue propagating error downward | **MUST** |
48264826
| All `on_error()` return `None` | Throw original error to caller | **MUST** |
48274827

4828-
#### 10.8.2 before() Edges
4828+
#### 11.8.2 before() Edges
48294829

48304830
| Scenario | Behavior | Level |
48314831
|------|------|------|
@@ -4835,7 +4835,7 @@ Implementations **must** handle middleware edge cases according to the following
48354835
| `before()` throws `ModuleError` | Trigger `on_error()` chain, skip module execution | **MUST** |
48364836
| `before()` modifies `context.data` | Allowed, modifications visible to subsequent middleware and module | **MUST** |
48374837

4838-
#### 10.8.3 after() Edges
4838+
#### 11.8.3 after() Edges
48394839

48404840
| Scenario | Behavior | Level |
48414841
|------|------|------|
@@ -4844,7 +4844,7 @@ Implementations **must** handle middleware edge cases according to the following
48444844
| `after()` throws `ModuleError` | Trigger `on_error()` chain, replace original result | **MUST** |
48454845
| `after()` returns value not matching `output_schema` | Trigger `SCHEMA_VALIDATION_ERROR` | **MUST** |
48464846

4847-
#### 10.8.4 Timeout Related
4847+
#### 11.8.4 Timeout Related
48484848

48494849
| Scenario | Behavior | Level |
48504850
|------|------|------|
@@ -5021,9 +5021,9 @@ Interface: MiddlewareManager
50215021
* Register middleware
50225022
* @param middleware — Middleware instance
50235023
*
5024-
* Note: Priority is determined by registration order, not by an explicit
5025-
* priority parameter. Middleware registered first executes first (before)
5026-
* and last (after), following the onion model.
5024+
* Note: Priority is explicit (0-1000, higher executes first), as defined
5025+
* in §11.2. Registration order is used only as a tiebreaker when two
5026+
* middleware have equal priority. Execution follows the onion model.
50275027
*/
50285028
add(middleware: Middleware) → void
50295029

@@ -5041,7 +5041,7 @@ Interface: MiddlewareManager
50415041
Interface: TracingProvider
50425042
/**
50435043
* Create new Span
5044-
* @param name — Span name (follows §10.7 naming convention)
5044+
* @param name — Span name (follows §10.8 naming convention)
50455045
* @param context — Execution context (contains trace_id, parent_span_id)
50465046
* @return span — Span object
50475047
*/

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,9 @@ class LoggingMiddleware(Middleware):
793793
794794
def on_error(self, module_id: str, inputs: dict, error: Exception, context: Context):
795795
log.error(f"Error in {module_id}: {error}")
796-
# Optional: Convert exception, trigger alerts, etc.
796+
# Return None to continue error propagation
797+
# Return a dict to stop propagation and use it as recovery output
798+
return None
797799
```
798800

799801
Typical middleware scenarios: logging, performance monitoring, caching, rate limiting, retry, auditing.

SCOPE.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,13 @@ Use these scenarios to validate whether our boundaries are correct:
197197
3. Schema specification (Schema)
198198
4. Module specification (Module)
199199
5. Access control configuration (ACL)
200-
6. Error handling (Error)
201-
7. Observability (Observability)
202-
8. Extension mechanism (Extension)
203-
9. Configuration specification (Configuration)
204-
10. Existing application integration (module() + External Binding)
200+
6. Approval system (Approval)
201+
7. Error handling (Error)
202+
8. Observability (Observability)
203+
9. Extension mechanism (Extension)
204+
10. Configuration specification (Configuration)
205+
11. Event system (Registry events, lifecycle hooks)
206+
12. Existing application integration (module() + External Binding)
205207

206208
### Appendix Reference (Non-core):
207209
- AI protocol mapping references (MCP, A2A, OpenAI Functions)

docs/concepts.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,9 @@ class LoggingMiddleware(Middleware):
721721
def on_error(self, module_id: str, inputs: dict, error: Exception, context: Context):
722722
"""On error"""
723723
print(f"[{context.trace_id}] {module_id} failed: {error}")
724-
raise error # Or handle error
724+
# Return None to continue error propagation
725+
# Return a dict to stop propagation and use it as recovery output
726+
return None
725727
```
726728

727729
**Middleware registration:**

0 commit comments

Comments
 (0)