Download the PHP package padosoft/laravel-flow without Composer

On this page you can find all versions of the php package padosoft/laravel-flow. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-flow

laravel-flow

Tests Latest Version PHP Version Laravel Version Total Downloads

DX-first workflow / saga / compensation engine for Laravel — with native dry-run, configurable compensation strategies, business-impact projection, opt-in persistence, and audit events. Built for Laravel teams that need dry-run, compensation, and persisted run telemetry inside the app they already operate.

laravel-flow is the third deliverable of the Padosoft v4.0 cycle (W5). It is a community Apache-2.0 package, standalone-agnostic (zero references to AskMyDocs / sister packages), and ships with the Padosoft AI vibe-coding pack so you can extend it with Claude Code or GitHub Copilot in minutes — not days.


Table of contents


Why this package

Laravel applications routinely need to orchestrate multi-step business workflows that mix:

The Laravel ecosystem has plenty of tools for some of these — Bus::chain() for sequence, jobs for async, transaction() for atomicity — but none of them ship with native dry-run, reverse-order saga compensation, and a single fluent surface that a junior dev can read in 30 seconds.

laravel-flow is that surface.

It is deliberately small. v0.1 is in-memory, synchronous, container-resolved. The current v0.2 foundation adds opt-in DB persistence for runs, steps, and audit rows plus queued dispatch, guarded retry metadata, database queue coverage, terminal-run replay, and opt-in parallel compensation for independent compensators. v0.3 has the approval pause primitive, hashed one-time approval-token issuance, persisted Flow::resume() / Flow::reject() APIs, CLI approvals, and signed webhook outbox delivery. The current v1.0 macro ships the package-side dashboard contracts (FlowDashboardReadModel read service, DashboardActionAuthorizer authorization hook with DenyAllAuthorizer default) so a separate companion app (padosoft-laravel-flow-dashboard, see docs/DASHBOARD_APP_SPEC.md) can build the operator UI on a stable headless surface.


Design rationale

Five non-negotiable choices that drove the API:

1. Dry-run is a first-class flag, not a convention

Every handler can declare ->withDryRun(true). When the engine runs in dry mode, it invokes dry-run-aware steps (so they can project impact) and skips the others, returning dry_run_skipped markers. There is no separate "preview" code path to maintain.

2. Compensation walks backwards by default

Saga semantics: when step N fails, the engine walks the previously-completed steps from N-1 back to 1, calling each registered FlowCompensator. There is no "compensate forward" or "best-effort cleanup" mode — predictable rollback every time.

When all compensators for a flow are independent and idempotent, set compensation_strategy=parallel to batch completed compensators through Laravel Concurrency. Reverse order stays the default because many saga rollbacks depend on undoing the newest side effect first. If the engine is constructed with an isolated/non-global container, or the configured Concurrency driver cannot run, parallel strategy falls back to in-process compensation through the injected container.

3. Handlers and compensators are container-resolved classes

step('persist', PersistPromotion::class) not step('persist', fn () => ...). Closures don't survive serialization (queued workers in v0.2), don't get DI, and don't surface in stack traces. Class-based handlers cost one extra file and pay back tenfold in observability.

4. The audit trail is event-driven

When audit_trail_enabled is enabled, normal-case step and compensation transitions dispatch the matching Laravel event, such as FlowStepStarted, FlowStepCompleted, FlowStepFailed, or FlowCompensated. When persistence is enabled, step events are dispatched only after the matching audit append succeeds, and compensation events are skipped if their audit append fails. The host application subscribes once and routes those events to the logger, DB, or metrics backend it already runs. Persisted flow_audit rows are written only for non-dry-run executions when both persistence and audit_trail_enabled are enabled. Dry-runs never write run, step, or audit rows.

5. Standalone-agnostic — zero AskMyDocs symbols

laravel-flow is a community package. It is not coupled to AskMyDocs, the sister patent-box-tracker, or any other Padosoft project. An architecture test enforces this on every CI run by walking src/ with RecursiveDirectoryIterator and asserting forbidden substrings never appear.


