Fixing invisible workflow statuses throughout - #6848
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Resolves the conflict in components/engine/engine-intent/CLAUDE.md: master rewrote the inbound-ingest entry of the catalog line (the accept:/map: arrival projection, eclipse-dirigible#6769) while this branch added onTransition to the lifecycle-trigger entry. Both kept. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Merged current Only one file actually conflicted: Verified on the merged tree before pushing: |
This PR:
onTransition: the-updatedhalf of the DSL was deaf to every status the system writes-transitionedand-updatedare fully disjoint channels. The three publishers of the former —SetField.java.template:61,Transition.java.template:76,Generate.java.template:176— neverpublish the latter, deliberately, so a system write cannot re-fire the onUpdate reactions meant for a
person's edit.
But
onTransitionexisted only inPostingIntent#eventandGeneratesIntent#event. Everything elsewas locked to the lifecycle vocabulary, so:
onUpdatelistened on the other channel and never fired — with nothing anywhere to say so.waitcould be aborted by a transition but never resumed by one.abortOn:binds-transitioned(Abort.java.template:34) whileProcessWaitSupport.EVENT_KINDSwas{onCreate, onUpdate}, so the instance parked forever, silently.The reported cases, both verified against the source:
The fix
onTransitionis now in the event vocabulary ofnotifications:,integrations:,outbound:,a process
trigger:and awaitstep.No template changed at all. Every handler already interpolates
${topicSuffix}into itsdestination(), and the topic already existed and already carried the full entity payload — so thisis a vocabulary change, not a new mechanism.
outbound:is included beyond the issue's list: it sharesvalidateEventBindingandGLUE_EVENT_KEYSwith the other two, so excluding it would have cost extra code to withhold acapability that arrives for free.
The
when:guard stays optional on all five ("on any status change" is a legitimate ask), unlikepostings:andgenerates, which mandate one because they create a document per transition. Thatdifference is now stated in both guides rather than left to be inferred.
The fifth enumeration — the one that would have shipped broken
The issue named four places to widen. There are five.
StatusSymbolResolver.triggerEntityOfkeepsits own list because it runs on the raw YAML tree before the typed mapping and therefore cannot
read
EventBinding. My own test caught it:trigger: { onTransition: Fine }was refused with— a message about the status nomenclature, pointing nowhere near the trigger. Any process using
symbolic status names would have broken the moment its trigger moved to
onTransition.All five now agree, and each carries a comment saying so:
EventBinding.KINDS+topicSuffixIntentParser.EVENT_KINDSProcessWaitSupport.EVENT_KINDSvalidateWaitStepsnow reads this list instead of its own copy, so validation and emission cannot driftUnknownKeyValidator.GLUE_EVENT_KEYS+ProcessIntent#triggerStatusSymbolResolver.triggerEntityOfAdding the kind to
EventBindingdoes not widenresolves:— its own vocabulary is stillonCreate/onUpdateand is checked first.Verification
GlueTransitionAxisTest(new) — notification, integration, departure and trigger each resolve-transitioned, driven through the real parser and glue generator.GlueWaitsTest.aWaitCanParkOnATransition— the wait half.NotificationSupportTest—topicSuffix("onTransition").formatter:validateclean.OutboundIntentTestasserted the old message verbatim; updated to the widened text.Reviewer note
onTransitionon an entity nothing ever transitions is still a silent no-op — the same as bindingonUpdateto an entity nobody updates. A publisher-existence check is computable (a setter step, atransitions:entry, or ageneratessourceStatus:on that entity) but would risk falserejections on cross-model sources and hand-written delegates, so it is deliberately out of scope.
Happy to add it as a generate-time warning if that's wanted.