Changelog¶
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.
[2.5.3] - 2026-09-09¶
Fixed¶
PluginLoader.shutdown():_stop_onecoroutine was defined but never awaited —self._handlers.clear()was called immediately, bypassing all plugin cleanup (on_unloadhooks, resource release). Now usesasyncio.gatherwith timeout per handler before clearing.AutoDispatchMixin.handle(): Scanneddir(self)on every dispatch (O(N) per call). Added lazy_build_action_map()that pre-computes adict[action_name → method]for O(1) dispatch.RoutedPlugin: Method namedRouterIn()butlifecycle.pylooks forget_router()— renamed toget_router()for consistency.PermissionEnginecache: Unboundeddictgrew forever within process lifetime. Replaced withOrderedDict-based LRU cache (max 10,000 entries) with automatic eviction of oldest entries.- TenantAware wrappers (
TenantAwareCache/DB/Scheduler):__getattr__proxy hid API surface from IDEs and mypy. Added explicit method declarations formget,mset,disconnect,ping,stats(Cache),connect,disconnect,ping,status,engine(DB),start,shutdown,health_check,status(Scheduler). - Version mismatch:
__version__.pywas2.3.3,pyproject.tomlwas2.5.2, README badge wasv2.3.5. Synced all to2.5.2. - Dead code: Removed unused
__TenancyConfigdataclass inconfigurations/sections.py. _is_db_adapter(): Fragile class-name-suffix detection replaced withisinstance()checks against actual adapter classes, with fallback for missing imports.RedisCacheBackend.clear(): Calledflushdb()which deleted the entire Redis database (not just cache keys). Now usesSCAN + DELETEto only remove matching keys.TenantAwareDB._set_tenant_schema(): Used unquoted f-string inSET search_path TO {tenant}, public. Now quotes the identifier with double quotes ("{tenant}") for PostgreSQL defense-in-depth against injection.
Changed¶
- Version synced to 2.5.3 across
__version__.py,pyproject.toml, and README badge.
[2.5.1] - 2026-08-20¶
Fixed¶
[cpp]/[all]extras removed (urgent):2.5.0shippedcpp = ["xscanner>=0.1.0"], butxscanneron PyPI is an unrelated third-party package — we never owned that name.pip install XCoreRuntime[cpp]would have silently installed a stranger's package instead of failing. Dropped both extras until the real accelerator package (xcorescanner) is published;[sdk]and[xcli]are unaffected.
[2.5.0] - 2026-08-20¶
Added¶
- Optional extras (
[project.optional-dependencies]):pip install XCoreRuntime[sdk](full plugin-author SDK,xcdk) andpip install XCoreRuntime[xcli](xcorecli, thexclicommand).[cpp]/[all]were part of this release but immediately broken — see2.5.1.
[2.4.4] - 2026-08-20¶
First release actually published to PyPI as XCoreRuntime — pip install XCoreRuntime now works. 2.4.0–2.4.3 were cut while the release pipeline itself was still being fixed and never successfully reached PyPI (see Fixed below); no functional difference to document for those beyond what's already in 2.4.0.
Changed¶
- PyPI distribution renamed to
XCoreRuntime: the registered PyPI project isn'txcore—pyproject.toml'snamedidn't match, so the project-scopedPYPI_TOKENwas rejected with403 Invalid API Token. The import name is unaffected:import xcorestill works, onlypip install <name>changes. xcoresdk/xcoreCligit dependencies dropped: PyPI rejects any package whose metadata declares a direct VCS dependency (xcoresdk @ git+https://...). Removing them brokeimport xcoreitself (ModuleNotFoundError: No module named 'sdk'—xcore/kernel/security/section.pyandvalidation.pyimportedPluginDependencyfrom the externalsdkpackage unconditionally, not just as an SDK convenience). Fixed by vendoring the pre-extraction SDK source (xcore/sdk/plugin_base.py,decorators.py,routers.py,mixin/ipc.py,adapter/*.py) back locally: the kernel now depends on nothing external, andxcore.sdk's newer features (EventMixin,HookMixin,ObservabilityMixin,ScheduledMixin,cached/cron/interval/health_check,AutoMixin, Mongo/Redis repositories) are picked up automatically if thexcdkpackage happens to be installed ([sdk]extra), and simply absent otherwise — no fake no-op fallbacks.xcore/kernel/security/{section,validation}.py:PluginDependencynow imported from...sdk.plugin_base(local) instead of the externalsdkpackage.
Fixed¶
- Release pipeline couldn't actually release:
release.ymlonly triggered onpush: tags:, but the version-bump commit + tag pushed byrelease-manual.ymluse the defaultGITHUB_TOKEN— GitHub deliberately never cascades apushevent triggered byGITHUB_TOKENinto other workflow runs (anti-loop protection).v2.3.5(era) tags were pushed with no build/publish/release ever firing.release.ymlnow also acceptsworkflow_dispatchwith ataginput, andrelease-manual.ymlexplicitly callsgh workflow run release.yml -f tag=vX.Y.Zafter pushing the tag. pypa/gh-action-pypi-publishtoken wiring: the PyPI API token was passed viaenv: PYPI_TOKEN, which the action never reads (it only reads thepassword:input) — publish step silently no-op'd on auth. Fixed towith: password: ${{ secrets.PYPI_TOKEN }}..github/workflows/labeler.yml: contained the label-mapping config ("core": - changed-files: ...) instead of a workflow definition — GitHub tried to parse it as a workflow and failed on every push. Moved the mapping to.github/labeler.yml(wherepr.yml's existing🏷️ Auto Labeljob already expected it) and deleted the broken duplicate workflow file.docs.yml: missingpermissions:block meant the Netlify PR-preview comment step failed withResource not accessible by integration. Addedcontents: read/pull-requests: write.xcore/kernel/security/validation.pyisort ordering (introduced by the SDK-vendoring fix above).
New tooling¶
.github/workflows/release-manual.yml:workflow_dispatch-only release trigger — bumppyproject.toml(explicit version orpatch/minor/major/pre-release), commit, tag, push, and dispatchrelease.yml. Supportsdry_run.
[2.4.0] - 2026-08-20¶
Added¶
- Real OpenTelemetry SDK integration and distributed trace propagation (W3C
traceparent, HTTP + sandbox IPC) — completes the tracing work started in2.3.5. Seedoc/observability/observability.md. - Tiered cache backend follow-up work, and general V2 Industrialization roadmap close-out (PR #271).
[2.3.5] - 2026-08-10¶
Closes out the V2 Industrialization roadmap: the two remaining ⚠️ items (Full OpenTelemetry, Distributed Tracing) are now implemented, and Advanced Hot Cache gets a tiered backend. V2 is now maintained in patch-release mode through December while running in production — see ROADMAP_PROGRESS.md for the V3 timeline decision.
Added¶
- Real OpenTelemetry SDK integration:
Tracer/Span(xcore/kernel/observability/tracing.py) now back onto a realTracerProviderwhenobservability.tracing.backend: opentelemetry— console export (SimpleSpanProcessor, immediate) by default, OTLP/HTTP export (BatchSpanProcessor) whenendpointis set. Public API unchanged, fully backward compatible with the previous noop implementation. - Distributed trace propagation (W3C TraceContext): a single
trace_idnow survives across process boundaries.TraceContextMiddleware(new,xcore/kernel/observability/http_middleware.py) extracts the incomingtraceparentHTTP header before any span opens; the sandbox IPC channel (sandbox/ipc.py/sandbox/worker.py) injects/parsestraceparentacross the hop to a sandboxed subprocess. Newinject_trace_context()/extract_trace_context()helpers, andspan(..., context=...)to parent a span explicitly. Tracer.shutdown(): flushes and stops theTracerProvider, wired intoXcore.shutdown(). Without it, spans still sitting in theBatchSpanProcessorbuffer at process exit were silently dropped.- Tiered cache backend (
backend: tieredinservices.cache):TieredCacheBackend(xcore/services/cache/backends/tiered.py) — memory L1 in front of Redis L2, read-through with backfill, write-through. No cross-node invalidation push (bounded byttl) — documented trade-off, seedoc/services/cache.md. - New dependencies:
opentelemetry-api,opentelemetry-sdk,opentelemetry-exporter-otlp-proto-http.
Changed¶
ServerConfig.hostdefault:0.0.0.0→127.0.0.1. Deployments that need to bind all interfaces (containers, LB in front) now do so explicitly viaapp.server.hostinintegration.yamlorXCORE__APP__SERVER__HOST.
Fixed¶
- Silent exception swallowing: 3 bare
except: passblocks now log at debug level instead of discarding the error —sandbox/ipc.py(IPCChannel.close),sandbox/worker.py(plugin.on_unload),tenancy/services.py(_set_tenant_schemacleanup). sandbox/ipc.py: replacedlogging.getLogger()with the project'sget_logger().
Documentation¶
doc/observability/observability.md: documented the real tracing backend, distributed propagation (HTTP + IPC), exporter selection table, and a new gotcha —self.tracer/self.metrics/self.healthareNoneinside ephemeral/sandboxed plugins (noPluginContextinjected there); automatic supervisor-level tracing still covers those calls without any plugin code.doc/services/cache.md: documented thetieredbackend and its cross-node staleness trade-off.
[2.3.4] - 2026-08-04¶
Added¶
- Ephemeral documentation: New
doc/plugins/ephemeral-plugins.mdguide covering what Ephemeral mode is, when to use it, the warm pool lifecycle, configuration (per-plugin + global), plugin authoring, monitoring, and tuning advice. Registered inmkdocs.yml. Updatedexecution-modes.md(3-mode comparison table + Ephemeral section),plugin-anatomy.md(manifest reference), andxcore-config.md(plugins.ephemeralsection). - CI/CD Netlify:
docs.ymlnow deploys MkDocs to Netlify instead of GitHub Pages. Production deploy on pushmain/ tags / manual, deploy preview on PR. RequiresNETLIFY_AUTH_TOKEN+NETLIFY_SITE_IDsecrets. Build is now strict (mkdocs build --strict).
Fixed¶
- Doc links: Fixed 6 broken relative links (
quickstart.md,advanced/multi-tenancy.md,sdk/examples/demo-plugin.md) that made the strict MkDocs build fail.
Fixed¶
- Ephemeral per-plugin config:
EphemeralActivatornow reads theephemeral:block frommanifest.extrawhen the manifest has noephemeralattribute (the SDK'sPluginManifestdoes not parse it as a field). Per-plugin config inplugin.yamlnow works as documented, with global fallback preserved. - warm_pool.py: Replaced
logging.getLogger()withget_logger()fromxcore.kernel.observabilityto comply with project logging conventions. Converted all 11 logger calls from%sstdlib style to structured kwargs logging.
Documentation¶
- ROADMAP_PROGRESS.md: Updated V2 progress from 70% to 85% — Ephemeral mode and Warm Pool were already implemented but marked as not done. Corrected status for Hot Cache (now ⚠️). Added "Points d'Attention" section noting duplicate
kernel/middlewares/directory.
[2.3.3] - 2026-06-08¶
Added¶
- Mode Éphémère (Ephemeral Mode): Introduced a new execution mode for plugins that optimizes RAM usage on the host machine during hot reloads. This enables fully stateless plugins and reduces resource footprints.
- Plugin Warm Pool: Implemented a warm pool mechanism to accelerate plugin activation and lifecycle transitions.
Changed¶
- Event Bus Performance: Optimized the
EventBusfor single-handler dispatch, reducing overhead for simple event flows. - Hot Reloading: Optimized the hot reloading process to be more memory-efficient by leveraging ephemeral handlers.
- Runtime Supervisor: Updated the supervisor to manage ephemeral plugin instances and warm pools efficiently.
- Internalization: Updated RBAC error messages to English for better consistency.
Fixed¶
- Resource Management: Addressed potential memory leaks during repeated hot reloads by implementing strict ephemeral lifecycle management.
[2.3.2] - 2026-06-05¶
Added¶
- Python 3.12 Support: Upgraded codebase and CI pipelines to support Python 3.12.
- C++ Security Scanner: Integrated high-performance
scanner_coreC++ extension for deeper security analysis. - Event Bus Singleton: Implemented a global
EventBussingleton available at configuration time, injected directly into middleware parameters. - Enhanced CI/CD: Added comprehensive test coverage reporting and PR size validation to GitHub Actions.
- CORS Configuration: Centralized CORS configuration in
integration.yaml.
Changed¶
- Modularization: Decoupled core runtime from SDK and CLI.
xcoreCliis now an external dependency (git+https://github.com/xcore-team/xcoreCli.git).xcoresdkis now an external dependency (git+https://github.com/xcore-team/xcoreSDK.git).
- Internal Refactoring:
- Complete overhaul of the middleware pipeline for better performance and extensibility.
- Improved database container connection handling with explicit session verification.
- Documentation: Migrated documentation system to MkDocs for better maintainability and rich search capabilities.
Fixed¶
- Plugin Sandbox: Fixed a bug where environment variables were not correctly injected into the plugin context if missing from the manifest.
- Database Reliability: Resolved an issue where database connections could fail due to unverified sessions; added automatic verification before usage.
- Plugin CLI: Fixed various bugs in plugin-related CLI commands.
[2.3.1] - 2026-05-29¶
Fixed¶
- database/session: Connections were failing silently because the session was not verified before use. Added an explicit check on the session state (
is_active) before each operation, with automatic reconnection if the session is expired or closed. - database/async_sql:
pool_pre_ping=Trueraisedping() missing 1 required positional argument: 'reconnect'when using theaiomysqldriver. Pre-ping is now disabled automatically foraiomysqlandcymysql, and is compensated by a pessimistic event listener (engine_connect) andpool_recycle. - database/async_sql: Improved handling of dead connections —
OperationalErrorandDisconnectionErrorerrors during rollback are now caught and logged instead of crashing the worker. - database/_utils: The
read_timeoutandwrite_timeoutparameters are exclusive topymysql.sanitize_connect_args()now filters them out foraiomysqlwith an explicit warning, avoiding a silent connection error. - database/migrations:
MigrationRunner._is_async()did not recognize the+aiomysqland+asyncmysuffixes, forcing the synchronous path on async connections. Both drivers are now included inasync_markers. - database/container: The
DatabaseConfigconfiguration did not expose certain production parameters (pool_timeout,pool_reset_on_return,connect_args,isolation_level,execution_options). These fields are now read fromintegration.yamland passed to the adapters.
Improved¶
- CI/CD: Updated
ci.ymlworkflow — refined the coverage step, reviewed PR labels, and added thepr.ymlworkflow to validate PR titles (conventional commits) and PR sizes. - CI/CD:
security.ymlworkflow — restricted Bandit scans to existing folders (xcore/,tests/) to eliminate false positives onextensions/andplugins/. - Tests: Fixed
test_tenancy.pytest — aligned assertion with actualContextVarbehavior after reset. - Documentation: Complete overhaul of the CLI section (
doc/cli/) with detailed guides for installation, configuration, and theworker,plugin,sandbox,manager, andmigrationcommands. Added the SDK API reference (doc/sdk/api/). - Observability: Enriched
XcoreLoggerwith structural support for contextual fields; extendedMetricsCollectorwith documentedmemoryandprometheusbackends.
[2.3.0] - 2026-05-14¶
Added¶
- Multi-tenancy Native (Axe 1):
TenantMiddleware: Extractstenant_idfrom HTTP header (X-Tenant-ID) or subdomain; injectsrequest.state.tenant_id.TenantAwareCache: Wraps cache and automatically prefixes all keys with{tenant_id}:.TenantAwareDB: Wraps SQL adapters and executesSET search_path TO {tenant_id}, public(PostgreSQL) before each query.TenantAwareScheduler: Prefixes APSchedulerjob_idwith{tenant_id}:.wrap_services_for_tenant(): Replaces services in plugin context at each call; zero code changes for existing plugins.
- IPC Authorization (allowed_callers):
IPCAuthMiddleware: First middleware in the pipeline; checksallowed_callersdeclared inplugin.yaml.- Deny-by-default: IPC calls are denied if the list is empty or missing. Direct HTTP calls (caller=None) still pass.
PluginLoader.get_manifest(name): Added method to retrieve manifest from middleware.
- @schema Decorator (Axe 3):
- Versioned decorator with built-in validation (Pydantic).
SchemaRegistry: Singleton storing all schemas declared via@schema.BreakingChangeDetector: Detects breaking changes between two registry versions.- CLI:
xcore plugin validate --check-breaking schemas_v1.json.
- Configuration:
tenancy:section inintegration.yamlwith 8 flags:enabled,header,subdomain,default_tenant,isolate_cache,isolate_db,isolate_scheduler,enforce_ipc.TenancyConfigdataclass inconfigurations/sections.py.allowed_callers: list[str]added toPluginManifest.
- Testing:
- 58 new tests:
tests/unit/kernel/test_tenancy.py(41) andtests/integration/test_tenancy_integration.py(17).
- 58 new tests:
- Documentation:
doc/guides/tenancy.md: Complete multi-tenant guide.doc/guides/plugin-manifest.md:plugin.yamlreference.doc/reference/configuration.md: Documentedtenancy:section.doc/reference/sdk.md: Documented@schema.doc/guides/security.md: IPC andallowed_callerssection.doc/architecture/decisions.md: Decisions 7 (location), 8 (IPC deny-by-default), 9 (@schema source of truth).
[2.2.1] - 2026-05-24¶
Fixed¶
- database/async_sql:
pool_pre_ping=Truecausedping() missing 1 required positional argument: 'reconnect'with aiomysql. Pre-ping is now disabled automatically for aiomysql/cymysql and compensated by a pessimistic event listener +pool_recycle. - database/migrations:
MigrationRunner._is_async()did not recognize+aiomysqland+asyncmydrivers, forcing synchronous path on async connections. - database/_utils:
read_timeoutandwrite_timeoutare pymysql-only parameters.sanitize_connect_argsnow filters them for aiomysql with an explicit warning.
[2.2.0] - 2026-05-24¶
Added¶
- DatabaseConfig: New configurable pool parameters in
xcore.yaml:pool_pre_ping,pool_recycle,pool_timeout,pool_reset_on_return,connect_args,isolation_level,execution_options. - database/adapters/_utils.py: New module for driver detection and connection argument sanitization.
Fixed¶
- database/async_sql: Fixed stale connections (MySQL/MariaDB) after
wait_timeout. - database/async_sql: Added missing
@asynccontextmanageronsession(). - database/async_sql + sql: Added missing
disconnect(). - database/async_sql + sql: Improved error handling during rollback on dead connections.
[2.2.0] - 2026-05-14¶
Changed¶
- Security: Removed
python-joseandpython-ecdsato eliminate vulnerability to Minerva timing attacks (CVE-2024-23342). - Cleanup: Removed 7 unused dependencies (
pillow,watchdog,user-agents,aiocache,toml,mysql-connector-python). - Optimization: Moved
psutilto dev dependencies andmarkdownto docs dependencies.
[2.1.3] - 2026-05-13¶
Added¶
- XWorker (Native Celery): Full Celery integration in
ServiceContainer. - CLI xcore worker: Command to manage FastAPI and Celery processes (
start,stop,status,logs, etc.). - Extended Configuration: FastAPI constructor parameters and uvicorn parameters configurable via YAML.
- Declarative Middleware System: Automatic loading from
integration.yaml.
[2.1.2] - 2026-04-29¶
Fixed¶
- 13 critical test failures resolved (kernel, permissions, sandbox).
- AST Scanner: detection of bypasses via import aliases.
Improved¶
- Performance:
- LRU Cache on
PermissionEngine: +34% throughput. - Native
mset/mgeton Redis: up to 77x faster on batch operations. - Pre-compiled regex in
Policy.matches(): short-circuit in 0.4 µs.
- LRU Cache on
- Quality:
pytest-benchmarkintegration.- Pre-commit hooks for black, isort, and flake8.
pyproject.tomlmigrated to PEP 621.
[2.0.0] - 2026-04-15¶
Added¶
- Plugin-First Architecture: Modular kernel, separation of Kernel / Services / Plugins.
- Advanced Sandboxing: OS subprocess isolation, JSON-RPC 2.0 communication.
- ServiceContainer: Dependency injection for DB (SQLAlchemy 2.0), Cache (Redis/Memory), Scheduler (APScheduler).
- MiddlewarePipeline: Pre-compiled pipeline (Tracing → RateLimit → Permissions → Retry).
- SDK:
@action,@router,@validate_payload,AutoDispatchMixin,RoutedPlugin. - RBAC: Pluggable
AuthBackend+ declarativeRBACChecker. - StateMachine: FSM per plugin with validated transitions.
- PluginRegistry: Metadata, dependencies, semver versioning.
[1.x] - Legacy¶
Added¶
- Initial stable release based on FastAPI.
- Monolithic plugin system without isolation.
- Limited support for asynchronous services.