Features at a glance


Web admin UI

A full-featured web admin panel for laravel-flow is available at padosoft/laravel-flow-admin.


Comparison vs alternatives

Legend: ✅ YES means the capability is first-class in the current product, ⚠️ PARTIAL means it is possible but manual, narrower, or provided through a different model, and ❌ NO means it is not available today.

Feature laravel-flow Durable Workflow (Laravel) Symfony Workflow Temporal AWS Step Functions
Native dry-run with no persistence writes ✅ YES - first-class Flow::dryRun(); no run, step, audit, or compensator writes ❌ NO - not documented as a first-class mode ❌ NO - app must model preview behavior ❌ NO - app must model simulation separately ❌ NO - app must model simulation separately
Reverse-order saga compensation ✅ YES - built-in per-step compensateWith() with default reverse-order rollback and opt-in parallel batching for independent compensators ⚠️ PARTIAL - sagas/error handling are possible, but compensation policy is workflow-defined ⚠️ PARTIAL - manual transition/state design ⚠️ PARTIAL - compensation pattern via workflow code/SDKs ⚠️ PARTIAL - manual cleanup states via Catch
Approval gate as a step type ✅ YES - approvalGate($name) pauses and audits runs, issues hashed expiring token records, reissues a later paused gate token once when an older approved token retries, and per-run shared-lock-guarded Flow::resume() / Flow::reject() continue or compensate persisted runs; duplicate resumes return the current persisted running state instead of re-entering handlers; flow:approve and flow:reject CLI commands cover operator decisions ⚠️ PARTIAL - model manually as a long-running workflow/activity ⚠️ PARTIAL - guards can block transitions but are not resumable approval steps ⚠️ PARTIAL - signals/await patterns, not Laravel step gates ✅ YES - callback/task-token pattern
Signed webhook outbox delivery ✅ YES - flow_webhook_outbox rows for flow.paused/resumed/completed/failed written inside engine transactions; flow:deliver-webhooks signs payloads with HMAC-SHA256 in an X-Laravel-Flow-Signature: t=...,v1=... header, leases pending/stale rows with attempts compare-and-set guard, and reschedules transient failures with exponential backoff up to a configured max ❌ NO - not documented as built-in ❌ NO - not part of the workflow component ⚠️ PARTIAL - signed delivery via custom activities or external integration code, not first-class ⚠️ PARTIAL - integrate with EventBridge/SNS/Lambda; signing is consumer-side
Headless dashboard contracts ✅ YES - package-side FlowDashboardReadModel (paginated listRuns/findRun/listApprovals/listWebhookOutbox/kpis returning immutable DTOs) plus DashboardActionAuthorizer interface bound to DenyAllAuthorizer by default; companion app brief at docs/DASHBOARD_APP_SPEC.md keeps the package itself headless ❌ NO - no read-model contract; consume Eloquent records directly ❌ NO - app-defined, no read-model contract ✅ YES - first-class Temporal Web UI plus gRPC/REST APIs (managed dashboard, not a Composer-path-repo headless contract) ✅ YES - first-class AWS Console execution graph + history (managed dashboard, not a Composer-path-repo headless contract)
Web admin UI ✅ YES - companion admin panel available at padosoft/laravel-flow-admin for runs, approvals, failures, outbox, and operational KPIs ⚠️ PARTIAL - optional Waterline UI, tied to that package's durable workflow model ❌ NO - no bundled admin panel ✅ YES - Temporal Web UI for workflow executions and history ✅ YES - AWS Console for state-machine executions and history
@api/@internal source marking + contract-test pinning ✅ YES - every public class is annotated @api (SemVer-covered) or @internal (implementation detail); tests/Contract/PublicApiContractTest pins class names, public methods, and constants so a follow-up patch cannot silently rename or remove the v1.0 surface ❌ NO - no in-source visibility tags or contract-test pinning documented ⚠️ PARTIAL - Symfony framework uses @internal annotations selectively; no companion contract-test pinning ⚠️ PARTIAL - SDKs document stability but no Laravel-package-level contract test surface ⚠️ PARTIAL - service-level API stability via AWS SLAs, not in-source per-class markers
Migration guides from competitors ✅ YES - docs/MIGRATION_DURABLE.md (Temporal-style mapping with trade-off table), docs/MIGRATION_SYMFONY.md (state-machine to linear-flow mapping with event listener table), docs/UPGRADE.md (v0.1→v1.0 + SemVer policy) ❌ NO - not shipped ❌ NO - not shipped ⚠️ PARTIAL - upgrade docs between Temporal versions exist; no migration-from-competitors docs ❌ NO - AWS migration tooling targets services, not other workflow engines
Container-resolved PHP handlers ✅ YES - handlers and compensators resolve through Laravel's container ✅ YES - PHP workflow/activity classes ✅ YES - Symfony services/listeners ❌ NO - worker model is outside Laravel's container ❌ NO - Lambda/service fanout
Audit trail and event hooks ✅ YES - FlowStep* / FlowCompensated events plus optional flow_audit rows ⚠️ PARTIAL - status tracking and Laravel event integration ✅ YES - workflow events and optional audit trail ✅ YES - managed workflow event history ✅ YES - execution history plus CloudWatch/CloudTrail integrations
In-memory default with opt-in app DB persistence ✅ YES - memory by default; DB runs/steps/audit only when enabled ❌ NO - durable persistence is central to the engine ⚠️ PARTIAL - marking store is app-defined ❌ NO - dedicated Temporal service/cluster ❌ NO - managed AWS service
Redacted JSON persistence ✅ YES - configurable key redaction before run/step/audit payload storage ❌ NO - not documented as built-in ❌ NO - app-defined storage concern ⚠️ PARTIAL - custom payload codecs/converters, not Laravel key config ⚠️ PARTIAL - service-level data handling, not Laravel key config
Correlation and idempotency keys ✅ YES - first-class FlowExecutionOptions with length validation and persisted reuse ❌ NO - not documented as first-class execution metadata ❌ NO - app-defined ⚠️ PARTIAL - workflow/activity IDs and idempotency patterns ⚠️ PARTIAL - execution names/tokens, service-specific semantics
Successful-step output aggregation ✅ YES - persisted successful outputs rehydrate idempotent run reuse ⚠️ PARTIAL - workflow/activity outputs exist, but this package contract is not documented ❌ NO - app-defined ✅ YES - workflow history/result model ⚠️ PARTIAL - state input/output paths, not Laravel step result objects
Transaction-scoped transition writes ⚠️ PARTIAL - step transitions use repository transactions and atomic upserts; compensation audit/finalization can be separate writes ⚠️ PARTIAL - package/app persistence model ⚠️ PARTIAL - marking store/app transaction concern ✅ YES - managed event-history durability ✅ YES - managed execution-history durability
Runtime-abort recovery before surfacing infrastructure failures ✅ YES - best-effort failure state plus compensation before rethrow ⚠️ PARTIAL - retries/error handling, recovery policy is workflow-defined ⚠️ PARTIAL - app-defined ✅ YES - durable execution/retry recovery ⚠️ PARTIAL - Retry, Catch, and redrive behavior
Retention pruning for persisted telemetry ✅ YES - flow:prune keeps pending/running rows intact ❌ NO - not documented as built-in ❌ NO - app-defined ⚠️ PARTIAL - service retention configuration, not package command ⚠️ PARTIAL - managed history/log retention, not app command
Business-impact projection on every result ✅ YES - businessImpact is part of every FlowStepResult ❌ NO - not documented ❌ NO - not a workflow component concern ❌ NO - app-defined ❌ NO - app-defined
Queue-backed workers today ⚠️ PARTIAL - Flow::dispatch() queues an after-commit RunFlowJob with per-dispatch locking, configurable lock-held release delay, completed-duplicate no-op handling, guarded Laravel-native tries/backoff metadata, and sync/database queue coverage ✅ YES - Laravel queue/worker support ❌ NO - not native ✅ YES - worker-based execution ✅ YES - managed orchestration
Replay/redrive of failed executions today ⚠️ PARTIAL - flow:replay {runId} creates a new linked run from persisted terminal input and warns on definition drift; deterministic event-history replay is not shipped ⚠️ PARTIAL - durable long-running workflow model; exact replay semantics differ ❌ NO - not native ✅ YES - deterministic replay/event history ✅ YES - Standard Workflow redrive
Low setup friction ✅ YES - composer require plus optional config/migration publish ⚠️ PARTIAL - Laravel queues/workers and optional Waterline UI ✅ YES - Composer package and framework config ❌ NO - service/cluster plus workers ❌ NO - AWS account, IAM, state-machine definitions
Self-hosted with no external workflow service ✅ YES - runs inside the Laravel app; DB optional ✅ YES - Laravel app/queue infrastructure ✅ YES - application component ❌ NO - requires Temporal service/cluster ❌ NO - AWS-managed service
Open-source package/license ✅ YES - Apache-2.0 ✅ YES - MIT ✅ YES - MIT ✅ YES - MIT core/server and SDKs ❌ NO - proprietary managed service

