You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dispatch lifecycle events when embedded runs are cancelled or terminated #896
An embedded Laravel app can't react when a run is cancelled or terminated. Apps that listen to lifecycle events to release external resources, update their own records or alert someone never learn that the run ended.
The engine has workflow events only for started, completed and failed runs. The dispatcher has nothing for the other two terminal statuses. The V1-compatible StateChanged event has no cancelled or terminated states either.
A timed-out run does dispatch WorkflowFailed, so two of the four terminal outcomes are silent.
Terminate runs no workflow code, so an event is the only in-process hook for cleanup after it. The events guide lists only Started, Completed and Failed, and doesn't say that other outcomes are silent.
Reproduced on published Workflow 2.14.2 (d60ce5f6): all three real terminal paths close successfully but emit zero application notifications; the existing completion event passes in the same app. Runtime evidence. Resolved in published Workflow 2.15.0. Normal installed-consumer acceptance and all eight live event/installation guides are verified; final evidence. Broader engine/storage atomicity remains tracked separately in #893.
Acceptance criteria
Embedded runs dispatch WorkflowCancelled and WorkflowTerminated events when they close by immediate cancel, cooperative cancellation or terminate. Each event carries the same identity fields as the existing workflow events, plus the command reason and the time the run closed.
The events follow the commit-ordering rules that workflow#893 sets for the existing events.
The lifecycle event tests cover cancel, cooperative cancellation and terminate, and show that a rejected command dispatches nothing.
The events guide lists the new events, adds cancelled and terminated lifecycle examples, and says which event a timed-out run produces.
Accepted as a product fix. Before implementation, reproduce immediate cancellation, cooperative cancellation and termination on a real embedded run and assert the currently missing Laravel events. Add WorkflowCancelled and WorkflowTerminated with the existing lifecycle identity, reason and close time, following the storage-connection/after-commit contract in #893. Rejected or rolled-back commands must dispatch nothing. The events are application notifications, not authority to resume a terminal workflow or a guarantee of durable delivery to an external system.
The events guide and all seven translations must cover both events and retain the timed-out → WorkflowFailed distinction. P3 source finding remains unconfirmed by runtime reproduction. General owns it after the active P0 security image delivery and the existing higher-priority release obligations.
Published-package reproduction confirms #896 on Workflow 2.14.2, exact Composer reference d60ce5f60e70b834c5d4ef142c3d5dc415cd39fe, with PHP8.3.36, Laravel13.38.0, Testbench11.3.0 and PHPUnit12.5.40. Normal registry install; no path repository, source override or vendor patch.
Four embedded consumer cases completed in1.642s: 29 assertions, three expected failures, one passing control, zero errors.
Immediate cancel: a genuinely executed/waiting run accepts the command, becomes cancelled, has closed_at and exactly one durable WorkflowCancelled history event, but emits zero Laravel WorkflowCancelled events.
Cooperative cancellation: the real RunWorkflowTask resumes cancellation, executes the workflow's finally cleanup (persisted memo verified), closes cancelled and records exactly one terminal history event, but emits zero matching application events.
Terminate: a genuinely executed/waiting run accepts termination, becomes terminated, has closed_at and exactly one durable WorkflowTerminated history event, but emits zero matching application events.
Control: the same app/listener setup executes a real completing workflow and receives exactly one existing WorkflowCompleted event with the correct run identity.
Only queue transport is faked; engine commands, task jobs, workflow code and SQLite persistence are real. Every failure is the final assertion expecting one application notification and observing zero. The three cases assert the installed version/reference before execution.
This upgrades the report from source-only to runtime-reproduced. Source implementation remains pending the current owner's acknowledged handoff. The #893 storage-connection/after-commit requirement remains part of acceptance, and the broader storage defect is not claimed fixed by this reproduction. Existing cancelled/terminated history and workflow cleanup behavior are preserved.
The published 2.14.2 reproduction is accepted, and implementation ownership is handed off through source, tests, documentation, qualified ordinary release and actual installed acceptance. The reproduction distinguishes the three missing-event cases from the passing completion control.
Next: dispatch cancelled/terminated events for immediate cancel, cooperative cancellation and terminate, using the run's storage-connection commit boundary. Include rollback, rejected-command and cooperative-finally controls. Keep #893's broader existing-event/storage correction explicit unless the necessary shared change also completes it with qualification. Server #784's independent adoption remains pinned to published 2.14.2 while qualifying.
Security reachability disposition — published 2.14.2 defect
The missing embedded Laravel notifications are real, but current first-party source does not use them as an authorization, revocation or cleanup boundary. Cloud, Server and Sample App register no WorkflowCancelled/WorkflowTerminated Laravel listeners. Cloud cancellation and termination API audit records are written directly after successful server responses, and its backup/runtime cleanup paths use workflow finally blocks, explicit native revocation, deadlines and reconciliation rather than these application events. The current production inventory has no external customer runtime.
Treat #896 as an ordinary released-product correctness fix, not a confirmed security incident or emergency hotfix. Implementation and qualification should continue with no Security wait. The commit-boundary, rollback/rejection and cooperative-finally controls already in acceptance remain important because future downstream consumers may use these notifications for resource cleanup; a material change that makes an event authoritative for access or revocation would require a new security review.
Source draft #946 implements the two missing lifecycle events at 307661c, tree 2089638de54045e4fe8c3745b7d36f027619e300.
The events carry run identity, the original nullable command reason and the persisted UTC close time. Immediate cancellation, cooperative cleanup and cleanup expiry emit WorkflowCancelled; termination emits WorkflowTerminated; ordinary run timeout still emits WorkflowFailed. Notifications wait for the actual run model's storage connection. Rejected commands and rolled-back storage writes emit none. The broader engine transaction defect #893 remains open.
Validation completed: published2.14.2 reproduction with three missing-event failures and a passing completion control; 28 regression tests /239 assertions; full ECS and PHPStan. Tests cover explicit default/separate storage transactions, a custom model connection, cooperative finally rollback/retry, deadline expiry, ordinary timeout, rejection and the existing collector/retry controls. Full unit, coverage and feature qualification remain incomplete.
Boundary, Sonar and CodeQL checks pass. Build40393156642 failed the replay-evidence preflight because WorkflowExecutor changed while its corpus stayed at79 cases. Next: add the required append-only regression evidence and qualify the same PR. English plus all seven translated guides, a qualified release, normal installed-consumer acceptance and published-documentation verification remain outstanding. Current published2.14.2 is unchanged; #896 stays open through delivery.
Immediate cancellation, cooperative cancellation after cleanup, and termination now prepare the corresponding Laravel lifecycle notification with the original command reason and persisted UTC close time. The notification follows the actual run-storage transaction; rejected commands and storage rollback emit none. The broader transaction/storage work in #893 remains separate.
Verified:
Lifecycle and existing collector tests: 28 tests / 239 assertions.
New PHP replay/live cleanup cases: 2 tests / 70 assertions. The unmodified strict validator passes with replay evidence growing 79 → 80, including the required base-fails/current-passes check.
Full coding style across 1,543 PHP files, static analysis, Composer validation and complete feature-shard inventories pass.
English and all seven translated event guides build successfully; the new sections, payload examples and canonical/language links were checked in all eight rendered pages and their version redirects.
The corrected full unit run is still in progress. Full coverage/feature qualification, the ordinary 2.15.0 release, a normally installed consumer and publication of the guides remain open. The release metadata is prepared; no tag, package or guide has been published for this change.
Source merged through PR #946 at e6a8fb8e3a5d9a79d4744bb650d57dc47dd6db6c. The signed merge has the identical reviewed tree 70b4a8d2b55b6698bb816e732b58b6d2131d35fa.
The final PR build passed, including the strict replay counterfactual and MySQL feature controls. Sonar reports zero new issues and zero security hotspots. The complete local composer unit command exits 0: 5,036 tests / 72,018 assertions, with 43 skips and 15 non-failing PHPUnit notices, in 20m15s. No assertions, deadlines or coverage thresholds were weakened.
The independent main build is running the full coverage, MySQL/PostgreSQL feature shards, MariaDB control and supported Laravel upgrade journeys. Release 2.15.0 remains unpublished until qualification completes.
The eight-language guide change has passed the normal full build and rendered-page/locale-link checks. After the package is actually published and normally installed acceptance passes, advance the documentation's shared Workflow install pin to that qualified version, rebuild, publish and verify the live guide. The existing consumer still has unmodified published 2.14.2 installed; the final acceptance test is prepared but has not yet run against 2.15.0. This issue remains open through that delivery; #893 remains separate.
Released and installed acceptance is complete for Workflow 2.15.0, source e6a8fb8e3a5d9a79d4744bb650d57dc47dd6db6c. The annotated tag, Packagist source and Packagist dist all resolve to that qualified merge.
The complete main qualification passes: combined coverage, all MySQL/PostgreSQL feature shards, MariaDB control, supported Laravel source upgrades and Sonar.
The exact local composer coverage command also passes its separate unchanged 60% unit-only floor at 77.11% (58,792/76,244 lines): 5,036 tests / 72,017 assertions, 43 skips and 15 non-failing PHPUnit notices. The earlier plain unit command passed 5,036 tests / 72,018 assertions.
Published Release Verification passes the package contract and all 16 Laravel/PHP published upgrade journeys. An additional normal Composer registry installation passes the public manifest, retained history-schema byte identity and 13 protocol resolver checks.
The original consumer upgraded through Composer from 2.14.2 to 2.15.0, changing only that package. Actual installed source/dist references match the release; 23 tests / 229 assertions pass for real terminal notifications, cleanup, rejection, storage commit/rollback, custom model connections and installed vendor identity.
The remaining acceptance is live documentation delivery in website PR #408: all eight event guides plus the shared qualified 2.15.0 install pin. The final eight-locale rebuild and hosted documentation qualification are running. This issue stays open through deployment and verification of the actual public pages. Broader #893 work remains separate.
Delivered and verified in Workflow 2.15.0, published October 26, 2026 at 22:00 UTC. The immutable release resolves to e6a8fb8e3a5d9a79d4744bb650d57dc47dd6db6c; normal Packagist source and distribution references agree.
WorkflowCancelled and WorkflowTerminated now describe actual durable closes, including cooperative cleanup completion and expiry. They carry the existing identity fields, the original nullable reason and persisted UTC closedAt. Rejected commands, cancellation requests without a close, and storage rollbacks emit neither event. Dispatch waits for the actual run storage connection to commit. Delivery remains in process; the broader engine/storage transaction work in #893 remains separate.
Verification completed:
The original consumer upgraded through normal Composer from 2.14.2 to 2.15.0, changing only that package. Installed acceptance passed 23 tests / 229 assertions, including real terminal paths, cleanup, rejection, default/secondary/custom-model storage, commit/rollback and published-version/reference/vendor-path guards.
Independent source qualification passed, including MySQL/PostgreSQL shards, MariaDB and Laravel upgrades. Exact local composer coverage passed 5,036 tests / 72,017 assertions, with 77.11% unit line coverage against the unchanged 60% floor; 43 skips and 15 non-failing PHPUnit notices remain recorded. The 100% target is not reached.
Actual canonical public reads passed for all eight event guides, eight installation pages and eight version aliases, including reviewed localized prose, event anchors/fields, canonical/language links and the rendered Composer 2.15.0 command. The shared installation manifest matches the qualified source exactly; its SHA256 is 85787d74d0aca89e9ba88c7c560d2e7aed3d43d164a3cc13db6991032a927e78.
The live events guide documents cancellation, termination, normal timeout failure, cleanup deadlines and the commit/delivery limits. Package and published-documentation acceptance are complete.
Published-package and all eight live documentation locales are accepted; final evidence is in comment 6429074557. Completed task worktrees, branches, build/test dependencies, raw reports and disposable resources are cleaned. Closing as completed in Workflow 2.15.0.
Activity
rmcdaniel commentedon Oct 21, 2026
Accepted as a product fix. Before implementation, reproduce immediate cancellation, cooperative cancellation and termination on a real embedded run and assert the currently missing Laravel events. Add
WorkflowCancelledandWorkflowTerminatedwith the existing lifecycle identity, reason and close time, following the storage-connection/after-commit contract in #893. Rejected or rolled-back commands must dispatch nothing. The events are application notifications, not authority to resume a terminal workflow or a guarantee of durable delivery to an external system.The events guide and all seven translations must cover both events and retain the timed-out →
WorkflowFaileddistinction. P3 source finding remains unconfirmed by runtime reproduction. General owns it after the active P0 security image delivery and the existing higher-priority release obligations.rmcdaniel commentedon Oct 26, 2026
Published-package reproduction confirms #896 on Workflow 2.14.2, exact Composer reference
d60ce5f60e70b834c5d4ef142c3d5dc415cd39fe, with PHP8.3.36, Laravel13.38.0, Testbench11.3.0 and PHPUnit12.5.40. Normal registry install; no path repository, source override or vendor patch.Four embedded consumer cases completed in1.642s: 29 assertions, three expected failures, one passing control, zero errors.
Only queue transport is faked; engine commands, task jobs, workflow code and SQLite persistence are real. Every failure is the final assertion expecting one application notification and observing zero. The three cases assert the installed version/reference before execution.
This upgrades the report from source-only to runtime-reproduced. Source implementation remains pending the current owner's acknowledged handoff. The #893 storage-connection/after-commit requirement remains part of acceptance, and the broader storage defect is not claimed fixed by this reproduction. Existing cancelled/terminated history and workflow cleanup behavior are preserved.
rmcdaniel commentedon Oct 26, 2026
The published 2.14.2 reproduction is accepted, and implementation ownership is handed off through source, tests, documentation, qualified ordinary release and actual installed acceptance. The reproduction distinguishes the three missing-event cases from the passing completion control.
Next: dispatch cancelled/terminated events for immediate cancel, cooperative cancellation and terminate, using the run's storage-connection commit boundary. Include rollback, rejected-command and cooperative-finally controls. Keep #893's broader existing-event/storage correction explicit unless the necessary shared change also completes it with qualification. Server #784's independent adoption remains pinned to published 2.14.2 while qualifying.
rmcdaniel commentedon Oct 26, 2026
Security reachability disposition — published 2.14.2 defect
The missing embedded Laravel notifications are real, but current first-party source does not use them as an authorization, revocation or cleanup boundary. Cloud, Server and Sample App register no WorkflowCancelled/WorkflowTerminated Laravel listeners. Cloud cancellation and termination API audit records are written directly after successful server responses, and its backup/runtime cleanup paths use workflow finally blocks, explicit native revocation, deadlines and reconciliation rather than these application events. The current production inventory has no external customer runtime.
Treat #896 as an ordinary released-product correctness fix, not a confirmed security incident or emergency hotfix. Implementation and qualification should continue with no Security wait. The commit-boundary, rollback/rejection and cooperative-finally controls already in acceptance remain important because future downstream consumers may use these notifications for resource cleanup; a material change that makes an event authoritative for access or revocation would require a new security review.
rmcdaniel commentedon Oct 26, 2026
Source draft #946 implements the two missing lifecycle events at 307661c, tree 2089638de54045e4fe8c3745b7d36f027619e300.
The events carry run identity, the original nullable command reason and the persisted UTC close time. Immediate cancellation, cooperative cleanup and cleanup expiry emit
WorkflowCancelled; termination emitsWorkflowTerminated; ordinary run timeout still emitsWorkflowFailed. Notifications wait for the actual run model's storage connection. Rejected commands and rolled-back storage writes emit none. The broader engine transaction defect #893 remains open.Validation completed: published2.14.2 reproduction with three missing-event failures and a passing completion control; 28 regression tests /239 assertions; full ECS and PHPStan. Tests cover explicit default/separate storage transactions, a custom model connection, cooperative finally rollback/retry, deadline expiry, ordinary timeout, rejection and the existing collector/retry controls. Full unit, coverage and feature qualification remain incomplete.
Boundary, Sonar and CodeQL checks pass. Build40393156642 failed the replay-evidence preflight because
WorkflowExecutorchanged while its corpus stayed at79 cases. Next: add the required append-only regression evidence and qualify the same PR. English plus all seven translated guides, a qualified release, normal installed-consumer acceptance and published-documentation verification remain outstanding. Current published2.14.2 is unchanged; #896 stays open through delivery.rmcdaniel commentedon Oct 26, 2026
Draft implementation: PR #946, head
3535d6bd.Immediate cancellation, cooperative cancellation after cleanup, and termination now prepare the corresponding Laravel lifecycle notification with the original command reason and persisted UTC close time. The notification follows the actual run-storage transaction; rejected commands and storage rollback emit none. The broader transaction/storage work in #893 remains separate.
Verified:
The corrected full unit run is still in progress. Full coverage/feature qualification, the ordinary 2.15.0 release, a normally installed consumer and publication of the guides remain open. The release metadata is prepared; no tag, package or guide has been published for this change.
rmcdaniel commentedon Oct 26, 2026
Source merged through PR #946 at
e6a8fb8e3a5d9a79d4744bb650d57dc47dd6db6c. The signed merge has the identical reviewed tree70b4a8d2b55b6698bb816e732b58b6d2131d35fa.The final PR build passed, including the strict replay counterfactual and MySQL feature controls. Sonar reports zero new issues and zero security hotspots. The complete local
composer unitcommand exits 0: 5,036 tests / 72,018 assertions, with 43 skips and 15 non-failing PHPUnit notices, in 20m15s. No assertions, deadlines or coverage thresholds were weakened.The independent main build is running the full coverage, MySQL/PostgreSQL feature shards, MariaDB control and supported Laravel upgrade journeys. Release 2.15.0 remains unpublished until qualification completes.
The eight-language guide change has passed the normal full build and rendered-page/locale-link checks. After the package is actually published and normally installed acceptance passes, advance the documentation's shared Workflow install pin to that qualified version, rebuild, publish and verify the live guide. The existing consumer still has unmodified published 2.14.2 installed; the final acceptance test is prepared but has not yet run against 2.15.0. This issue remains open through that delivery; #893 remains separate.
rmcdaniel commentedon Oct 26, 2026
Released and installed acceptance is complete for Workflow 2.15.0, source
e6a8fb8e3a5d9a79d4744bb650d57dc47dd6db6c. The annotated tag, Packagist source and Packagist dist all resolve to that qualified merge.composer coveragecommand also passes its separate unchanged 60% unit-only floor at 77.11% (58,792/76,244 lines): 5,036 tests / 72,017 assertions, 43 skips and 15 non-failing PHPUnit notices. The earlier plain unit command passed 5,036 tests / 72,018 assertions.The remaining acceptance is live documentation delivery in website PR #408: all eight event guides plus the shared qualified 2.15.0 install pin. The final eight-locale rebuild and hosted documentation qualification are running. This issue stays open through deployment and verification of the actual public pages. Broader #893 work remains separate.
rmcdaniel commentedon Oct 26, 2026
Delivered and verified in Workflow 2.15.0, published October 26, 2026 at 22:00 UTC. The immutable release resolves to
e6a8fb8e3a5d9a79d4744bb650d57dc47dd6db6c; normal Packagist source and distribution references agree.WorkflowCancelledandWorkflowTerminatednow describe actual durable closes, including cooperative cleanup completion and expiry. They carry the existing identity fields, the original nullable reason and persisted UTCclosedAt. Rejected commands, cancellation requests without a close, and storage rollbacks emit neither event. Dispatch waits for the actual run storage connection to commit. Delivery remains in process; the broader engine/storage transaction work in #893 remains separate.Verification completed:
composer coveragepassed 5,036 tests / 72,017 assertions, with 77.11% unit line coverage against the unchanged 60% floor; 43 skips and 15 non-failing PHPUnit notices remain recorded. The 100% target is not reached.85787d74d0aca89e9ba88c7c560d2e7aed3d43d164a3cc13db6991032a927e78.The live events guide documents cancellation, termination, normal timeout failure, cleanup deadlines and the commit/delivery limits. Package and published-documentation acceptance are complete.
rmcdaniel commentedon Oct 26, 2026
Published-package and all eight live documentation locales are accepted; final evidence is in comment 6429074557. Completed task worktrees, branches, build/test dependencies, raw reports and disposable resources are cleaned. Closing as completed in Workflow 2.15.0.