Skip to content

Releases: humansoftware/synaflow

v0.17.0

18 Jun 13:43

Choose a tag to compare

v0.17.0 (2026-06-18)

Ci

  • ci: separate lint, test, and coverage into parallel jobs

Split the single test job in ci.yml (which ran lint + install + tests
sequentially) into three independent parallel jobs:

  • lint — only needs ruff via uvx, skips package installation (faster)
  • test — builds/installs the wheel and runs pytest
  • total-coverage — runs pytest --cov, posts Total Coverage and Patch
    Coverage checks to GitHub (gated on pull_request events)

The Total Coverage check now enforces an 80% threshold (previously
always success) and includes a per-file coverage report table in its
summary, so the full report is visible directly on the PR checks
without digging into job logs. Patch Coverage keeps its 80% threshold.

Consolidated the standalone test-coverage.yml workflow into the
total-coverage job and deleted the old file. Pre-commit behavior is
unchanged locally — everything still runs together via the pytest hook. (2441ba3)

Feature

  • feat: validate terminal steps with unmaterialized stream output at build time

A terminal step (no consumers) whose output is Iterator/Generator or
AsyncIterator/AsyncGenerator and whose output is not materialized
(needs_materialize is False) produces a stream that nobody drains. At
runtime this causes either a deadlock (bounded handoff pump blocks
forever) or silent data loss (the pump discards items to deliver the
EOF marker).

Add validate_no_unmaterialized_terminal_streams in dag_steps.py, called
from build_dag after materialized_deps are computed. Uses the existing
needs_materialize flag -- no new materialization logic. Steps exported
via sub-pipeline exports are skipped because they will have consumers
in the parent. Also propagate force_materialize through sub-pipeline
expansion (was missing).

Fix existing tests with latent terminal Iterator-returning steps:

  • corpus complex_parallel_mixed: step3 -> list[int]
  • observer runtime: lazy_consumer/passthrough -> None (drain input)
  • dag_materializer: add force_materialize=True (test targets UNRUNNABLE)
  • dag_expansion: add force_materialize=True (test targets DAG structure)
  • materializers_ergonomics: add force_materialize=True on sub-pipeline gen
  • async_runner_basic: add force_materialize=True (test targets RuntimeError)

Document in DESIGN_PHILOSOPHY that observers receiving an Iterator must
consume it fully (application responsibility, causes tee buffer growth
otherwise). (26b999f)

Refactor

  • refactor: remove dead branches in async _pump_iterator and drop put_terminal
  • Collapse the two isinstance(q, AsyncQueueBranch): await q.put(item)
    else: await q.put(item) blocks in async _pump_iterator (both arms
    were byte-for-byte identical) into a single await q.put(item), and
    unify the materialize_before_enqueue / plain paths under one async
    for loop.
  • Remove AsyncQueueBranch.put_terminal: it was functionally identical
    to put (same active-gated put_nowait loop), so collapse callers in
    _pump_iterator to use put for terminal markers too.
  • Add pytest-timeout dev dependency and a per-test timeout=10s in
    pyproject.toml so a hung streaming test fails loudly instead of
    stalling the suite.

The sync SyncFanout._put_terminal busy-wait + get_nowait() drop is
intentionally left untouched here: removing the drop without a full
shutdown redesign of SyncFanout (terminal consumer that never drains
its SyncQueueIterator deadlocks the pump) turns it into a hard hang.
That belongs in its own PR. (dc8bebf)

Unknown

  • Merge pull request #37 from humansoftware/feat/validate-terminal-stream-output

feat: validate terminal steps with unmaterialized stream output at build time (43e5787)

  • Merge pull request #35 from humansoftware/ci/separate-lint-test-coverage

ci: separate lint, test, and coverage into parallel jobs (2377af9)

  • Merge pull request #34 from humansoftware/refactor/max-in-flight-cleanup

refactor: remove dead branches in async _pump_iterator and drop put_terminal (9d9a325)