Competitor snapshot checked against Durable Workflow, Symfony Workflow, Temporal, and AWS Step Functions documentation on 2026-05-05. laravel-flow is deliberately positioned as the lightest Laravel-native dependency in the table. If you already run Temporal or AWS Step Functions and need their queue/replay/redrive guarantees today, use them. If you want saga semantics, dry-run, business-impact projection, opt-in persistence, signed webhook delivery, headless dashboard contracts, and a companion web admin UI inside an existing Laravel app, this is the package.


Installation

Publish the config (optional — the engine works with defaults):

Publish the v0.2 persistence migrations only when you are opting into DB-backed storage:

The in-memory engine path still works without migrations. To persist runtime runs, enable LARAVEL_FLOW_PERSISTENCE_ENABLED=true; dry-runs remain simulation-only and do not write to the database.

Prune old terminal persistence records with the built-in retention command:

flow:prune deletes only terminal runs (succeeded, failed, compensated, aborted) with finished_at older than the cutoff. Matching flow_steps and flow_audit rows are deleted in the same batch transaction; running and pending rows are left untouched. Use LARAVEL_FLOW_RETENTION_DAYS=90 to make --days optional, and --force for non-interactive production runs.

Replay a terminal persisted run as a new linked run:

flow:replay reads the original persisted input and current registered definition, then creates a fresh persisted run with replayed_from_run_id pointing at the original. It does not mutate the original run and refuses to replay pending/running rows. If the stored step names/handlers differ from the current definition, the command warns and still uses the current definition. Redacted persisted input stays redacted during replay.

