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.2.7] - 2026-06-26
Added
Injector strict_mode support:
OrchidSymbiont.Hooks.Injectornow reads:strict_modefrom the workflow baggage. Whenstrict_mode: true, the resolver will not fall back to the global catalog, ensuring strict multi-tenant isolation at the hook level.Orchid.run(recipe, params, baggage: %{scope_id: "tenant-1", strict_mode: true} )
[0.2.5] & [0.2.6] - 2026-04-24
Enhenced
- Documents: Updated documents.
[0.2.4] - 2026-03-26
Enhenced
- Symbiont ID Type: Now Symbiont's ID also support binary. If the name is dynamically generated in your application, it is recommended to use binary instead of atom to avoid memory leaks.
Changed
- Scopa Name Declaration: Now we use
:scope_idinstead:session_idto seperate domains.
Migration Guide (0.2.3 -> 0.2.4)
# Before
{OrchidSymbiont.Runtime, session_id: "my_session"}
OrchidSymbiont.register("my_session", :worker, {MyWorker, []})
Orchid.WorkflowCtx.put_baggage(:session_id, "my_session")
# After
{OrchidSymbiont.Runtime, scope_id: "my_session"}
OrchidSymbiont.register("my_session", :worker, {MyWorker, []})
Orchid.WorkflowCtx.put_baggage(:scope_id, "my_session")[0.2.3] - 2026-03-25
Fix
- Fixed a bug where adding options other than session_id would prevent the creation of additional processes.
[0.2.2] - 2026-03-25
Added
Strict Mode: A new
strict_mode: trueoption has been added toOrchidSymbiont.Resolver.resolve/3. When enabled, if the corresponding service blueprint is not found in the current Session's Catalog, an error will be thrown directly, and there will be no fallback to the global Catalog, thus ensuring stricter multi-tenant security isolation.State Backup and Restore: The
dump/1andrestore/2methods have been added toOrchidSymbiont.Catalogfor easy exporting and restoring of the current Catalog's state.
Changed
[Architecture Refactoring] True Session Isolation: The Session's supervised tree model has been refactored. Now, when you start a Session using
OrchidSymbiont.Runtime, it launches a dedicatedOrchidSymbiont.Catalogprocess for that Session. Registration states between different Sessions are now truly physically isolated, instead of being distinguished by tuples{{session_id, name}, val}in the global state.[Performance Optimization] Catalog Underlying Replacement: The underlying implementation of
OrchidSymbiont.Cataloghas been simplified fromGenServertoAgent, making it more lightweight and better suited to its pure state storage nature.**Startup Layer Optimization: The application startup process has been streamlined. The bloated list of child processes in OrchidSymbiont.Application has been removed. The startup logic for global services (
Registry, globalCatalog,DynamicSupervisor,Preloader) is now consolidated and wrapped within the:globalinitialization strategy ofOrchidSymbiont.Runtime.
Removed
- Removed
clear/0andclear_session/1inOrchidSymbiont.Catalogmodule. Since Sessions now manage their lifecycle through an independent supervision tree, their internal Catalog processes are automatically destroyed and reclaimed when the correspondingRuntimeterminates, eliminating the need for manual cleanup.
[0.2.1] - 2026-03-24
BREAKING CHANGE
- Move legacy module name
Orchid.SymbiontintoOrchidSymbiont.
Fixed
- Atom Exhaustion Vulnerability: Resolved a critical memory leak issue where dynamic session IDs (atoms) were never garbage collected, potentially causing VM crashes in long-running multi-tenant applications.
Changed
- Session ID Type: Changed
session_idfromatom()tobinary()(String). Example::project_a→"project_a". - Unified Registry Architecture: Replaced per-session Registry/Catalog/Preloader processes with a single global Registry using compound keys
{session_id, name}. This significantly reduces process overhead for high-session-count scenarios. - Runtime Implementation:
Orchid.Symbiont.Runtimenow usesDynamicSupervisordirectly instead of wrapping it in aSupervisor. - Simplified Naming Module: Refactored
Orchid.Symbiont.Namingwith cleaner API:get_registry/0- Returns the unified registrysession_supervisor/1- Returns via tuple for session supervisorworker/2- Returns via tuple for session workers
Removed
- Per-session Registry processes (now uses global with compound keys)
- Per-session Catalog processes (now uses single global instance)
- Per-session Preloader processes (now uses global
Orchid.Symbiont.Preloader) Naming.registry/1,Naming.catalog/1,Naming.preloader/1functions
Migration Guide (0.2.0 → 0.2.1)
# Before (0.2.0)
{Orchid.Symbiont.Runtime, session_id: :my_session}
Orchid.Symbiont.register(:my_session, :worker, {MyWorker, []})
Orchid.WorkflowCtx.put_baggage(:session_id, :my_session)
# After (0.2.1)
{OrchidSymbiont.Runtime, session_id: "my_session"}
OrchidSymbiont.register("my_session", :worker, {MyWorker, []})
Orchid.WorkflowCtx.put_baggage(:session_id, "my_session")[0.2.0] - 2026-01-04
Added
- Session Isolation (Multi-Tenancy): Introduced the ability to run completely isolated sandboxes of Symbiont processes using
session_id. Perfect for concurrent workflows or multi-tenant SaaS architectures without PID conflicts. - Dynamic Supervision Trees:
Orchid.Symbiont.Runtimecan now be started multiple times under different namespaces by passing[session_id: :your_session_name]. Each session gets its own isolatedRegistry,DynamicSupervisor,Catalog, andPreloader. - Smart Catalog Fallback: Added a hierarchical lookup mechanism in
Orchid.Symbiont.Catalog. If a blueprint is not found in a session-specific catalog, it will automatically fall back to the global catalog. (Write blueprints once globally, run instances locally!) - New Naming Module: Added
Orchid.Symbiont.Namingto handle dynamic process registration routing transparently.
Changed
- Injector Hook Upgraded:
Orchid.Symbiont.Hooks.Injectornow automatically extracts:session_idfrom theOrchid.WorkflowCtxbaggage and routes the process resolution to the corresponding session's registry. - API Enhancements:
Orchid.Symbiont.registerandOrchid.Symbiont.Resolver.resolvenow accept an optionalsession_idparameter. (Fully backward compatible with global singleton usage). - Dependencies Bump: Updated
orchidto0.5.6,telemetryto1.4.1, andex_docto0.40.1.
[0.1.4] - 2026-01-03
Added
- Global Mapping Support:
Orchid.Symbiont.Hooks.Injectornow supports resolving symbiont aliases from theOrchid.WorkflowCtxbaggage. - Hierarchical Resolution: Symbiont mappings are now merged from two levels:
- Global: Set via
Orchid.WorkflowCtx.put_baggage(ctx, :symbiont_mapper, [...]). - Local: Set via
step_opts. Note: Local step-specific mappings will override global mappings if both define the same logical name.
- Global: Set via
Fixed
- Internal
get_headerslogic in the Injector hook to properly handle the workflow context.
[0.1.3] - 2026-01-02
Changed
- Breaking: Renamed
Orchid.Symbiont.Step.get_required/0with old name calledget_step_required_mapper/0for shorter and cleaner API usage. Orchid.Symbiont.call/3now usesapply/3for dynamic module invocation.
Added
Orchid.Symbiont.preload/1now accepts a single symbiont name in addition to a list of names.
[0.1.2] - 2026-01-02
Dependencies
- update orchid's version to
0.5
[0.1.1] - 2025-12-27
Dependencies
- use a looser version constraint for better compatibility with future patch releases
[0.1.0] - 2025-12-26
Added
- Initial Release: Launched
OrchidSymbiontas the official process management extension for the Orchid workflow engine. - Lazy Loading: Introduced a mechanism to start GenServers (Symbionts) only when requested by a workflow step, optimizing resource usage for heavy tasks (e.g., ML models, DB connections).
- Dependency Injection: Added
Orchid.Symbiont.Hooks.Injectorto automatically resolve and inject running process references (PIDs) into Steps implementing theOrchid.Symbiont.Stepbehavior. - Lifecycle Management (TTL):
- Implemented an
Idle Shutdownmechanism using a transparent Wrapper/Proxy pattern. - Workers configured with a
:ttloption will automatically terminate after a period of inactivity to free up resources. - The Wrapper ensures request forwarding is transparent and handles timeouts (
:infinityinternally) correctly to support long-running tasks.
- Implemented an
- Registry & Catalog:
Orchid.Symbiont.register/2: API to define blueprints for services, supporting both standard startup and TTL-enabled modes.- Built-in
Registryfor name resolution and idempotency check (preventing duplicate startups).
- Integration:
- Provides
Orchid.Symbiont.Stepbehavior requiringrequired/0(dependencies) andrun_with_model/3(execution logic). - Added helper
Orchid.Symbiont.call/3for ergonomic synchronous communication with Symbionts.
- Provides
Dependencies
- Requires Orchid ~> 0.4.0 (utilizes the new Context and Hook architecture).