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.6.1] - 2023-03-30
Added
- Orchid.Repo: Added a helper funtion
Orchid.Repo.dispatch_store/3.
Changed
- Type Annotation: Move
Orchid.Param.ref_payload/0's second item into{module, ref}.
[0.6.0] - 2026-03-29
Breaking Changes
- Orchid.Repo: Refactored storage behaviour. Callbacks now accept a
store_refas the first argument to support multiple store instances. - Operon.Request: Fixed typo in struct field
:inital_params, renamed to:initial_params. Code manually constructing this struct needs to be updated.
Added
- Orchid.Repo: Added optional extension behaviours:
Deletable,ContentAddressable,GC,Transferable.
Fixed
- Correct key name in
Orchid.Operon.Requestfrom:inital_paramstoinitial_params.
[0.5.8] - 2026-03-27
Fixed
- Monokey with List: Now monokey like
["simple_key"]may not cause{:error, :stuck}.
[0.5.7] - 2026-03-26
Added
- Binary Step IO Key: Now Orchid can resolve binary keys!
Documentation
- Release Data: Correct release date from 2025 into 2026.
[0.5.6] - 2026-02-12
Changed
- Core Hook: Enhanced
align_output_names/2logic inOrchid.Runner.Hooks.Core. The runner now automatically renames the returnedParamstruct to match the output key defined in the Recipe. This improvement ensures smoother data flow, especially for Implicit Mapping in Nested Steps, allowing inner steps to be reused more flexibly without manual renaming.
Documentation
- Refactor: Major update to
README.md.- Added detailed sections and examples for Nested Steps (covering both Implicit and Explicit mapping).
- Clarified usage of Executors (Serial vs. Async).
- Expanded explanations for Layered Hooks and Pipeline Middleware (Operons).
- Fixes: Corrected multiple typos (e.g.,
Definate->Define,mannual->manual) throughout the documentation and code comments.
[0.5.5] - 2026-02-11
Added
- Telemetry Hook: Add
Orchid.Runner.Hooks.Telemetry.error_handler/4to facilitate debugging.
Fixed
- Async Executor: Fixed an issue where cleaning up other steps failed when one step in an Async Executor threw an error.
[0.5.4] - 2026-02-02
Added
- Support for Steps returning a Map
%{key => param}directly. Orchid.Recipe: Support{:ok, opts}return value invalidate_options/1callback (friendly to NimbleOptions).
Fixed
- Single Step Runner: Fixed a bug where returning multiple params in a Step list could lead to incorrect output mapping.
- Single Step Runner: Now raises
ArgumentErrorwhen a Step returns multiple params but none match the requested output key name (preventing ambiguity).
[0.5.3] - 2026-01-23
This release improves the developer experience with syntactic sugar for workflow execution, reorganizes documentation for better readability, and significantly boosts test coverage.
Added
- Execution Sugar:
Orchid.run/3now accepts a raw list of steps ([Step.t()]). It automatically wraps them into aRecipeinternally, reducing boilerplate for simple scripts or tests. - Single Param Input:
Orchid.Scheduler.build/3now accepts a singleOrchid.Paramstruct asinitial_params, automatically wrapping it into the required map structure. - CI/CD: Integrated Codecov for test coverage reporting.
Documentation
- Module Grouping: Configured
groups_for_modulesinmix.exs. HexDocs are now organized into logical categories (Dataflow Declaration, Orchestration, Executors, etc.) instead of a flat list. - Moduledocs: Added missing documentation for
Orchid.Executor.Async,Orchid.Param, andOrchid.Operon.Execute. - Badges: Added Hex.pm, License, and Codecov badges to
README.md.
Changed
- Internal Safety: In
Orchid.Recipe, strict key fetching (Keyword.fetch!) is now used when updating inner recipes forNestedStep, ensuring configuration errors are caught early.
[0.5.2] - 2026-01-17
Robustness & Cleanup. This release focuses on standardizing return types, fixing edge cases in asynchronous execution, and cleaning up internal identifiers to be less dependent on list indices.
Fixed
- Async Executor: Fixed an issue where
Orchid.Executor.Asyncwould discard the context payload when a step returned{:special, context}. It now correctly wraps the payload in the error reason{:core_executor_not_support_special, context}. - Pipeline Consistency:
Orchid.Pipeline.run/2now consistently returns anOrchid.Operon.Responsestruct (wrapping the error) even when the middleware stack is empty or hits the sink, preventing format mismatch errors.
Added
- Custom Core Hook: Added
:core_hooksupport inOrchid.WorkflowCtxconfig. This allows replacingOrchid.Runner.Hooks.Corewith a custom module, which is useful for specialized execution strategies or testing mocks. - Step Comparison: Added
Orchid.Step.ID.same?/2to check if two steps share the same Input/Output interface.
Changed
- Recipe Validation:
Orchid.Recipe.validate_steps/2no longer includes the step index (idx) in{:invalid_step_option, ...}errors. This aligns with the roadmap goal of moving away from order-based identification. - Internal ID Logic: Refactored
Orchid.Step.ID.finger_print/2. Theas_num?option is replaced byheadless?. It no longer returns an integer hash but simpler tuples ({in, out}or{impl, in, out}), making it more predictable for debugging. - Context API: Renamed Orchid.WorkflowCtx's
add_step/2toadd_depth/2to better reflect its purpose of tracking call stack depth in nested workflows.
[0.5.1] - 2026-01-04
Documentation & Refactoring. This release polishes the internal architecture, making the
WorkflowCtxthe single source of truth for configuration, and significantly improves internal documentation.
Changed
- Configuration Source of Truth:
Orchid.run/3now initializesWorkflowCtxearlier. Consequently,Orchid.Operon.Requestno longer carriesexecutor_and_optsdirectly; it is now dynamically resolved fromWorkflowCtx. This allows Operons to swap Executors dynamically (e.g., switching to a GPU-optimized executor based on input). - Scheduler Internals:
- Reordered fields in
Orchid.Scheduler.Contextfor better memory alignment (maybe). - Docs: Added detailed explanation on why Orchid uses a mix of
List(for deterministic order) andMapSet(for O(1) lookups) in the Scheduler context.
- Reordered fields in
- Code Generation:
Orchid.Runnernow usesapply/3to invoke step implementations. This reduces compile-time dependency warnings when creating dynamic workflows.
Fixed
- Execution History: Fixed an inconsistency in
Scheduler.merge_result/3where execution history tracking was slightly malformed (removed the index from history tuples). - Typing: Relaxed type specs for
telemetry_metaandassignsinRunnerto genericmap()to accommodate more flexible plugin data.
[0.5.0] - 2026-01-02
Happy New Year!
This is the first release of the year, bringing a new plugin architecture to Orchid. May your workflows bloom beautifully this year!
Breaking Changes
- Nested Step Error Handling:
Orchid.Step.NestedStepnow returns{:error, {:nested_step_execution_failed, inner_context}}instead of just the reason. This allows parent workflows to access the failed child's context for potential recovery or debugging. - Hook Protocol: The
Orchid.Runner.Hookbehavior now supports a third return type:{:special, any()}. Custom hooks implementing stricter type checks may need updates. - Default Executors: The built-in
SerialandAsyncexecutors will now explicitly error with{:core_executor_not_support_special, ...}if a step returns a{:special, ...}tuple. This signals that a specialized executor (e.g., from a Session plugin) is required to handle such states.
Added
- Plugin Support (Special Return): Introduced
{:special, payload}as a first-class return type inOrchid.Runner. This mechanism is designed for plugins (likeOrchid.Session) to implement flow control logic like Pause, Interrupt, or Yield without abusing the Error channel. - Telemetry: Added a new event
[:orchid, :step, :special]to track steps that exit with the special status. - Error Kinds: Added
:logic_or_exceptiontoOrchid.Errorkinds to better describe failures caught in async tasks.
Changed
- Async Executor: Improved robustness by explicitly flushing the monitor message (
:DOWN) when a task completes successfully, preventing potential race conditions or mailbox pollution. - Dependencies: Updated
lib/orchid/step/id.exto depend onOrchid.Stepalias correctly. - Documentation: Updated README roadmap and translated more comments in
Asyncexecutor to English. - Copyright: Updated License year to 2026.
Internal
- Refactoring:
Orchid.WorkflowCtxnow uses pipeline operators for cleaner config/baggage merging logic.
[0.4.1] - 2025-12-27
Refinements (Improvements to 0.4.0)
- Context Propagation: Introduced "Baggage" to
Orchid.WorkflowCtx. You can now pass global metadata viaOrchid.run(..., baggage: map)which propagates vertically into nested steps. - Hooks Resolution: Global hooks are now correctly resolved from the
WorkflowCtxconfiguration instead of the recipe options. This aligns the behavior with the new Context architecture introduced in 0.4.0. - Error Reporting: The cyclic dependency error now returns useful
Stepstructs ({:cyclic, steps}) instead of opaque indices.
Fixed
- Validation: Fixed a variable scope issue in
Recipe.validate_stepsthat could cause a crash during cycle detection. - Key Normalization: Moved IO key normalization logic to
Orchid.Step.IDto fix potential inconsistencies between static checks and runtime execution. - Telemetry: Fixed the injection timing of
__reporter_ctx__to ensuring metadata is available during the entire step lifecycle.
Docs
- Internals: Added comprehensive documentation for
Orchid.Error,Orchid.Scheduler.Context, andOrchid.WorkflowCtx. - Tests: Translated integration test comments to English.
[0.4.0] - 2025-12-26
Breaking Changes
- Context & Options:
Orchid.run/3now strictly filters input options. Arbitrary keys are no longer implicitly merged into step options. User-defined metadata/context must now be passed via the new:baggageoption. - Error Handling: Execution failures are now returned as
{:error, %Orchid.Error{}}. TheOrchid.Errorstruct (an Exception) contains the failure reason, the step fingerprint, the failure kind (:logic,:exception,:exit), and the execution context (enabling partial result recovery). - Telemetry: Renamed the event
[:orchid, :step, :stop]to[:orchid, :step, :done]to distinct completion from termination. - Step DSL: The
nested?/0callback has been replaced by the module attribute@orchid_step_nested booleanwhen usingOrchid.Step. - Plugin: Removed
Orchid.Pluginmodule as it was unused and superseded by the Operon/Hook architecture.
Added
- Workflow Context: Introduced
Orchid.WorkflowCtxto explicitly manage execution scope, nested paths, configuration, and baggage throughout the pipeline. - API: Added
Orchid.run_with_ctx/3to support executing recipes with a pre-initialized context (e.g., for sub-workflows or resuming). - Identification: Introduced
Orchid.Step.IDto generate deterministic fingerprints/IDs for steps. - Helpers: Added
Orchid.Step.report/3to standardize progress reporting via Telemetry.
Changed
- Executor: Executors (
AsyncandSerial) now capture the runtime context upon failure and wrap it inOrchid.Error, preventing data loss during crashes. - Internals: Refactored
Orchid.Runnerto propagateWorkflowCtxinstead of loose keyword lists.
[0.3.5] - 2025-12-23
Changed
- Executor: Refined the return signature of
Orchid.Executor.execute_next_step/1. It now returns{:cont, context}for successful step execution, providing a clearer distinction between running, stuck, and done states. - API Visibility: Changed Orchid.inject_opts_into_recipe/2 from public (
def) to private (defp) to reduce the public API surface area. - Structs: initialized default values for
Orchid.Operon.Request.assignsnow defaults to%{}(was nil) andoperon_optionsto[]. - Packaging: Included
CHANGELOG.mdin the Hex package definition and documentation extras inmix.exs.
Fixed
- Types: Added missing type specifications for
Orchid.Pipeline.run/2and corrected the spec forOrchid.Recipe.assign_options/3.
Documentation
- Roadmap: Updated
README.mdto reflect plans forOrchidInstrumentsandOrchidPersistence.
[0.3.4] - 2025-12-22
Added
- Executor: Added
Orchid.Executor.execute_next_step/1. This helper encapsulates logic for fetching the next ready step and detecting "stuck" or "done" states, simplifying custom Executor implementation and debugging. - Recipe: Enhanced
Orchid.Recipe.assign_options/3. It now accepts a transformation function(Step.t() -> Step.t())as the third argument, allowing dynamic modification of step configurations. - Runner: Updated
Orchid.Runner.run/4. Added an optionalinitial_assignsargument to inject context assigns when running individual steps.
Changed
- Executor.Serial: Refactored the internal loop to utilize the new
execute_next_step/1helper. - Scheduler: Updated the internal structure of
Context.history. It now records{Step.t(), step_index, MapSet<ProducedKeys>}to track keys produced by each step more accurately. - Mix: Configured
elixirc_pathsinmix.exs. Files intest/supportare now automatically compiled only in the:testenvironment, removing the need for manual requires intest_helper.exs.
[0.3.3] - 2025-12-18
Fixed
- Scheduler: Fixed a potential crash in executor caused by invoking a scheduler function signature,
mark_running/2. - Dialyzer: Resolved opaque type warnings related to
Scheduler.build/2by adding explicit ignore rules.
Changed
- Error Handling: Renamed the error tag in
NestedStepfrom:nested_execution_failedto:nested_step_execution_failedfor better clarity. - Internal API: Renamed
step_default_optstostep_optswithinOrchid.Runner.Contextto better reflect that these are the final merged options. - Refactoring: Consolidated
Orchid.Scheduler.Contextdefinition back intolib/orchid/scheduler.exto improve module cohesion and reduce file fragmentation. - Custome Executor: Changed
mark_running/2intomark_running_steps/3to allow pushing running steps when retry. - Code Style: Unified codebase to use single-line function definitions (
def ..., do: ...) for consistency.
Documentation
- Internationalization: Enhanced
README.mdand translated core module docstrings (Executor, Async, Serial) from Chinese to English. - Architecture: Updated architecture diagrams in
README.mdto reflect the current data flow more accurately.
[0.3.2] - 2025-12-15
Added
- Nested Recipes: Introduced
Orchid.Step.NestedStepto treat entire recipes as atomic steps. - Parameter Mapping: Added
input_mapandoutput_mapsupport inNestedStepto rename parameters across boundaries. - Global Configuration: Added
global_hooks_stacksupport inOrchid.run/3options. - Plugin Infrastructure: Laid the groundwork for plugin integration via standard option injection.
Changed
- Option Inheritance: Improved the option merging strategy (
Orchid.inject_opts_into_recipe).- Hooks are now stacked (Parent ++ Child).
- Executors and other options now follow a Base + Specific inheritance rule (Child overrides Parent defaults).
[0.3.1] - 2025-12-12
Added
:executor_and_optsoptions inOrchid.run/3