Requirements

  • PHP 8.3+
  • Laravel 13.x

Quick start


Usage examples

Correlation and idempotency

When persistence is enabled, correlationId and idempotencyKey are stored on flow_runs. Both values are trimmed, empty strings become null, and non-empty values are limited to 255 characters to match the published migrations. A later persisted execution with the same idempotency key returns the existing run state without executing handlers again. Dry-runs still avoid persistence writes.

Queue dispatch foundation

Flow::dispatch() validates the registered definition and required input before queuing RunFlowJob. The job dispatches after the current database transaction commits and takes a per-dispatch cache lock before execution; duplicate deliveries that find the lock held are released after the smaller of queue.lock_retry_seconds and queue.lock_seconds, while duplicates that arrive after the dispatch completed are acknowledged as no-ops. Configure queue.tries and queue.backoff_seconds to stamp Laravel-native retry metadata into the queued job payload for workers and Horizon. Because async Laravel workers retry the whole RunFlowJob from the beginning, policies that can re-run a flow are rejected until step-level retry semantics are available. The sync queue driver ignores worker retry metadata and remains allowed for local/test dispatches. The worker resolves the current FlowEngine and executes the same definition with the serialized input and execution options. Compensation still defaults to reverse-order rollback; set compensation_strategy=parallel only for flows whose compensators are independent and idempotent.

