FlowDrop Backward Compatibility Policy¶
This document defines the backward compatibility (BC) policy for FlowDrop starting with version 1.0.0. FlowDrop follows pragmatic semantic versioning (semver), meaning:
- Patch releases (1.0.x): Bug fixes only. No BC breaks.
- Minor releases (1.x.0): New features, deprecations. No BC breaks to stable API.
- Major releases (x.0.0): May contain BC breaks with migration path documented.
API Classification¶
Every PHP class and interface in FlowDrop falls into one of two categories, indicated by PHPDoc annotations. Every class must carry exactly one of @api or @internal.
@api¶
Classes and interfaces marked @api are the stable public API. They follow strict semver:
- Method signatures will not change in the 1.x release line.
- New optional parameters may be added.
- New methods may be added to classes (but not to interfaces without a deprecation cycle).
- Removal or renaming requires a major version bump with deprecation in the prior minor.
The stable API includes the FlowDropNodeProcessor plugin system — the classes that external modules use to create custom node types:
- Plugin discovery:
FlowDropNodeProcessorattribute,FlowDropNodeProcessorPluginManager - Plugin contracts:
FlowDropNodeProcessorInterface,AbstractFlowDropNodeProcessor,NodeExecutorInterface,ConfigEditProviderInterface,ExecutionContextAwareInterface,TriggerNodeProcessorInterface - Lifecycle opt-ins (1.4.0+):
CancellableNodeProcessorInterface,ResumableNodeProcessorInterface - Parameter system:
ParameterBag,ParameterBagInterface - Data/Output:
Data,DataInterface,Output,OutputInterface - Validation:
ValidationResult,ValidationError,ValidationWarning - Execution context:
ExecutionContextDTO - Node metadata:
NodeMetadata,NodeMetadataBuilder,NodePort - Config editing:
ConfigEdit,DynamicSchemaEndpoint,ExternalEditLink,ConfigEditApiEndpoints
The Orchestrator plugin system is part of the stable API — the classes that external modules use to create custom workflow execution strategies:
- Plugin discovery:
Orchestratorattribute - Plugin contracts:
OrchestratorPluginInterface,OrchestratorPluginBase,OrchestratorInterface - Interrupt contracts:
InterruptExceptionInterface,FlowDropInterruptException
The Trigger system and Workflow Executor APIs are stable:
- Trigger contracts:
TriggerManagerInterface,FlowDropTriggerConfigInterface,FlowDropEventTypeInterface - Workflow executor contracts:
WorkflowExecutionServiceInterface,WorkflowExecutionMode,WorkflowExecutionStatus
The StateGraph, Interrupt, and supporting APIs are also stable:
- StateGraph contracts:
StateManagerInterface,CheckpointerInterface,ApprovalGateInterface,StateAwareProcessorInterface,ReducerInterface,IteratorHelperInterface - StateGraph data:
GraphState,StateUpdate,Checkpoint,ApprovalStatus - StateGraph exceptions:
MaxIterationsException,StateValidationException,CheckpointException,IteratorExhaustedException - Interrupt contracts:
InterruptManagerInterface,InterruptPersistenceInterface - Interrupt data:
InterruptState,InterruptType - Interrupt message bus (1.4.0+):
InterruptMessageInterface,AbstractInterruptMessage,HitlInterruptMessage,LinkedInterruptMessage,InwardSignalMessage. The concrete shapes are the DTOs a node processor throws viaInterruptRequiredException; the bus and handler registry (InterruptMessageBusInterface,InterruptFactoryInterface,InterruptCreationData) are part of the stable surface too.
The Pipeline runtime contract is stable (1.4.0+):
- Runtime contract:
FlowDropPipelineRuntimeInterface— the narrow runtime view of a pipeline used by the storage layer, orchestrators, events, and queue workers. The fullFlowDropPipelineInterface(entity-shaped) is@internal; type-hint the runtime interface in code that does not need entity-level access.
The FlowDropSchema form builder is stable (1.4.0+):
- Form builder contract:
FlowDropSchemaFormBuilderInterface— renders Drupal form arrays from FlowDropSchema fragments. FlowDropSchema is a documented subset of JSON Schema; see FlowDropSchema for the supported keyword set. The concreteFlowDropSchemaFormBuilderimplementation is@internal.
@internal¶
Classes marked @internal are implementation details with no BC promise:
- May change, move, or be removed in any release (including patches) without notice.
- Should not be extended, instantiated, or type-hinted against by external code.
- Typically also marked
finalto prevent extension.
This includes all classes outside the @api surface: entity classes and interfaces, controllers, forms, list builders, hook implementations, concrete service implementations, storage classes, DTOs, exception classes, orchestrator plugins, and queue workers.
HTTP API Stability¶
FlowDrop's HTTP endpoints under /api/* (defined by *ApiController classes — pipeline, playground, interrupt, job, trigger, snapshot, chat) are @internal. They exist to serve the bundled @flowdrop/flowdrop JavaScript library (the FlowDrop Editor and Playground components) and are not a public REST contract.
- Endpoint paths, query parameters, request bodies, and response shapes may change between any two FlowDrop releases — including minor releases — without a deprecation cycle.
- The HTTP layer ships in lock-step with the bundled JS library; consumers should use the matching JS library version rather than calling endpoints directly.
- The OpenAPI document at
docs/development/api/openapi.yamldescribes the current shape for reference only and is not a stability promise.
Why these endpoints can't be a stable contract¶
The HTTP layer is the interop boundary between the Drupal backend and the FlowDrop Editor / Playground JS components. Both halves are versioned together and ship from this repository as a single unit, and the wire format is dictated by what the editor of a given version needs to render and operate on. That coupling is structural, not a temporary state we plan to grow out of:
- Editor features extend the wire shape. Every editor capability that surfaces backend state — new node-type metadata, port typing, visual hints, execution telemetry, interrupt shapes — adds or restructures fields on the response. The 1.4 series added typed I/O ports, schema snapshots, lifecycle events, pipeline bundles, linked interrupts, and a HITL inbox; each of those reshaped at least one endpoint to carry the new state. Holding the wire format frozen would either freeze editor evolution or force every new field through a parallel side-channel, both of which we'd reject in review.
- The Drupal module and the editor are released together. A given Drupal site runs the JS library bundled in the matching FlowDrop module version. Within a single deployment there is exactly one client and exactly one server, and they're version-matched by construction. The classic motivation for a stable REST contract — independently deployed clients you cannot coordinate with — does not apply.
- Versioning the URL would not buy stability, only duplication. A
/api/v1//api/v2scheme would require us to maintain both shapes in the same Drupal release, which means twice the controller code, twice the surface area for security review, and a forced freeze on whichever version is declared "stable." Given (2), the result is cost without a corresponding consumer. - This matches Drupal core's posture. The internal AJAX, layout-builder, big-pipe, and CKEditor endpoints that core uses to power its admin UI are not part of core's BC promise either, for the same structural reason: they're a private interop layer between core PHP and core JS, not a public REST API.
If you need a stable programmatic interface, type-hint against the @api PHP classes listed above (the FlowDropNodeProcessor, Orchestrator, Trigger, Workflow Executor, and StateGraph contracts) rather than the HTTP endpoints. For an integration that genuinely needs to be an HTTP client of FlowDrop independent of the bundled editor, open an issue describing the use case so we can decide whether to expose a separate, deliberately-stable surface for it.
Configuration Schema¶
Configuration schemas (.schema.yml) follow these rules in 1.x:
- Existing config keys will not be removed or renamed.
- New keys may be added with sensible defaults.
- Schema changes are additive-only.
- Config export/import compatibility is maintained within the 1.x line.
Entity Type Stability¶
Entity type IDs and their base field definitions are stable in 1.x:
- Entity type machine names will not change.
- Base fields will not be removed (new fields may be added via update hooks).
- Storage schema changes will always include update hooks.
Plugin System Stability¶
Two plugin types are stable in 1.x:
FlowDropNodeProcessor — for creating custom node types:
- The
FlowDropNodeProcessorattribute andFlowDropNodeProcessorInterfacewill remain backward compatible. - Plugin discovery mechanisms will not change.
Orchestrator — for creating custom workflow execution strategies:
- The
Orchestratorattribute,OrchestratorPluginInterface, andOrchestratorPluginBasewill remain backward compatible. - The interrupt contracts (
InterruptExceptionInterface,FlowDropInterruptException) will remain backward compatible. - Concrete orchestrator implementations (e.g.,
SynchronousOrchestratorPlugin) are@internaland not covered by BC guarantees.
New plugin types may be added in minor releases but are not covered by BC guarantees until marked @api.
Drupal Version Support¶
FlowDrop 1.x requires Drupal ^11.2. Drupal 10 is not supported.
Reporting BC Breaks¶
If you believe a release introduced an unintended BC break to stable API, please report it in the FlowDrop issue queue on Drupal.org. Unintended BC breaks to stable API will be treated as bugs and fixed in a patch release.