v0.16.0

18 Jun 11:27

Choose a tag to compare

v0.16.0 (2026-06-18)

Documentation

  • docs: add final finished state t11 to interactive animation (a12d697)

  • docs: add interactive visualization for max_in_flight (c9ca483)

  • docs: add max_in_flight parallels to java-streams and linq comparison pages (830636b)

  • docs: restructure max-in-flight page with Sync/Async tabs (917e367)

  • docs: expand max_in_flight documentation (c4059a6)

Feature

  • feat: complete max_in_flight runtime and docs (c3f54d5)

  • feat: add max_in_flight tests and fix bounded iterator

  • Add test_dag_builder_max_in_flight.py (8 build-time validation tests)
  • Add test_runner_max_in_flight.py for sync and async (4 tests each)
  • Fix BoundedIterator: propagate exceptions immediately, don't buffer
  • Fix test parity by using identical test function names in sync and async (27c0fdd)
  • feat: add max_in_flight with bounded handoff for sync and async
  • Add max_in_flight: int = 1 to Step and DagNode
  • Validate max_in_flight >= 1 and integer at build time
  • Serialize max_in_flight in DAG JSON (always present)
  • Sync: BoundedIterator deque-backed wrapper for max_in_flight > 1
    (max_in_flight=1 preserves exact current behavior)
  • Async: use max(max_in_flight, 100) for queue sizing
  • Update all 18 corpus snapshots with max_in_flight: 1 (c838678)

Fix

  • fix: async queue sizing, observer threads, bounded handoff tests