Approval gates

Approval resume/reject requires persistence and a shared cache store that supports Laravel atomic locks. Custom persistence backends must bind their approval backend to ApprovalRepository, implement ApprovalDecisionRepository on that approval backend for decided-token lookup, run-status-conditional consumes, and one-time pending-token reissue for downstream approval gates, return a ConditionalRunRepository from FlowStore::runs() for paused-run claims, keep the approval backend and FlowStore::runs() on the same durable storage boundary so conditional consumes and paused-run claims observe the same run state, and apply the package payload redactor consistently to approval decision JSON. Backends that delegate approval JSON redaction to laravel-flow can implement RedactorAwareApprovalRepository so Flow::resume() / Flow::reject() inject the same execution-frozen redactor used for step/run writes. The process-local array cache store is rejected for approval decisions because concurrent HTTP/API requests would not share the lock. The decision lock is keyed by run, so retries of older gate tokens serialize with a later gate resume on the same run. The plain token is returned only on the immediate paused run, while flow_approvals stores the current token hash, at most one previous hash for a reissued downstream-gate token, expiry, redacted decision payload, and redacted actor metadata. Custom approval repositories that support downstream token reissue must resolve both current and previous hashes in lookup, consume, and expiry paths so both handed-out tokens remain valid until expiry or decision. If a retry of an older approved token finds the run paused at a later approval gate, Laravel Flow can rotate that later gate's pending token hash once while it is still unexpired, keep the previous hash valid, refresh the paused-step expiry metadata, and return a fresh plain token on the current run. If the per-run lock is already held, old-token retries ask the caller to retry instead of returning a tokenless paused run or reissuing without owning the lock. Flow::resume() marks the approval gate succeeded and continues from the next unfinished step without rerunning prior or already-persisted downstream successes. If a duplicate resume sees that the run is already running, it returns the current persisted state instead of re-entering downstream handlers while another process may still own the side effect. Later steps receive the stored approval payload and stored approval actor metadata, so configured secret keys are redacted before handler context is reconstructed. Flow::reject() records the gate as failed and runs compensators for prior completed steps. Resume reconstructs context from persisted input and step outputs, so values redacted before storage remain redacted after resume.

Signed webhook outbox delivery

flow:deliver-webhooks processes pending rows from flow_webhook_outbox and sends signed HTTP POST payloads to laravel-flow.webhook.url. Each call can be retried with exponential backoff and a configurable attempt cap. Rows are marked delivered, pending (with a future available_at), or failed.

The command requires laravel-flow.webhook.enabled=true and a non-empty valid laravel-flow.webhook.url.

Compensation chain (saga rollback)

Dry-run / impact projection

Subscribing to the audit trail


Configuration reference

