All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.7.0 - 2026-03-01
- ApprovalHandler Protocol - Async protocol for pluggable approval handlers with
request_approval()andcheck_approval()methods - ApprovalRequest / ApprovalResult - Frozen dataclasses carrying invocation context and handler decisions with
Literalstatus typing - Phase A (synchronous) - Handler blocks until approval decision; denied/timeout raise immediately
- Phase B (asynchronous) -
pendingstatus returns_approval_tokenfor async resume viacheck_approval() - Built-in handlers -
AlwaysDenyHandler(safe default),AutoApproveHandler(testing),CallbackApprovalHandler(custom logic) - Approval errors -
ApprovalError,ApprovalDeniedError,ApprovalTimeoutError,ApprovalPendingErrorwithresult,module_id, andreasonproperties - Audit events (Level 3) - Dual-channel emission:
logging.info()always + span events when tracing is active - Extension point -
approval_handlerregistered as a built-in extension point inExtensionManager - ErrorCodes - Added
APPROVAL_DENIED,APPROVAL_TIMEOUT,APPROVAL_PENDINGconstants
- Step 4.5 approval gate - Inserted between ACL (Step 4) and input validation (Step 5) in
call(),call_async(), andstream() - Executor.set_approval_handler() - Runtime handler configuration
- Executor.from_registry() - Added
approval_handlerparameter - Dict and dataclass annotations - Both
ModuleAnnotationsand dict-stylerequires_approvalsupported - Unknown status fail-closed - Unrecognized approval statuses treated as denied with warning log
- Approval errors re-exported from
apcore.approvalfor multi-language SDK consistency; canonical definitions remain inerrors.py ApprovalResult.statustyped asLiteral["approved", "rejected", "timeout", "pending"]per PROTOCOL_SPEC §7.3.2
0.6.0 - 2026-02-23
- ExtensionManager / ExtensionPoint - Added a unified extension-point framework for
discoverer,middleware,acl,span_exporter, andmodule_validator - Extension wiring - Added
apply()support to connect registered extensions intoRegistryandExecutor
- AsyncTaskManager - Added background task orchestration with status tracking, cancellation, concurrency limits, shutdown, and cleanup
- TaskStatus / TaskInfo - Added task lifecycle enum and metadata dataclass for async task management
- CancelToken / ExecutionCancelledError - Added cooperative cancellation primitives and integrated cancellation checks into executor flows
- TraceContext / TraceParent - Added W3C Trace Context utilities for
inject(),extract(), and strict parsing viafrom_traceparent() - Context.create(trace_parent=...) - Added distributed-tracing entry support by accepting inbound trace context
- OTLPExporter top-level export - Added OTLP exporter re-exports in observability and top-level public API
- Custom discoverer/validator hooks - Added
set_discoverer()andset_validator()integration paths - Module describe support - Added
Registry.describe()for human-readable module descriptions - Hot-reload APIs - Added
watch(),unwatch(), and file-change handling helpers for extension directories - Validation constants/protocols - Added
MAX_MODULE_ID_LENGTH,RESERVED_WORDS,Discoverer, andModuleValidatorexports
- Expanded top-level
apcoreexports to include cancellation, extensions, async task types, trace context types, additional registry protocols/constants, and new error classes
- Added
ModuleExecuteErrorandInternalErrorto the framework error hierarchy and exports - Extended
ErrorCodeswith additional constants used by newer execution/extension paths
- executor - Added recursive
_secret_key redaction for nested dictionaries - executor - Preserved explicit cancellation semantics by re-raising
ExecutionCancelledError
- Reduced import-coupling risk across middleware/observability/trace typing paths while preserving existing runtime behavior and public interfaces
0.5.0 - 2026-02-22
- decorator - Renamed
_generate_input_model/_generate_output_modeltogenerate_input_model/generate_output_modelas public API - context_logger - Renamed
formatparameter tooutput_formatto avoid shadowing Python builtin - registry - Renamed
_write_lockto_lockfor clearer intent
- decorator - Replaced bare
dictwithdict[str, Any]in_normalize_result,annotations,metadata,_async_execute,_sync_execute - bindings - Fixed
_build_model_from_json_schemaparameter type fromdicttodict[str, Any] - scanner - Fixed
rootsparameter type fromlist[dict]tolist[dict[str, Any]] - metrics - Fixed
snapshotreturn type fromdicttodict[str, Any] - executor - Removed redundant string-quoted forward references in
from_registry; fixedmiddlewaresparameter type tolist[Middleware] | None
- executor - Extracted
_convert_validation_errors()helper to eliminate 6 duplicated validation error conversion patterns - executor - Refactored
call_async()andstream()to use new async middleware manager methods - executor - Removed internal
_execute_on_error_asyncmethod (replaced byMiddlewareManager.execute_on_error_async) - loader - Use
self._resolver.clear_cache()instead of accessing private_file_cachedirectly - tracing - Replaced
print()withsys.stdout.write()inStdoutExporter - acl / loader - Changed hardcoded logger names to
logging.getLogger(__name__)
- ExtensionManager and ExtensionPoint for unified extension point management (discoverer, middleware, acl, span_exporter, module_validator) with
register(),get(),get_all(),unregister(),apply(),list_points()methods - AsyncTaskManager, TaskStatus, TaskInfo for async task execution with status tracking (PENDING, RUNNING, COMPLETED, FAILED, CANCELLED), cancellation, and concurrency limiting
- TraceContext and TraceParent for W3C Trace Context support with
inject(),extract(), andfrom_traceparent()methods Context.create()now accepts optionaltrace_parentparameter for distributed trace propagation
- MiddlewareManager - Added
execute_before_async(),execute_after_async(),execute_on_error_async()for proper async middleware dispatch withinspect.iscoroutinefunctiondetection - RefResolver - Added
clear_cache()public method for cache management - Executor - Added
clear_async_cache()public method
- SchemaExporter - Added
streaminghint toexport_mcp()annotations fromModuleAnnotations
- context - Changed
Identity.rolesfrom mutablelist[str]to immutabletuple[str, ...]in frozen dataclass
- context_logger / metrics - Handle cases where
before()was never called inObsLoggingMiddlewareandMetricsMiddleware
- acl - Added explicit
encoding="utf-8"to YAML file open
0.4.0 - 2026-02-20
- Executor.stream() - New async generator method for streaming module execution
- Implements same 6-step pipeline as
call_async()(context, safety, lookup, ACL, input validation, middleware before) - Falls back to
call_async()yielding single chunk for non-streaming modules - For streaming modules, iterates
module.stream()and yields each chunk - Accumulates chunks via shallow merge for output validation and after-middleware
- Full error handling with middleware recovery
- Implements same 6-step pipeline as
- ModuleAnnotations.streaming - New
streaming: bool = Falsefield to indicate if a module supports streaming execution - Test coverage - Added 5 comprehensive tests in
test_executor_stream.py:- Fallback behavior for non-streaming modules
- Multi-chunk streaming
- Module not found error handling
- Before/after middleware integration
- Disjoint key accumulation via shallow merge
0.3.0 - 2026-02-20
- ErrorCodes - New
ErrorCodesclass with all framework error code constants; replaces hardcoded error strings - ContextFactory Protocol - New
ContextFactoryprotocol for creating Context from framework-specific requests (e.g., Django, FastAPI) - Registry constants - Exported
REGISTRY_EVENTSdict andMODULE_ID_PATTERNregex for consistent module ID validation - Executor.from_registry() - Convenience factory method for creating an Executor from a Registry with optional middlewares, ACL, and config
- Comprehensive schema system - Full implementation with loading, validation, and export capabilities
- Schema loading from JSON/YAML files
- Runtime schema validation
- Schema export functionality
- ErrorCodes class - Prevent attribute deletion to ensure error code constants remain immutable
- Planning documentation - Updated progress bar style in overview.md
0.2.3 - 2026-02-20
- ContextFactory Protocol - New
ContextFactoryprotocol for creating Context from framework-specific requests (e.g., Django, FastAPI) - ErrorCodes - New
ErrorCodesclass with all framework error code constants; replaces hardcoded error strings - Registry constants - Exported
REGISTRY_EVENTSdict andMODULE_ID_PATTERNregex for consistent module ID validation - Executor.from_registry() - Convenience factory method for creating an Executor from a Registry with optional middlewares, ACL, and config
- Module ID validation - Strengthened to enforce lowercase letters, digits, underscores, and dots only; no hyphens allowed. Pattern:
^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)*$ - Registry events - Replaced hardcoded event strings with
REGISTRY_EVENTSconstant dict - Test fixtures - Updated registry test module IDs to comply with new module ID pattern
- .code-forge.json - Updated directory mappings:
basefromplanning/to./;inputfromfeatures/to../apcore/docs/features
- Better type hints and protocol definitions for framework integration
- Consistent error handling with standardized error codes
0.2.2 - 2026-02-16
- planning/features/ - Moved all feature specifications to
apcore/docs/features/for better organization with documentation - planning/implementation/ - Restructured implementation planning to consolidate with overall project architecture
- Implementation planning - Reorganized implementation plans to streamline project structure and improve maintainability
0.2.1 - 2026-02-14
- code-forge integration - Added
.code-forge.jsonconfiguration (v0.2.0 spec) with_toolmetadata, directory mappings, and execution settings - Feature specifications - 7 feature documents in
planning/features/covering all core modules: core-executor, schema-system, registry-system, middleware-system, acl-system, observability, decorator-bindings - Implementation plans - Complete implementation plans in
planning/implementation/for all 7 features, each containingoverview.md,plan.md,tasks/*.md, andstate.json - Project-level overview - Auto-generated
planning/implementation/overview.mdwith module dependency graph, progress tracking, and phased implementation order - Task breakdown - 42 task files with TDD-oriented steps, acceptance criteria, dependency tracking, and time estimates (~91 hours total estimated effort)
0.2.0 - 2026-02-14
- MiddlewareManager - Added internal locking and snapshot pattern;
add(),remove(),execute_before(),execute_after()are now thread-safe - Executor - Added lock to async module cache; use
snapshot()for middleware iteration incall_async()andmiddlewaresproperty - ACL - Internally synchronized;
check(),add_rule(),remove_rule(),reload()are now safe for concurrent use - Registry - Extended existing
RLockto cover all read paths (get,has,count,module_ids,list,iter,get_definition,on,_trigger_event,clear_cache)
- InMemoryExporter - Replaced unbounded
listwithcollections.deque(maxlen=10_000)and addedthreading.Lockfor thread-safe access
- TracingMiddleware - Added empty span stack guard in
after()andon_error()to log a warning instead of raisingIndexError - Executor - Set
daemon=Trueon timeout and async bridge threads to prevent blocking process exit
- apdev integration - Added
apdev[dev]as development dependency for code quality checks and project tooling - pip install support - Moved dev dependencies to
[project.optional-dependencies]sopip install -e ".[dev]"works alongsideuv sync --group dev - pre-commit hooks - Fixed
check-charsandcheck-importshooks to run as local hooks viaapdevinstead of incorrectly nesting underruff-pre-commitrepo
- Context.child() - Added docstring clarifying that
datais intentionally shared between parent and child for middleware state propagation
0.1.0 - 2026-02-13
- Schema-driven modules - Define modules with Pydantic input/output schemas and automatic validation
- @module decorator - Zero-boilerplate decorator to turn functions into schema-aware modules
- Executor - 10-step execution pipeline with comprehensive safety and security checks
- Registry - Module registration and discovery system with metadata support
- Access Control (ACL) - Pattern-based, first-match-wins rule system with wildcard support
- Call depth limits - Prevent infinite recursion and stack overflow
- Circular call detection - Detect and prevent circular module calls
- Frequency throttling - Rate limit module execution
- Timeout support - Configure execution timeouts per module
- Composable pipeline - Before/after hooks for request/response processing
- Error recovery - Graceful error handling and recovery in middleware chain
- LoggingMiddleware - Structured logging for all module calls
- TracingMiddleware - Distributed tracing with span support for observability
- YAML bindings - Register modules declaratively without modifying source code
- Configuration system - Centralized configuration management
- Environment support - Environment-based configuration override
- Tracing - Span-based distributed tracing integration
- Metrics - Built-in metrics collection for execution monitoring
- Context logging - Structured logging with execution context propagation
- Sync/Async modules - Seamless support for both synchronous and asynchronous execution
- Async executor - Non-blocking execution for async-first applications
- Type safety - Full type annotations across the framework (Python 3.11+)
- Comprehensive tests - 90%+ test coverage with unit and integration tests
- Documentation - Quick start guide, examples, and API documentation
- Examples - Sample modules demonstrating decorator-based and class-based patterns
- pydantic >= 2.0 - Schema validation and serialization
- pyyaml >= 6.0 - YAML binding support
- Python 3.11+