Codex changes:

  • AsyncQueueBranch: implement aiter/anext for direct async iteration
  • Async executor: _attach_argument_cleanup, _close_stream_arguments
  • Async executor: queue sizing uses max(2, max_in_flight+1) for EOF
  • Async executor: _resolve_queue handles AsyncQueueBranch type
  • Sync executor: observer threads via SyncFanout branches
  • Sync executor: _observer_threads with cleanup on pipeline finish
  • Sync executor: _notify_observers in publish stream paths
  • 12 new tests: ahead_distance_bounded, producer_blocks,
    terminal_lazy_drains, flattening_stream_internal_items (sync+async)
  • 3 new observer tests: does_not_force_eager, does_not_consume_slots,
    bound_is_unchanged (sync+async) (73e92a9)
  • fix: use producer's max_in_flight for async unroll queue sizing
  • Async _unroll_step: look up producer node's max_in_flight instead
    of using consumer node's (fixes reviewer issue #1)
  • Keep 100 minimum queue size for publish/unroll to prevent pump
    deadlock (v1 limitation — reviewer issue #2 acknowledged)
  • Sync tee fan-out limitation documented as v1 constraint (0d8b75b)
  • fix: honor max_in_flight contract for sync fan-out and async queue sizing
  • Sync fan-out: apply BoundedIterator to source BEFORE itertools.tee
    so producer advancement is bounded at the source level
  • Async queue sizing: use node.max_in_flight directly when > 1,
    keep 100 for default=1 (backward compatible)
  • Add tests: sync fan-out bounded, async bounded ahead verification,
    parity between sync and async test names (5d8059d)

Refactor

  • refactor: move execution graph helpers onto Dag (7601b76)

  • refactor: clean residual imports and shared executor helpers (dcb9408)

  • refactor: structure pipeline executors (15fb065)

  • refactor: structure DAG builder and include expansion (a9deeab)

  • refactor: stabilize observer defaults and build helpers (07711b4)

  • refactor: replace **kw with explicit params in observer dispatch, direct attribute access

  • Sync and async executors: replace **kw in _dispatch_pipeline_event,
    _dispatch_step_event, _dispatch_materialization_event with explicit
    parameters (step_name, exception, success_count, error_count,
    completed_all_inputs)
  • Replace getattr(node, 'observers', None) with node.observers (DagNode
    always has observers as a list)
  • Replace getattr(step, 'error_materializer') → step.error_materializer
  • Replace getattr(step, 'parent_pipeline') → step.parent_pipeline
  • Replace getattr(step, 'observers') → step.observers in dag_builder
  • Replace getattr(node, 'observers', []) → node.observers in definition
  • Keep getattr for IncludeStep (lacks Step attributes) in dag_expansion
    and dag_steps validate_sync_async_consistency (5b6467d)

Style

  • style: ruff format codex changes (205afba)

  • style: format PR1 changes (a95f620)

Test

  • test: add runner contract, adapter serialization tests and fix threadpool corpus output type (c16170d)

  • test: add max_in_flight runtime coverage (4d44897)

  • test: expand max_in_flight coverage (c4b58ba)

  • test: add BoundedIterator unit tests, fix exception deferral

  • Add 10 unit tests for BoundedIterator edge cases
  • Fix exception handling: buffer items before raising, only raise
    pending exception when buffer is empty
  • maxsize validation, empty source, partial iteration covered (269a7d8)
  • test: cover Dag execution helper methods (344a64d)

Unknown

  • Merge pull request #33 from humansoftware/feat/max-in-flight-clean

feat: max_in_flight — bounded stream handoff (4879c70)

  • fix max_in_flight expansion and docs (0bfc670)

  • Merge pull request #31 from humansoftware/refactor/pr4-residual-cleanup

[codex] Refactor PR4: residual cleanup and shared executor helpers (e2d8787)

  • Merge pull request #30 from humansoftware/refactor/pr3-executor-structure

[codex] Refactor PR3: structure pipeline executors (b7a355a)

  • Merge pull request #29 from humansoftware/refactor/pr2-builder-expansion-structure

[codex] Refactor PR2: structure DAG builder and include expansion (bac95d6)

  • Merge pull request #28 from humansoftware/refactor/pr1-internal-contracts

[codex] Refactor PR1: stabilize observer defaults and build helpers (c240e4a)

  • Merge pull request #27 from humansoftware/refactor/observer-dispatch-cleanup

refactor: explicit observer dispatch params, direct attribute access (f20fd3c)

v0.15.0

15 Jun 16:45

Choose a tag to compare

v0.15.0 (2026-06-15)

Documentation

  • docs: rewrite README to reflect current documentation
  • Concise quickstart matching landing page
  • Highlights: type-hint wiring, lazy streaming, static validation, custom runners
  • Expanded comparison table with links
  • Links to all documentation sections
  • Badges (PyPI, license, Python) (79e63dc)
  • docs: add Google Analytics tracking ID (a83a636)

  • docs: improve SEO metadata in mkdocs.yml (9b06873)

  • docs: add LINQ comparison, concise landing page examples, reorganize comparisons section

  • Move java-streams to new Comparisons section
  • Add LINQ comparison page (Select/Where/GroupBy/ToList mapping)
  • Add concise type-hint wiring + lazy streaming examples to homepage
  • Update introduction page to mention Comparisons section (1e9fcef)
  • docs: add interactive lockstep animation + expanded framework comparison
  • Replace static table/sequence diagram on lockstep-flow with interactive
    frame-by-frame animation (play/pause, step navigation)
  • Shows pipeline executing concurrently: numbers yielding item 2 while
    doubler processes item 1 and printer prints item 0
  • Expand How It Compares table on homepage with Dagster, Prefect, Airflow
  • Add framework comparison table to DESIGN_PHILOSOPHY.md section 2.4 (09849db)
  • docs: rewrite lockstep-flow + enable branch preview deploys
  • Rewrite lockstep-flow with pipeline example first, DAG diagram,
    execution walkthrough table, fan-out section, execution levels
  • Single docs.yml workflow deploys via peaceiris/actions-gh-pages
    • main branch → root of gh-pages
    • feat/* branches → preview/<branch>/
  • No environment restrictions — deploys directly to gh-pages branch

IMPORTANT: GitHub Pages must be set to 'Deploy from branch'
(gh-pages, / root) for this to work. (f5eec27)

Feature

  • feat: add cookiecutter templates for quick project scaffolding
  • boilerplates/minimal: single-file app with pipeline.py
  • boilerplates/structured: multi-file project (steps, pipeline, main)
  • boilerplates/scaffold: single module to drop into existing project
  • Update installation docs with cookiecutter quickstart section
  • Exclude boilerplates/ from ruff in pre-commit config (d69bae0)

Unknown

  • Merge pull request #26 from humansoftware/feat/cookiecutter-templates

feat: cookiecutter templates for project scaffolding (50825eb)

  • Merge pull request #25 from humansoftware/feat/readme-update

docs: rewrite README to reflect current documentation (2d5be75)

  • Merge pull request #24 from humansoftware/feat/landing-page-examples

docs: landing page overhaul, comparisons, build-vs-run architecture (11e243b)

  • Merge pull request #23 from humansoftware/feat/docs-animation-comparison

docs: interactive lockstep animations, expanded comparisons, Java Streams & event-based processing (c920014)

  • Merge pull request #22 from humansoftware/feat/docs-improvements

docs: improve lockstep-flow page + enable branch preview deploys (0e4bda3)

v0.14.0

14 Jun 23:51

Choose a tag to compare

v0.14.0 (2026-06-14)

Feature

  • feat: documentation portal with MkDocs Material
  • Add mkdocs-material>=9.5 to dev dependencies
  • Configure mkdocs.yml with Material theme, code tabs, Mermaid support
  • Create .github/workflows/docs.yml to deploy to GitHub Pages on merge
  • Create scripts/visualize_dag.py (JSON to Mermaid flowchart)
  • Write comprehensive documentation under docs/user_docs/:
    • Introduction & Getting Started (installation, lockstep flow)
    • Step-by-step tutorial (4 levels: hello world, multi-step, observers, materializers)
    • Core Concepts (semantic naming, DAG construction, sync/async parity)
    • Advanced Guides (custom materializers, observers, export guidance)
  • All code snippets use sync/async tabs via pymdownx.tabbed
  • Update README.md with link to documentation portal
  • Delete docs/specs/documentation_portal.md (spec implemented)
  • Update docs/ROADMAP.md — moved to Completed (c05e533)

Unknown

  • Merge pull request #21 from humansoftware/feat/documentation-portal

feat: documentation portal with MkDocs Material (2ef6da0)

v0.13.0

14 Jun 23:42

Choose a tag to compare

v0.13.0 (2026-06-14)

Feature

  • feat: implement Smart Binding & Semantic Step Naming
  • Add inflect>=7.0 dependency for plural/singular resolution
  • New module synaflow/core/naming.py with get_base_dataset_name()
  • Smart binding at build time: deps keys are base names (producer names),
    DagNode.dataset_param_names maps base name → original param name
  • Executors use dataset_param_names for function calling; no runtime resolution
  • Build-time validations:
    • Duplicate Base Datasets (e.g., 'user' and 'users' steps)
    • Duplicate Parameters within a single function
  • dag.py: consumers_of and get_execution_levels simplified (deps are base names)
  • materialized_deps use dep keys directly (already base names)
  • Corpus pipelines updated (producer 'numbers', transformer param 'number')
  • 16 naming tests + 3 validation tests
  • Delete docs/specs/step_naming_rules.md (spec implemented)
  • Update docs/ROADMAP.md and docs/DESIGN_PHILOSOPHY.md (c5c4ba5)

Unknown

  • Merge pull request #20 from humansoftware/feat/semantic-naming

feat: Smart Binding & Semantic Step Naming (ff2d1b3)

v0.12.0

14 Jun 22:59

Choose a tag to compare

v0.12.0 (2026-06-14)

Feature

  • feat: add patch coverage check (80%) to pre-commit hook
  • Refactor coverage_report.py to support --precommit mode
  • Pre-commit shell script calls coverage_report.py --precommit
  • Single source of truth for coverage computation (05efffb)
  • feat: add coverage to pre-commit pytest hook (0bba7dc)

Unknown

  • Merge pull request #19 from humansoftware/feat/precommit-coverage

feat: add patch coverage check (80%) to pre-commit hook (2f8302a)

v0.11.0

14 Jun 22:52

Choose a tag to compare

v0.11.0 (2026-06-14)

Chore

  • chore: address PR #18 review comments
  • Add [tool.coverage.run] omit for tests/ and scripts/
  • Delete docs/specs/test_coverage_ci.md (spec implemented)
  • Move Test Coverage CI to Completed in ROADMAP.md (19b671b)

Documentation

  • docs: update roadmap to reflect in-progress specs (46a09bf)

  • docs: add pypi version and install instructions to documentation spec (6dcebc9)

  • docs: upgrade spec 3 to full documentation portal and visualization (b2c73fd)

  • docs: add pre-commit hook requirement for testing to coverage spec (7aa5ead)

  • docs: rewrite coverage spec for dual metrics and non-blocking statuses (7145f7b)

  • docs: detail coverage spec with pyproject.toml and PR comment action (9d4418b)

  • docs: add specs for naming rules, test coverage, and export guidance (fa92f3a)

Feature

  • feat: implement dual test coverage CI (total + patch at 80%)
  • Add .github/workflows/test-coverage.yml workflow triggered on PRs
  • Add .github/scripts/coverage_report.py to compute and post check runs
  • Add pytest hook to pre-commit config
  • Add pytest-cov to dev dependencies
  • Update .gitignore for coverage artifacts (0580864)

Unknown

  • Merge pull request #18 from humansoftware/feat/test-coverage-ci

feat: implement dual test coverage CI (total + patch at 80%) (0a4072c)

  • Merge pull request #17 from humansoftware/feature/update-roadmap-and-specs

docs: add specs for naming rules, coverage, and export guidance (cbb505b)

v0.10.0

14 Jun 21:13

Choose a tag to compare

v0.10.0 (2026-06-14)

Chore

  • chore: update uv.lock with ruff dependency (088fd05)

Documentation

  • docs: clarify observer scope model; restore pipeline_observers to DAG JSON

Documentation:

  • Step-level observers never receive PipelineEvent.*
  • Pipeline-level observers receive PipelineEvent.* + inherited by all steps
  • DAG JSON: pipeline_observers at root, observers per step

DAG JSON now includes compiled pipeline observer metadata alongside
per-step effective observer lists. Both carry handler_name + source. (20eb757)

Feature

  • feat: unified lifecycle observer system

Introduces a generic observer infrastructure for pipeline, step, and
materialization lifecycle events with sync/async parity.

  • Public API: Observer, PipelineEvent, StepEvent, MaterializationEvent
  • Step-level observers compile into the same model as pipeline-level
  • Effective observers resolved at build time, stored in DagNode
  • DAG JSON includes observer metadata (event + source), never callables
  • Fire-and-forget dispatch: observer failures are logged and swallowed
  • Async handler detection via awaitable protocol (not iscoroutinefunction)
  • 54 new tests: 15 build-time, 18 sync runtime, 21 async runtime
  • Corpus pack updated for integration coverage
  • Docs updated: DESIGN_PHILOSOPHY (3.15) and ROADMAP (385fedc)

Fix

  • fix: propagate observers through include() / sub-pipeline expansion (35d2505)

  • fix: three remaining codex issues

  1. Async _run_step isinstance check covers AsyncIterator/AsyncGenerator/Generator
  2. ResolvedObserver internal type replaces _source mutation
  3. dispatch_observers_async uses inspect.isawaitable

Both sync and async repros now emit single terminal FAILED with real exception. (3e493c1)

  • fix: thread real exception through StepFailedContext; remove pipeline_observers from DAG JSON
  1. _collect_iterator returns (items, had_error, exception)
    _apply_materializer and _materialize_with_events propagate it
    _emit_step_result passes it to StepFailedContext.exception
    Applied to both sync and async executors.

  2. DAG JSON: removed redundant top-level pipeline_observers field.
    Effective per-step observer lists already preserve source metadata.
    Pipeline observers are inherited into each step node with source="pipeline".

Verified codex repro now emits:
('gen', 'step_failed', 1, 1, False, 'ValueError') (bc575a9)

  • fix: defer ALL-mode Iterator step COMPLETED until consumption

For ALL-mode steps that return an Iterator, COMPLETED was emitted
prematurely in _run_step before the iterator was consumed. If the
iterator later failed during downstream materialization, the step
remained marked as COMPLETED instead of FAILED.

Now: ALL-mode Iterator steps have their COMPLETED deferred to
_publish_output, same as EACH-mode steps. The _emit_step_result
helper checks had_error and emits StepFailedContext when the
iterator fails during consumption.

Confirmed with codex repro: gen yields 1 item then raises; downstream
list consumer triggers materialization. Now correctly emits:
('gen', 'step_failed', 1, 1, False, None) (be65d6a)

  • fix: DAG JSON source preservation and lazy iterator step lifecycle
  1. DAG JSON: pipeline observers inherited into steps now preserve
    source="pipeline" on the step node instead of source="step".
    Uses _source attribute tagged during build_dag normalization.

  2. Lazy iterator step lifecycle: when an EACH-mode step"s iterator
    fails during consumption (OnError.CONTINUE), StepFailedContext is
    now emitted instead of StepCompletedContext.
    _collect_iterator and _apply_materializer return (result, had_error).
    _emit_each_step_result dispatches COMPLETED or FAILED accordingly.
    Applied to both sync and async executors.

  3. Added tests for source preservation on step-level and mixed observers. (000e00a)

Refactor

  • refactor: align Observer API with updated spec
  • Observer now carries only handler (no event field)
  • dispatch_observers(registrations, context) — no event param, calls all handlers
  • Event filtering done via wrapper helpers inspecting ctx.event
  • Pipeline observers inherited by all steps (receive pipeline + step + mat events)
  • DAG JSON metadata uses handler_name instead of event
  • Tests updated: on_event() wrapper pattern matching spec recommendations
  • 340 tests passing (2bf6ee6)

Unknown

  • Merge pull request #15 from humansoftware/feature/observer-system

feat: unified lifecycle observer system (5fdeeb1)

v0.9.1

14 Jun 12:39

Choose a tag to compare

v0.9.1 (2026-06-14)

Documentation

  • docs: remove stale SyncStreamManager reference from coding standards (ee522cf)

  • docs: fix inconsistencies in design philosophy

  • Clarify materializer resolution (runtime still handles factory-with-context)
  • Rename needs_materialize→materialized_deps section (matches code)
  • Replace adapt_argument_to_consumer_type section (removed from code)
  • Add sections: inline executors, step_output_observers, PipelineStopException context (efa3698)

Fix

  • fix: make materializer signature validation strict and prevent swallowing signature exceptions (c400779)

  • fix: support async sub-materializers and handlers in composite materializers (1b618bb)

  • fix: resolve sub-pipeline laziness regression and align DAG serialization contract (cff719b)

Refactor

  • refactor: simplify laziness design by removing has_step_materializer and relying on force_materialize (50b09f4)

Test

  • test: refactor error_handling corpus verification to dedicated parity tests (66f0c94)

  • test: add explicit regression tests for lazy steps with step-level materializers (756192f)

  • test: add async error presets, include() precedence, and serializer/helper unit tests (b5e1088)

Unknown

  • Merge pull request #14 from humansoftware/feature/materializers-ergonomics

Materializer Ergonomics and Standard Library (abdf950)

  • Implement materializer ergonomics improvements and standard library (396a702)

  • Merge pull request #12 from humansoftware/review/dag-snapshots-observer-contracts

[codex] strengthen DAG snapshots and observer contracts (f4884de)

  • update docs for step mode and runtime contracts (f3f9f17)

  • strengthen dag snapshots and observer contracts (710d729)

  • Merge pull request #11 from humansoftware/review/more-robustness-tests

[codex] strengthen mode resolution and runtime robustness (52f3571)

  • align runtime error handling and output inference contracts (1011364)

  • add step mode coverage and robustness tests (03a70a1)

  • Merge pull request #10 from humansoftware/review/test-contract-gaps

[codex] add failing contract tests for materialization semantics (209ef93)

  • fix materialization and error handling semantics (3b66eaf)

  • add failing contract tests for materialization semantics (f8fcc33)

  • Merge pull request #9 from humansoftware/docs/update-design-philosophy

docs: fix design philosophy inconsistencies (26a782f)

  • Merge pull request #8 from humansoftware/chore/cleanup-dump-script

chore: remove debug dump script (c4919e2)

v0.9.0

13 Jun 21:33

Choose a tag to compare

v0.9.0 (2026-06-13)

Ci

  • ci: add ruff F401 check for unused imports in pre-commit and CI
  • Add ruff to pre-commit with --fix --select F401 (auto-remove)
  • Add ruff check to CI workflow (verify only)
  • Remove unused imports found by ruff across codebase (c2ea5d2)

Feature

  • feat: add name to Dag, make _dag public, use dag.name in runtime
  • Add name field to Dag dataclass, set during build_dag
  • Make _dag public (dag) on PipelineDef
  • Include name in DAG JSON output
  • Runtime components use dag.name instead of pipeline.name
  • Update all corpus json_dag with name field (7d782c0)

Fix

  • fix: ruff fixes (format + unused imports) (26b5e30)

  • fix: use ruff-check hook id instead of legacy alias (5230d36)

  • fix: align ruff version to 0.15.17 in pre-commit and dev deps (6d86afc)

  • fix: ruff format test_parity.py (39888f4)

  • fix: remove redundant ruff-format (black already covers formatting) (e67a6a3)

Refactor

  • refactor: replace black+isort with ruff format+ruff check
  • Replace black and isort hooks with ruff-format and ruff
  • Update CI to use ruff format --check and ruff check
  • Add ruff to dev dependencies (b840f56)
  • refactor: rewrite executors, add dag methods, update docs
  • Merge all sync/async engine modules into single executor.py each
  • Remove Sync/AsyncStreamManager, NodeRunner, DependencyResolver classes
  • Remove TeeWrapper/AsyncTeeWrapper, InterleavedIterator, materializer stubs
  • Add step_output_observers for test injection
  • PipelineStopException with step_name + cause + raise from
  • Composite key fan-out, zip multi-stream unroll with None padding
  • each_inputs method on Dag
  • Move pipeline_pack.py to tests/common/
  • Delete dump_packs.py, stale files
  • Update DESIGN_PHILOSOPHY.md, ROADMAP.md, AGENTS.md (5a202d1)
  • refactor: replace SyncStreamManager with pure functions in stream_routing.py
  • Move topology.py to stream_routing.py with clean functions: handle_step_output, apply_materializer, resolve_dependency
  • Remove SyncStreamManager class - no state needed
  • Remove coerce_value_for_consumer - materializer should produce right type directly
  • Move consumers_of to Dag with unit test
  • Simplify SyncNodeRunner and PipelineExecutor - no stream_manager dependency
  • Remove set/tuple coercion tests (tested wrong contract) (69c45c6)

Unknown

  • Merge pull request #7 from humansoftware/refactor/executor_di

refactor: executor rewrites, dag model improvements, materializer architecture (cbd5c8b)