Key Default Effect
default_storage null DB connection used by persistence repositories. Inherits app default when null.
persistence.enabled false Enables synchronous engine writes to flow_runs and flow_steps; flow_audit writes also require audit_trail_enabled=true and a non-dry-run execution. Dry-runs do not write.
persistence.redaction common secrets Redacts configured JSON payload keys before run, step, and audit payloads are stored.
persistence.retention.days null Default retention window for php artisan flow:prune; pass --days to override per run.
queue.lock_store null Cache store used for queued run locks and approval resume/reject locks. When null, Flow::dispatch() captures the current cache.default store into the job; queued workers require a shared atomic lock store, while process-local array is accepted only with the sync queue driver. Approval resume/reject always rejects array.
queue.lock_seconds 3600 TTL for the per-dispatch queue lock used by RunFlowJob and the per-run approval decision lock used by Flow::resume() / Flow::reject(); set it longer than the expected maximum queued run or approval resume/reject runtime because Laravel's portable lock contract cannot renew it.
queue.lock_retry_seconds 30 Delay before a duplicate delivery retries when the per-dispatch lock is still held; the job caps it at queue.lock_seconds.
queue.tries null Optional Laravel job attempts value stamped onto RunFlowJob; null leaves the worker/connection default in control, while 0 preserves Laravel's unlimited-retry semantics. Async values that can retry the whole run are rejected until step-level retry or replay semantics are available.
queue.backoff_seconds null Optional Laravel job backoff value stamped onto RunFlowJob; use a single integer or comma-separated/list values such as 5,30,120. Async backoff schedules that can retry the whole run are rejected until step-level retry or replay semantics are available.
approval.token_ttl_minutes 1440 Expiry window for ApprovalTokenManager one-time tokens consumed by Flow::resume() / Flow::reject(). Only token hashes are stored in flow_approvals; the plain token is returned once from issuance.
webhook.enabled false Enables signed lifecycle delivery. Set true only when your app can reach the webhook URL from the command schedule or worker.
webhook.url '' URL endpoint receiving lifecycle event JSON from flow:deliver-webhooks; the command rejects empty or syntactically invalid URL values (HTTPS strongly recommended for production).
webhook.secret null Shared HMAC secret for signing X-Laravel-Flow-Signature: t=...,v1=... headers. Leave empty to disable signing.
webhook.retry_base_delay_seconds 30 Base delay (seconds) for exponential backoff between outbox retries.
webhook.max_attempts 3 Maximum delivery attempts before flow_webhook_outbox.status becomes failed.
webhook.timeout_seconds 5 Per-request delivery timeout in seconds (must be >=1).
audit_trail_enabled true When false, suppresses every FlowStep* / FlowCompensated event and persisted audit row; persisted audit rows also require persistence and a non-dry-run execution.
dry_run_default false When true, Flow::execute() behaves like dryRun() — guard rail for staging environments.
step_timeout_seconds 300 Reserved for follow-up queued step execution; the current RunFlowJob dispatch slice does not enforce per-step timeouts.
compensation_strategy reverse-order Supported values are reverse-order and parallel; use parallel only when completed compensators are independent, idempotent, and safe without reverse-order dependencies.
compensation_parallel_driver process Laravel Concurrency driver used only for compensation_strategy=parallel and only when the engine uses the global Laravel container; set sync for deterministic local/tests or process/fork for actual parallelism when your app supports it. If the driver cannot be resolved or run, the engine falls back to injected-container in-process compensation.

When persistence is enabled, synchronous FlowStep* listener or persistence failures are rethrown after the engine records best-effort recovery state and compensates completed steps. FlowCompensated listener failures are swallowed after the compensation audit row is durable so rollback is not interrupted. Wrap Flow::execute() in application-level exception handling anywhere infrastructure outages must be surfaced separately from business step failures.

Custom FlowStore implementations that need the same per-execution PayloadRedactor used by engine error-text sanitization should implement Padosoft\LaravelFlow\Contracts\RedactorAwareFlowStore. The engine calls withPayloadRedactor() once per persisted execution before writing run, step, and audit telemetry; implementations that keep transaction state on the store should return the same instance or a state-sharing decorator. PayloadRedactor decorators that wrap the package execution-scoped redactor should implement Padosoft\LaravelFlow\Contracts\CurrentPayloadRedactorProvider so multi-field repository writes can reuse one stable inner redactor without changing each JSON payload shape.


Architecture

Every box is one PHP class under src/. The engine path is still synchronous and in-memory by default; when persistence is enabled, runtime runs and steps are written to flow_runs and flow_steps for non-dry-run executions. Audit transitions are written to flow_audit only for non-dry-run executions while persistence and audit_trail_enabled are both enabled. Dry-runs never write audit rows. Flow::dispatch() queues an after-commit RunFlowJob with per-dispatch locking, database queue coverage, and guarded Laravel retry/backoff metadata. flow:replay creates new linked runs from terminal persisted input, and compensation_strategy=parallel batches independent compensators through Laravel Concurrency.

Public API surface (v1.0)

