# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.3.0] - 2026-04-28

### Added

- **New `flowdrop_chat` module** (`lifecycle: experimental`): Chat backend for conversational workflow orchestration, supporting two processing modes:
  - **Built-in LLM mode** with `ChatLlmClient` (Ollama, Anthropic), `ChatService` orchestration, and `SystemPromptBuilder` that injects slim workflow state and node type definitions into system prompts.
  - **Workflow-based mode** that delegates chat handling to a FlowDrop workflow, with `GetNodeTypes` and `BuildSystemPrompt` node processors and default chat processor workflows shipped as recipe content.
  - Chat API controller and routing with configurable endpoint config.
  - Admin settings form for provider and mode configuration.
  - `SystemPromptBuilder::nodeTypesJson()` API for retrieving slim node type definitions from a node.
  - Unit tests for `ChatService` and `SystemPromptBuilder`.
  - **Note:** `flowdrop_chat` requires `drupal/flowdrop_ai_provider` (currently `dev-1.0.x`), which is not pulled automatically by `composer require drupal/flowdrop`. Install it separately: `composer require drupal/flowdrop_ai_provider:dev-1.0.x@dev` before enabling this submodule.
  - `hook_uninstall()` deletes all chat history memory records when the module is uninstalled.
- **`FlowDropNodeTypeManagerInterface`**: New public service interface for the node type manager. FQCN aliases are registered for `FlowDropNodeTypeManagerInterface` and all three `flowdrop_chat` services (`ChatServiceInterface`, `SystemPromptBuilderInterface`, `ChatLlmClientInterface`), enabling `$container->get(ServiceInterface::class)` lookups alongside the existing string-ID approach.
- **`TextProcessor` node**: New node type for common text utilities, with documentation in the Text & Output reference.
- **`HtmlToMarkdown` node processor**: Converts HTML input to Markdown, with unit test coverage.
- **`MarkdownExtractor` node processor**: Extracts structured data from Markdown content.
- **`MarkdownToHtml` node processor**: Converts Markdown input to HTML.
- **Tolerant parse mode for `json_to_data`**: New mode that recovers from partial or malformed JSON, improving robustness in LLM output pipelines.
- **`visual_type` and `supported_visual_types`** exposed in node type API data, enabling richer frontend rendering hints.
- **Dashboard-layout library** (#3583166): Replaces `fullscreen-layout` on admin pages with a dedicated dashboard layout, removing the unintended white background.
- **Plugin dependency declarations on `flowdrop_node_type` config entities** (#3583422): Config entities now declare the module dependencies of their executor plugins, so exported configuration installs cleanly on a fresh site.
- **Plugin-driven select for `memory_backend`**: Replaces the freeform textfield with a validated select populated from registered memory backends; prompt templates are validated on save.
- **Workflow description length limit**: Enforces a 1000-character maximum on the workflow description field.

### Changed

- **Drupal-side JavaScript modernized**: Pipeline monitor drops jQuery in favor of `core/once`, and the remaining Drupal-side JS uses arrow functions and tidied JSDoc.
- **Frontend library bumped to `@flowdrop/flowdrop` 1.8.1**.

### Fixed

- Fixed `ChatService::getHistory()` and `clearHistory()` operating on the wrong memory store in workflow processing mode (they now return early when `processing_mode` is `workflow`).
- Fixed `memory_backend` config defaulting to `null` instead of `'entity'` when unset.
- Fixed `flowdrop_ui_components` clobbering the persisted theme preference on initialization, which caused light/dark mode to flicker back to default on page load.
- Fixed `TranslatableMarkup` not cast to string before display in the pipeline form, causing render errors on some labels and descriptions.
- Fixed workflow API controllers swallowing HTTP exceptions instead of re-throwing them, masking 4xx/5xx responses with generic 500s.
- Fixed chat API not returning `workflowId` as `conversationId` in the response payload.
- Fixed toolbar icons not rendering under the Drupal Navigation module (#3583239): adds Navigation-module CSS selectors (`.toolbar-link--*`, `.toolbar-button--icon--*`) and a `hook_page_attachments` that attaches the toolbar library on every page (gated on `administer flowdrop`), since Navigation does not invoke `hook_toolbar()`.
- Removed developer `console` statements from Drupal-side JS components.

### Security

- **Workflow API hardening**: Added ID conflict check on import, complexity limits on submitted workflows, and random IDs to prevent enumeration.
- **Workflow list builder**: Sanitize the `sort` query parameter to prevent injection of unintended sort columns.
- **Chat API rate limiting and observability**: Flood control on chat endpoints, payload size limit, and audit logging of chat requests.
- **Chat prompt-injection hardening**:
  - Sanitize non-JSON `workflowState` payloads before injecting into the system prompt.
  - XML-encode chat history before injection.
  - Remove client-supplied history and enforce a per-message length limit.
- **Reduced error-message disclosure**: Avoid exposing the configured model ID in chat error responses.
- **Chat API `workflowState` size limit**: Array-typed `workflowState` payloads now enforce the same complexity limits as the workflow API (max 500 nodes, 1000 edges), closing a DoS vector where the string-only size check could be bypassed by sending an array.
- **Workflow export documentation**: Warn users that exported workflow configuration may contain sensitive values.

## [1.2.0] - 2026-03-19

### Added

- **Dynamic input/output ports**: Node types can now declare dynamic ports whose number and names are determined at runtime by configuration. Introduces `DynamicPortTrait` for node processors, a `ReservedName` constants class to prevent name collisions, and a new `DataMapper` node processor that maps input fields to output ports dynamically.
- **ExpressionEvaluator plugin system**: New `#[ExpressionEvaluator]` attribute-based plugin manager with four built-in engines — `property_path` (Symfony PropertyAccess), `expression_language` (Symfony ExpressionLanguage), `twig` (Twig), and `jsonpath` (JSONPath via `flowdrop_runtime`). Replaces hardcoded service dependencies in expression-heavy processors with a configurable, swappable architecture.
- **`EventCategory::Integration`**: New enum case for grouping event types triggered by external platform invocations (e.g. Orchestration Invoke).
- **Module installation kernel tests**: `ModuleInstallationTest` now covers all 18 FlowDrop modules via a `@dataProvider`, simulating `drush en <module>` for each and catching missing dependency declarations automatically.

### Changed

- **DataExtractor** (v2.1.0): Replaces direct `JsonPathService` dependency with the `ExpressionEvaluator` plugin system. Adds a configurable `engine` parameter (defaults to `jsonpath` — existing behavior preserved).
- **DataShaper** (v1.1.0): Replaces `DataMapperService` with the `ExpressionEvaluator` plugin system. Adds a configurable `engine` parameter (defaults to `property_path` — existing behavior preserved).
- **DataMapper** (v1.0.0): Switches from hardcoded Twig to a configurable `engine` parameter (defaults to `expression_language`).
- Node type config entities for `data_extractor`, `data_shaper`, and `data_mapper` updated with the new `engine` parameter.
- `OrchestrationInvoke` event type plugin now uses the typed `EventCategory::Integration` constant instead of a bare string.

### Fixed

- Fixed `flowdrop_node_type` not declared as an explicit dependency of `flowdrop_job`, which could cause install failures in a fresh environment.
- Fixed `NULL` node type values causing errors in pipeline job timeline components.
- Fixed `EventCategory` enum not converted to string before use in trigger services.
- Fixed dynamic port `configurable` flag not toggleable by site administrators in the node type form.

## [1.1.2] - 2026-03-18

### Fixed

- Fixed error enabling `flowdrop_playground` caused by a circular module dependency between `flowdrop_pipeline` and `flowdrop_runtime` (#3579822). The `snapshot_id` field on `FlowDropPipeline` is now injected dynamically by `flowdrop_runtime` via `hook_entity_base_field_info()` instead of being declared statically in `flowdrop_pipeline`, eliminating the install-time dependency cycle.

## [1.1.1] - 2026-03-17

### Fixed

- Fixed autowiring failure for `Drupal\flowdrop_memory\Hook\CronHooks` during `drush cr` (#3579749).

## [1.1.0] - 2026-03-15

### Added

- **New `flowdrop_memory` module**: Persistent memory system for workflows, enabling nodes to store, retrieve, and delete stateful data across executions. Includes:
  - `MemoryRead` / `MemoryWrite` / `MemoryDelete` node processors with automatic context-based scope resolution.
  - `MemoryReadRaw` / `MemoryWriteRaw` / `MemoryDeleteRaw` node processors for explicit cross-scope memory operations.
  - `ConversationBuffer` node processor implementing sliding-window message management (LangChain-style memory patterns).
  - Pluggable memory backend system with `EntityMemoryBackend` (database-backed) and `CachedMemoryBackend` (cache-backed) implementations.
  - `MemoryRecord` content entity with database indexes for efficient scope-based lookups.
  - Cron-based cleanup for expired memory records.
  - Configuration form with validated cache bin selection for the cached backend.
  - Value size validation (1 MB limit) to prevent abuse.
  - Comprehensive unit test coverage for backends, entity, and all node processors.

### Changed

- Switched JS library package from `@d34dman/flowdrop` to `@flowdrop/flowdrop`.
- Updated `@flowdrop/flowdrop` JS library to 1.4.0.
- Registered all submodules in `composer.json` PSR-4 autoload.


## [1.0.0] - 2026-03-07

**First stable release of FlowDrop.** All public APIs are now covered by semantic versioning backward compatibility guarantees. See `docs/api/BC-POLICY.md` for details.

### Changed

- Upgraded `@d34dman/flowdrop` JS library to 1.0.0.
- Disabled CI testing against next Drupal major version.

### Fixed

- Fixed build script to restore `build/.gitignore` and `README.md` after Vite build cleans output directory.
- Linter fixes across codebase.

## [1.0.0-beta2] - 2026-03-07

### Changed

- **Trigger module stabilized**: `flowdrop_trigger` promoted from `lifecycle: experimental` to `lifecycle: stable`. `TriggerManagerInterface`, `FlowDropTriggerConfigInterface`, and `FlowDropEventTypeInterface` marked `@api` with full semver BC guarantees.
- **Workflow Executor module stabilized**: `flowdrop_workflow_executor` promoted from `lifecycle: experimental` to `lifecycle: stable`. `WorkflowExecutionServiceInterface`, `WorkflowExecutionMode`, and `WorkflowExecutionStatus` marked `@api`.
- **All experimental modules promoted to stable**: `flowdrop_stategraph`, `flowdrop_interrupt`, `flowdrop_playground`, and `flowdrop_orchestration_connector` promoted from `lifecycle: experimental` to `lifecycle: stable`. Public contracts annotated `@api`; implementation classes annotated `@internal`.
- **BREAKING**: `WorkflowExecutionServiceInterface::execute()` now accepts `WorkflowExecutionMode` enum instead of string constants. `getStatus()` returns `WorkflowExecutionStatus` enum instead of `string`.
- **BREAKING**: `FlowDropEventTypeInterface::getCategory()` returns `EventCategory` enum; `getDefaultExecutionMode()` returns `TriggerExecutionMode` enum.
- `AbstractOrchestratorBase` promoted from `@internal` to `@api`.
- SDC components (`playground`, `editor`, `schema-form`) status updated to stable.
- Updated BC policy to document newly stabilized APIs and removed experimental module list.
- Replaced raw string errors with `ValidationError` objects in stategraph node processors.
- Added missing `strict_types` declarations across codebase.
- Documented `accessCheck(FALSE)` bypass rationale in entity queries.
- Updated `@d34dman/flowdrop` JS library to 0.0.63.

### Security

- Fixed LIKE wildcard injection in workflow search query by escaping user-supplied wildcards.
- Added sort direction and entity field name validation in list builder and node processors to prevent query manipulation.
- Prevented SSRF DNS rebinding by pinning curl to validated IP via `CURLOPT_RESOLVE`.
- Added IPv6 DNS resolution support for SSRF protection.

### Fixed

- Fixed kernel test failures caused by incorrect `DrupalKernel` `app_root` resolution in `ddev-drupal-contrib` environments.
- Fixed permission name mismatches in job and pipeline routing files.
- Fixed missing `nodeId` in `ExecutionContextDTO::toArray()` serialization.
- Added missing return type declarations on public controller methods.
- Added missing `drupal:user` and `drupal:views` module dependencies.
- Added missing `hook_uninstall()` implementations to prevent data leakage on module removal.
- Resolved `EntityInterface` type narrowing issues across controllers and forms.
- Corrected broken BC policy document link in UPGRADE.md.

### Added

- **Configurable access-check user for EntitySave**: The `EntitySave` node processor now supports specifying which user context to use for entity access checks.
- PHP enums for trigger and executor type safety: `EventCategory`, `TriggerExecutionMode`, `WorkflowExecutionMode`, `WorkflowExecutionStatus`.
- SECURITY.md with vulnerability reporting guidelines.
- Unit tests for SSRF protection and IPv6 DNS resolution in HTTP Request node processor.
- API contract tests for 1.0.0 stability guarantee.
- Critical service layer unit tests for 1.0.0 release.
- CI testing against next Drupal major version.
- Site builder documentation with new guides and node reference.
- Script for automatically injecting API docs into MkDocs.

## [1.0.0-beta1] - 2026-02-27

**First beta release. FlowDrop is now feature-complete for 1.0 and entering stabilization. No new breaking changes are planned — only bug fixes and documentation improvements from this point forward.**

### Changed

- **API annotation policy**: Fixed `@api` / `@internal` annotation violations and documented Orchestrator plugin classes in the backward compatibility policy.
- Updated documentation on how to extend components in FlowDrop.
- Updated documentation links.

### Fixed

- Fixed broken test after recent refactor.

## [1.0.0-alpha5] - 2026-02-27

### Added

- **Typed event system**: 26 purpose-built event classes with `readonly` properties replace `GenericEvent` across 5 modules (`flowdrop_interrupt`, `flowdrop_pipeline`, `flowdrop_runtime`, `flowdrop_stategraph`, `flowdrop_trigger`). Each class carries a `NAME` constant for the event name. All events are marked `@experimental`.
- **Orchestrator plugin API stabilized**: `OrchestratorPluginBase`, `OrchestratorPluginInterface`, `OrchestratorInterface`, and `Orchestrator` attribute promoted from `@internal` to `@api` with full semver BC guarantees.
- **Typed constant classes**: `PortDirection` and `EdgeKeys` (`@api`) for workflow edge data; `ErrorCategory` and `ExecutionStatus` (`@internal`) for runtime status tracking. Replaces hardcoded status strings across session, pipeline, and job modules.
- **Exception class hierarchy**: `FlowDropException` base class (`@api`) with typed subclasses `InvalidNodeConfigurationException`, `NodeProcessingException`, and `EntityProcessingException`. All module-level exceptions re-parented under `FlowDropException`.
- **Cron recovery for stuck sessions**: Sessions stuck in `running` or `awaiting_input` for over 10 minutes are automatically reset to `idle` during cron. Processes up to 50 sessions per run.
- **Cron cleanup for interrupts**: Expired, resolved, and cancelled interrupts automatically cleaned up during cron. Configurable via `flowdrop_interrupt.settings` (`cleanup_enabled`, `cleanup_max_age`).
- **Interrupt metadata enrichment**: Flat metadata keys (`allow_cancel`, `confirm_label`, `cancel_label`, `placeholder`, `multiline`, `min_length`, `max_length`) added to interrupt session messages for frontend rendering.
- **Interrupt polling lifecycle**: `onSessionStatusChange` and `startPolling` wired up for real-time interrupt status updates.
- **Job mode trigger messages**: `WorkflowExecutionService` now processes trigger messages synchronously in job mode (#3573704).
- **Concurrent interrupt resolution lock**: Prevents race conditions when multiple requests attempt to resolve the same interrupt simultaneously.
- **LICENSE and CONTRIBUTING.md**: Added project license and contribution guidelines with pre-commit configuration.

### Changed

- **BREAKING**: All FlowDrop events now dispatch typed event classes instead of `GenericEvent`. Event subscribers must update type hints and change property access from `$event->getArgument('key')` to `$event->property`. See UPGRADE.md for migration details.
- **BREAKING**: 32 internal services marked `public: false` across `flowdrop_interrupt`, `flowdrop_orchestration`, `flowdrop_runtime`, `flowdrop_session`, and `flowdrop_stategraph`. Code using `\Drupal::service()` for these must switch to dependency injection.
- **BREAKING**: Constructor signatures changed: `ApprovalGateHandler` (removed `$entityTypeManager`), `StateGraphOrchestrator` (removed `$configFactory`), `FlowDropEndpointConfigService` (constructor removed).
- Replaced `assert()` calls with runtime-safe `if` checks across 15 files. In production (`zend.assertions=-1`), `assert()` is compiled out, silently disabling type guards. Access control handlers now return `AccessResult::neutral()` on type mismatch instead of silently passing.
- Node processors now throw typed exceptions (`InvalidNodeConfigurationException`, `NodeProcessingException`, `EntityProcessingException`) instead of generic `\RuntimeException`.
- Extracted `FlowDropListBuilderTrait` (`@internal`) consolidating shared tablesort, pagination, and status pill rendering logic from entity list builders.
- Replaced `\Drupal::` static service calls with proper dependency injection in entity classes, controllers, and hook classes.
- Interrupt event subscribers registered and pipeline now pauses on interrupt creation.
- Unified interrupt exception hierarchy with correct event subscriber types.
- Removed empty `.module` files no longer needed in Drupal 10+.
- Updated `@d34dman/flowdrop` JS library to 0.0.61.
- Improved UI components accessibility, build configuration, and type safety.

### Security

- **XSS prevention**: Escaped dynamic values in `#markup` render arrays across forms and traits using `Html::escape()`.
- **Input validation**: Validate `EntityQuery` operator and sort direction, `IfElse` operator and `Calculator` operation, `DataOperations` and `DataframeOperations` parameters against allowlists.
- **ReDoS protection**: Harden regex handling with validation, error handling, and pattern length limits.
- **CSRF protection**: Add CSRF token to node validation POST route and provide token to frontend via endpoint config auth headers.
- **Access control**: Add entity-level access checks to Snapshot and Pipeline API controllers.
- **Information disclosure**: Sanitize error messages in API responses to prevent stack trace and internal path leakage.
- **Dependency vulnerability**: Patch rollup dependency for path traversal vulnerability (GHSA-mw96-cpmx-2vgc).
- **API hardening**: Comprehensive SSRF protection, CSRF validation, access checks, and error sanitization across API controllers.

### Fixed

- Restore `flowdrop.module` stub required by PHPStan file discovery.
- Accept session UUIDs in `listSessionInterrupts` route.
- Include `sessionStatus` in playground `getMessages` API response.
- Restore loose comparison semantics for `==` and `!=` operators in `ConditionalEdgeEvaluator`.
- Add error logging and strict comparison in `FlowDropPipeline`.
- Clean up job routing permissions.
- Fix Icon Picker JavaScript library VERSION number mismatch (#3574978).
- Fix misleading node type registration example in DEVELOPMENT.md.
- Make `deferred_message_processor` and other services accessed via `$container->get()` properly public.

## [1.0.0-alpha4] - 2026-02-21

### Changed

- **BREAKING**: Standardized all API response envelopes to `{ success, data, error }` format using new `ApiResponseTrait`. The `message`, `code`, and `count` fields have been removed from responses.
- **BREAKING**: Pagination in `WorkflowsController` moved from HTTP headers (`X-Total-Count`, etc.) to response body `pagination` object.
- **BREAKING**: Hardcoded CORS headers removed from `WorkflowsController`. Configure CORS at the server level.
- **BREAKING**: `StateCheckpoint` entity class renamed to `FlowDropStateCheckpoint` (entity type ID unchanged).
- **BREAKING**: `StateCheckpointInterface` renamed to `FlowDropStateCheckpointInterface`.
- **BREAKING**: `StateCheckpointAccessControlHandler` renamed to `FlowDropStateCheckpointAccessControlHandler`.
- **BREAKING**: Frontend custom events renamed: `schemaform:*` → `flowdrop:schemaform:*`, `fd-plugin-selected` → `flowdrop:plugin-selector:selected`.
- **BREAKING**: Frontend data attributes renamed: `data-fd-*` → `data-flowdrop-*`, `data-schema-form-initialized` → `data-flowdrop-initialized`.
- **BREAKING**: Drupal behavior names standardized: `fdPluginSelector` → `flowdropPluginSelector`, `fdDepNav` → `flowdropDependencyNavigator`.
- **BREAKING**: Removed non-functional `mountSchemaForm.update()` method. Callers should destroy and re-mount instead.
- Replaced hardcoded orchestrator ID checks with capability-based detection using `OrchestratorHelper` methods.
- Extracted large form classes into traits: `TriggerConfigForm`, `WorkflowExecutionForm`, and `FlowDropNodeTypeForm` methods split into focused traits.
- Replaced static `\Drupal::` service calls with proper dependency injection in all entity list builders.
- `FlowDropInterruptInterface` now extends `EntityChangedInterface`.
- `FlowDropInterrupt` entity converted from `@ContentEntityType` annotation to `#[ContentEntityType]` attribute.
- Interface inheritance order standardized to `ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface`.
- Added `: void` return type to `preSave()` in `FlowDropPipeline` and `FlowDropJob`.
- All API controllers made `final` with consistent constructor property promotion.
- Stripped `console.log`/`console.debug`/`console.info` from production JS build.
- Libraries.yml version set to `VERSION` (tracks module version).
- Updated `@d34dman/flowdrop` JS library to 0.0.59.

### Removed

- `FlowDropPipeline::getReadyJobs()` — use `JobGenerationService::getReadyJobs()` instead.
- Non-functional `mountSchemaForm.update()` method.

### Fixed

- Added version query string to inter-chunk JS imports for cache busting.
- Added `detach` hook to `data-viewer.js` to prevent memory leaks.
- Aligned `WorkflowsController` API response with frontend `Workflow` interface.

## [1.0.0-alpha3] - 2026-02-07

### Added

- **`patch_mode` for EntitySave node processor**: When enabled, loads the existing entity by ID and merges only the specified field values, preserving all other fields. Prevents validation failures on required fields during partial updates.
- **Revision support for EntitySave**: `new_revision` and `revision_log_message` parameters allow forcing new revisions on revisionable entities with optional log messages. Outputs `revision_id` after save.

### Changed

- **BREAKING**: `JsonPathServiceInterface` moved from `Drupal\flowdrop_runtime\Service\JsonPath` to `Drupal\flowdrop\Service\JsonPath`. Update `use` statements accordingly.
- **BREAKING**: `PipelineExecutorInterface` moved from `Drupal\flowdrop_orchestration` to `Drupal\flowdrop_runtime\Service\Orchestrator`. Update `use` statements accordingly.
- **BREAKING**: `$storage` parameter is now required in `FlowDropWorkflowSnapshot::createFromWorkflowSnapshot(WorkflowSnapshot $snapshot, EntityStorageInterface $storage)`.
- **BREAKING**: Service ID `flowdrop_runtime.interrupt_persistence` renamed to `flowdrop_interrupt.persistence`. Update any service references or `@inject` annotations.
- **BREAKING**: `WorkflowSnapshot` and `NodeSnapshot` moved from `Drupal\flowdrop_runtime\DTO\Snapshot` to `Drupal\flowdrop_orchestration\DTO\Snapshot`.
- **BREAKING**: `InterruptExceptionInterface` moved from `Drupal\flowdrop_interrupt\Exception` to `Drupal\flowdrop_orchestration\Exception`.
- **BREAKING**: `Message` and `IteratorState` moved from `Drupal\flowdrop_stategraph\DTO` to `Drupal\flowdrop_orchestration\DTO\Snapshot`.
- **BREAKING**: `DrupalInterruptPersistence` moved from `Drupal\flowdrop_runtime\Service\Interrupt` to `Drupal\flowdrop_interrupt\Service`.
- **Converted procedural hooks to PHP 8 attribute-based hook classes** across 7 modules (`flowdrop_workflow`, `flowdrop_job`, `flowdrop_pipeline`, `flowdrop_runtime`, `flowdrop_session`, `flowdrop_interrupt`, `flowdrop_playground`). All hook classes use constructor injection instead of `\Drupal::` static calls.
- **Replaced magic strings with constant classes**: Added `PipelineStatus`, `JobStatus`, `WorkflowSnapshot`, and `NodeSnapshot` status constants. Created 12 `Permissions.php` constant classes replacing 50+ magic permission strings across access handlers and controllers.
- **Split TriggerManager** (1415 lines) into three focused services: `EventFilterService`, `OrchestrationRequestBuilder`, and `TriggerExecutor`. Public `TriggerManagerInterface` remains unchanged.
- **Split SessionService** (1878 lines) by extracting workflow execution logic into `SessionExecutionService` (909 lines). Broke circular dependency with `DeferredMessageProcessor` via `DeferredSchedulerInterface` and `MessageProcessorInterface`.
- **Extracted cross-module interfaces**: `NodeRuntimeServiceInterface`, `WorkflowCompilerInterface`, `StateManagerInterface`, `RealTimeManagerInterface`, `TriggerManagerInterface`. All consumers now type-hint interfaces instead of concrete classes.
- **Decoupled FlowDropSettingsForm** from orchestration module using dynamic service access via `$container->has()`.
- **Centralized per-node initialData injection** in `NodeRuntimeService::executeNode()` as the single canonical location, replacing 4 separate caller implementations.
- Replaced `\Drupal::entityTypeManager()` service locator calls with proper dependency injection in entity classes.
- Improved TypeScript type safety with proper interfaces for workflow editor mount options and lazy-loaded modules.
- Aligned `.info.yml` dependencies with actual code imports across 4 modules.
- Updated `@d34dman/flowdrop` JS library to 0.0.56.

### Deprecated

- `FlowDropPipeline::getReadyJobs()` — use `JobGenerationService::getReadyJobs()` instead. Will be removed in 1.0.0.

### Fixed

- **JS memory leaks and XSS vectors**: Added `Drupal.behaviors.*.detach()` for proper event listener cleanup, replaced `innerHTML` with DOM API construction, fixed race condition in initialization, and fixed DOM dataset deletion across all behavior scripts.
- Per-node initialData injection in `SynchronousOrchestrator` now correctly passes only the subset keyed by the current node's ID instead of the entire initialData array.
- Mixed variable types in `PromptTemplate` Twig context: array/object variables are now spread into context for direct key access while preserving backward compatibility.
- Circular dependency between `flowdrop_runtime` and `flowdrop_interrupt` by relocating `DrupalInterruptPersistence` and using optional service references.
- Integrity constraint violation during session entity migration.
- Replaced `->rowCount()` on raw queries with `SELECT COUNT(*)` for database compatibility.
- Missing `flowdrop_runtime` dependency declaration in `flowdrop_interrupt` module.
- Allow null for `playground_url` SDC prop in editor component.
- Added missing configuration schemas and default config for `flowdrop_runtime` and `flowdrop_playground` settings.

## [1.0.0-alpha2] - 2026-02-07

**Permission system overhaul: introduces granular ownership-based permissions across all modules.**

### Added

- **Granular own/any permissions for content entities**: All content entities now support ownership-based access control with `view own`, `view any`, `edit own`, `edit any`, `delete own`, and `delete any` permission variants.
  - `flowdrop_job`: Replaces flat `view/edit/delete flowdrop_job` permissions.
  - `flowdrop_pipeline`: Replaces flat `view/edit/delete flowdrop_pipeline` permissions.
  - `flowdrop_workflow_snapshot`: Replaces flat `view/edit/delete flowdrop_workflow_snapshot` permissions.
  - `state_checkpoint`: Replaces flat `view/edit/delete state_checkpoint` permissions.
  - `flowdrop_interrupt`: Replaces flat `view/resolve/cancel flowdrop interrupts` with own/any variants.
- **View permissions for config entities**: Non-admin users can now view config entities without full admin access.
  - `view flowdrop_workflow`: View workflows and their details.
  - `view flowdrop_node_type`: View node types and their details.
  - `view flowdrop_node_category`: View node categories.
- **New access control handlers**:
  - `FlowDropStateCheckpointAccessControlHandler` for `state_checkpoint` entities.
  - `FlowDropInterruptAccessControlHandler` for `flowdrop_interrupt` entities with custom `resolve` and `cancel` operations.
- **Entity-level access checks in InterruptApiController**: All interrupt API endpoints now enforce ownership-based access via `$entity->access()` checks.

### Changed

- **BREAKING**: Permission machine names changed for `flowdrop_job`, `flowdrop_pipeline`, `flowdrop_workflow_snapshot`, `state_checkpoint`, and `flowdrop_interrupt`. Flat permissions (e.g., `view flowdrop_job`) replaced with own/any variants (e.g., `view own flowdrop_job`, `view any flowdrop_job`). Reassign permissions after updating.
- **Standardized `administer flowdrop` super-admin bypass**: All access control handlers and custom access callbacks now check `administer flowdrop` as the first bypass, providing consistent super-admin access across all modules.
  - Updated: `FlowDropSessionAccessControlHandler`, `FlowDropSessionMessageAccessControlHandler`, `PlaygroundApiController`.
  - New handlers and rewritten handlers include it by default.
- All routing files updated to include `administer flowdrop` as an OR option alongside module-specific permissions.
- `flowdrop_interrupt` entity now uses a dedicated access control handler instead of the default `EntityAccessControlHandler`.

### Fixed

- Documentation link corrections.

## [1.0.0-alpha1] - 2026-02-07

**This is the first alpha release toward a stable 1.0. Breaking changes from 0.6.x are listed below.**

### Added

- **New `flowdrop_session` module**: Extracted session and message management from `flowdrop_playground` into a stable, standalone module. New entity types: `flowdrop_session`, `flowdrop_session_message`.
- **New `flowdrop_orchestration` module**: Extracted orchestrator contracts (interfaces, DTOs, plugin manager, helper) from `flowdrop_runtime` into a dedicated stable module.
- **New `PipelineExecutorInterface`**: Interface in `flowdrop_orchestration` for pipeline-based execution, replacing direct dependency on concrete `SynchronousPipelineOrchestrator`.
- **Categories API endpoint**: New `GET /api/flowdrop/categories` route serves category metadata (name, label, icon, color, description) for the workflow editor sidebar.
- **API stability annotations**: All classes annotated as `@internal` (no BC promise), `@experimental` (may change in minors), or stable (unmarked). See `docs/api/BC-POLICY.md`.
- **Backward compatibility policy**: Documented in `docs/api/BC-POLICY.md`.
- **Documentation overhaul**: Restructured docs with getting-started guides, user guides, per-module reference pages, and improved MkDocs navigation.

### Changed

- **BREAKING**: Drupal 10 support dropped. Minimum requirement is now `core_version_requirement: ^11.2` across all modules.
- **BREAKING**: `flowdrop_playground_session` entity type renamed to `flowdrop_session`.
- **BREAKING**: `flowdrop_playground_message` entity type renamed to `flowdrop_session_message`.
- **BREAKING**: Session-related service ID changed from `flowdrop_playground.service` to `flowdrop_session.service`.
- **BREAKING**: Orchestrator service IDs changed: `flowdrop_runtime.orchestrator_manager` is now `flowdrop_orchestration.plugin_manager`, `flowdrop_runtime.orchestrator_helper` is now `flowdrop_orchestration.helper`.
- **BREAKING**: `InterruptExceptionInterface` moved from `Drupal\flowdrop_runtime\Exception` to `Drupal\flowdrop_interrupt\Exception`.
- **BREAKING**: `InterruptPersistenceInterface` moved from `Drupal\flowdrop_runtime\Service\Interrupt` to `Drupal\flowdrop_interrupt\Service`.
- **BREAKING**: `InterruptState` DTO moved from `Drupal\flowdrop_runtime\Service\Interrupt` to `Drupal\flowdrop_interrupt\DTO`.
- **BREAKING**: `Orchestrator` attribute moved from `Drupal\flowdrop_runtime\Attribute` to `Drupal\flowdrop_orchestration\Attribute`.
- **BREAKING**: Orchestrator interfaces and DTOs moved from `Drupal\flowdrop_runtime` to `Drupal\flowdrop_orchestration` namespace.
- **BREAKING**: Session permission machine names changed from `flowdrop_playground_session` to `flowdrop_session` (e.g., `view any flowdrop_session`).
- Category color removed from node API responses; now served exclusively by the dedicated `/api/flowdrop/categories` endpoint.
- Editor configuration wired to fetch categories from the new categories endpoint.
- Experimental modules now use Drupal's `lifecycle: experimental` metadata consistently.
- Concrete cross-module class imports replaced with interface-based dependency injection.
- Module dependency graph cleaned up: all circular dependencies resolved.
- Session-aware `InterruptResolvedSubscriber` moved from `flowdrop_session` to `flowdrop_interrupt` (as `SessionInterruptResolvedSubscriber`) to eliminate circular dependency.
- Updated `@d34dman/flowdrop` JS library to 0.0.52.

### Fixed

- Circular dependency between `flowdrop_interrupt` and `flowdrop_playground` resolved via `flowdrop_session` extraction.
- Circular dependency between `flowdrop_runtime`, `flowdrop_interrupt`, and `flowdrop_session` resolved by removing unnecessary `flowdrop_runtime` and `flowdrop_interrupt` dependencies from `flowdrop_session`.
- `flowdrop_interrupt` no longer depends on `flowdrop_runtime` (was circular); now depends on `flowdrop_orchestration`.
- AorB node processor branches now correctly marked as `readOnly`.

## [0.6.0] - 2025-02-05

**BREAKING CHANGE: For users coming from 0.4.x or 0.5.x you would have to resave all your triggers.**

### Added

- **New Node Processors**
  - `Range` processor for generating numeric sequences
  - `Repeat` processor for duplicating values
  - `EntityQuery` processor for querying Drupal entities
  - `EntityContext` plugin for accessing entity data in workflows

- **Workflow Executor Module** (`flowdrop_workflow_executor`) - New submodule for workflow execution

- **Orchestration Improvements**
  - Refactored orchestration layer to allow swappable storage and re-usable code
  - `OrchestratorHelper` service for centralized orchestrator interactions
  - Namespacing support for `OrchestratorPluginManager`

- **UI Enhancements**
  - A better UX for selecting Node Processor Plugin (instead of select list).
  - Permission-based toolbar link visibility (#3571653)

- **Developer Experience**
  - Debug logging for interrupt node processors
  - Unhidden experimental sub-modules for user testing
  - Deriver support in plugin managers

### Changed

- **Design System**: Refactored to use design token-based system for flowdrop UI. You can update the look and feel of FlowDrop UI to match your brand/design (well almost).

### Fixed

- AJAX form callbacks not updating orchestrator and conditions subforms
- Chat outputs now display before checking for nested interrupts
- Session ID propagation to nested interrupt nodes
- Input node detection now uses instance ID instead of type ID
- Text and chat input node detection logic for playground
- Namespaced orchestrator IDs in connector and playground modules
- `PipelineExecutionForm` now uses namespaced orchestrator IDs
- Derivative plugin IDs handling in provider namespacing
- flowdrop JS library version number

### Performance

- Added cacheable responses to `NodesController` API endpoints

## [0.5.1] - 2025-01-27

### Added

- **Playground Enhancements**
  - Configurable auto-run setting for workflows
  - Chat input configuration support
  - Initial session support to auto-select most recent session
  - Display who resolved HIL (Human-in-the-Loop) prompts

### Changed

- **Dashboard Improvements**
  - Consolidated Structure section into Configuration section
  - Simplified main dashboard Configuration section layout

### Fixed

- PlaygroundService::createSession() now properly JSON-encodes metadata array (#3569982)

## [0.5.0] - 2025-01-26

### Added

- **Human-in-the-Loop (HIL)** interrupt system for workflows requiring user input
  - New `flowdrop_interrupt` module with `ConfirmationNode` and `ChoiceNode` processors
  - `interrupted` job status and `awaiting_input` workflow status
  - Playground UI support for handling HIL interrupts
- **Unified Ports** for simplified node data flow
  - Unified input/output port configuration on node types
  - Automatic decomposition of unified inputs with precedence rules
  - Automatic composition of unified outputs from exposed ports
- **Plugin ID Namespacing** - Plugin IDs now automatically prefixed with provider module (e.g., `flowdrop_node_processor:text_input`)
- Gateway mode support for `ConfirmationNode`
- `readOnly` attribute support in JSON Schema for non-editable exposed parameters
- `Entity Save` node processor for persisting entities
- Trigger output port added to all nodes by default

### Changed

- **BREAKING**: Plugin IDs are now namespaced as `{provider}:{id}`. Update hooks migrate existing configs automatically.
- Removed `ChatModel` from core FlowDrop (use `flowdrop_ai_provider` module instead)
- Improved playground UX: user messages display immediately with deferred processing

### Fixed

- Trigger manager WSOD when serializing
- Playground chat getting stuck after execution failure
- Loop iteration results now preserved when HIL interrupt occurs
- Plugin ID sanitization for valid machine name suggestions
- `text_output` renamed to `text` to avoid reserved name conflict
- Composer autoload dependency error (#3569610)

## [0.4.3] - 2025-01-17

### Fixed

- Triggers now properly load and execute orchestrators (stategraph, synchronous, asynchronous, etc.)
- Trigger config and general settings forms now dynamically load orchestrator options (StateGraph was missing from UI)
- Main FlowDrop settings form now dynamically loads orchestrator options

### Changed

- **BREAKING**: Refactored orchestrator system from tagged services to PHP 8 attribute-based plugin discovery
- Orchestrators are now discovered via `#[Orchestrator]` attribute in `Plugin/Orchestrator` directories
- TriggerConfigSchemaBuilder now dynamically builds orchestrator list from plugin manager

### Added

- `Orchestrator` attribute class for plugin discovery
- `OrchestratorPluginInterface` extending base `OrchestratorInterface` for backward compatibility
- `OrchestratorPluginBase` abstract class for easier orchestrator implementation
- Plugin wrappers for all existing orchestrators (synchronous, synchronous_pipeline, asynchronous, stategraph)

## [0.4.2] - 2025-01-17

### Added

- Optional icon picker for node category and node type forms with settings toggle
- Terminal node type added to visual types
- Sortable headers and pagination to all entity list builders
- Execution status column with standardized column order across list builders
- Job dependency navigator component with curved connectors

### Fixed

- Grid component slot rendering now accepts multiple child components
- Crashes when certain modules are not enabled
- Job data section now expanded by default

## [0.4.1] - 2025-01-16

### Fixed

- Form trigger now properly respects enabled/disabled configuration
- Wildcard pattern matching in trigger configuration now works correctly
- TriggerManager serialization fixed using DependencySerializationTrait

### Changed

- Trigger categories (form, entity, user) now default to disabled, requiring explicit opt-in

## [0.4.0] - 2025-01-15

### Added

- Visual Types configuration page accessible from FlowDrop dashboard

### Changed

- **BREAKING**: Removed `execute()` method from NodeProcessorInterface in favor of the clearer `process()` method
- Split EntityTrigger from base Trigger class for cleaner entity-specific trigger handling
- Converted node type form from AJAX-based to URL-based multi-step form for improved reliability
- Removed unnecessary drupalSettings injection from workflow editor

### Fixed

- Workflow editor no longer injects classes into body tag when in fullscreen mode
- Node type form now validates for duplicate machine names
- Node type form Save button now properly submits the form

## [0.3.0] - 2025-01-14

### Added

- New SDC components: editor, schema-form, pill, data-viewer, detail-grid, detail-section, progress-bar, job-list
- Enhanced pipeline detail page with progress bar, job list, and collapsible data sections
- Enhanced job detail page with parent/child node relationships and pipeline link
- Shared FlowDrop library for consistent component behavior

### Changed

- Refactored workflow editor to use SDC component
- Removed flowdrop_ui dependency, consolidated into flowdrop_ui_components

## [0.2.0] - 2025-01-12

### Added

- Event-driven trigger system for automatic workflow execution
- UI components module with reusable workflow editor components

### Changed

- Improved plugin architecture with unified parameter schema
- Enhanced module organization and dependency structure


## [0.1.0] - 2025-01-27

### Added

- Node processor plugin system with PHP 8 attribute-based discovery
- 25+ node processors including AI models, data operations, HTTP requests, and logic gates
- Runtime execution engine with synchronous and asynchronous orchestration modes
- Queue-based execution system for background workflow processing
- Job execution tracking and pipeline management modules
- Node category system for organizing node types

- Initial release of FlowDrop module