The package marks every class with @api (stable, SemVer-covered) or @internal (implementation detail, not covered by SemVer). Public surface:

The tests/Contract/PublicApiContractTest testsuite pins the v1.0 surface so a follow-up patch cannot silently rename or remove an @api class, method, or constant. Internal namespaces (Persistence, Models, Queue, Jobs, Console) may change in any minor release; route consumers through the public contracts instead. See docs/UPGRADE.md for the full SemVer policy and upgrade chain.

Companion dashboard

The package itself is headless — there is no embedded UI. The companion app padosoft/padosoft-laravel-flow-dashboard (separate repo) consumes the dashboard contracts via Composer path repository during development and from Packagist in production. The complete brief for an AI agent or human team building that app is at docs/DASHBOARD_APP_SPEC.md.


AI vibe-coding pack

🚀 Every Padosoft package ships with the same vibe-coding pack — drop the .claude/ directory into Claude Code or GitHub Copilot and you get:

The pack is the same baseline used across all padosoft/* repos. It is opt-in: delete .claude/ if you don't use Claude Code or Copilot — nothing else depends on it.


Testing — Default + Live

The default phpunit invocation runs only the offline Unit + Architecture testsuites and never makes a network call:

The Live testsuite is opt-in and reserved for v0.2+ scenarios that need a real external dependency (queue worker, webhook receiver). Every Live test self-skips unless LARAVEL_FLOW_LIVE=1 is set:

CI runs Pint (style), PHPStan (level 6), and the Unit + Architecture suites through Composer scripts on the PHP 8.3 / 8.4 × Laravel 13 matrix for pushes to main and PRs targeting main or task/**. PHP 8.5 is intentionally not a hard gate until Laravel/Testbench dependency support is reliable enough for this package.


Roadmap

Version Scope Target
v0.1 In-memory engine, fluent builder, dry-run, reverse-order compensation, four audit event classes, business-impact field on results, Facade. Architecture test enforces standalone-agnostic. code complete
v0.2 Persistence core: flow_runs / flow_steps / flow_audit tables, synchronous engine writes, redacted payload storage, correlation/idempotency keys, terminal-run retention pruning, queued dispatch foundation with per-dispatch locking, database queue coverage, guarded Laravel-native retry/backoff metadata, flow:replay for terminal persisted runs, and opt-in parallel compensation for independent compensators. Q3 2026
v0.3 Approval-gate primitive, hashed one-time approval-token issuance, persisted API flow resume/reject controls, CLI approval commands, and signed webhook outbox delivery now landed (flow:approve, flow:reject, flow:deliver-webhooks included). Q4 2026
v1.0 Package-side dashboard contracts (FlowDashboardReadModel, DashboardActionAuthorizer, DenyAllAuthorizer default), stable API marking, semver guarantee, migration helpers from Durable Workflow / Symfony Workflow, and companion app spec at docs/DASHBOARD_APP_SPEC.md. 2027

Contributing

See CONTRIBUTING.md. Community PRs target main; enterprise roadmap work uses the macro/subtask PR loop documented in AGENTS.md.


Security

Report vulnerabilities privately to [email protected] per SECURITY.md. Operational guarantees the package enforces:

Enterprise notes

The package is designed to live inside a Laravel application's process and database, not in a separate workflow service. That keeps the operational footprint small (no dedicated workflow cluster) at the cost of cross-language workflows and managed multi-region failover. If you need either, evaluate a managed durable-workflow runtime instead — see docs/MIGRATION_DURABLE.md for the trade-off table.

For teams adopting laravel-flow:


License

Apache-2.0.

Built by Padosoft — part of the v4.0 ecosystem.


All versions of laravel-flow with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
illuminate/cache Version ^13.0
illuminate/console Version ^13.0
illuminate/contracts Version ^13.0
illuminate/database Version ^13.0
illuminate/queue Version ^13.0
illuminate/support Version ^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package padosoft/laravel-flow contains the following files

Loading the files please wait ...