Skip to content

feat(workflow): boundary events on call workflow (mendixlabs/mxcli#1532) - #1530

Merged
ako merged 1 commit into
mainfrom
feature/1532-call-workflow-boundary-events
Oct 21, 2026
Merged

ako merged 1 commit into
mainfrom
feature/1532-call-workflow-boundary-events

Conversation

@ako

@ako ako commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Implements mendixlabs#1532 (#1414), approved by the maintainer.

The gap

create workflow … call workflow M.Child … boundary event interrupting timer … failed with mismatched input 'boundary' expecting ';'. The reader, writer, describe, ALTER and the MCP backend already handled boundary events on a CallWorkflowActivity, so describe printed a clause that would not parse back.

Fix

  • Grammar: workflowCallWorkflowStmt reuses call microflow's exact boundary-event clause. No new tokens.

  • AST, visitor and builder: WorkflowCallWorkflowNode.BoundaryEvents is filled by the visitor and written by buildCallWorkflowActivity.

  • Validation walkers. Eight hand-written walkers over boundary events skipped call workflow:

    • workflow rules WF07–10, WF15, WF18 and WF19;
    • the rewrite guard's count;
    • the 11.11 notification gate.

    They now share one helper, workflowActivityBoundaryEvents, so rules and reference checks also check a call workflow's boundary bodies.

  • Walkers over stored workflows: two had the same gap and are fixed too.

    • ALTER's end-placement check lost the non-interrupting context below a call workflow.
    • MDL-WF05 (jump target) ignored targets inside its boundary body.
  • Version gating: the metamodel puts boundary events on CallWorkflowActivity at the same floor (10.14.0) as other activities. A notification boundary event hits the existing 11.11 gate.

Tests

  • visitor_workflow_callworkflow_boundary_test.go: the issue's repro, and the old with (…) form with a clause after it.
  • workflow_callworkflow_boundary_test.go:
    • the builder writes both events, and a call without the clause writes none;
    • a rule table for WF05, WF08, WF09, WF15, WF18 and WF19, each with a passing control;
    • the rewrite guard count and the notification gate;
    • describe output re-parses;
    • ALTER end-placement on a stored workflow.
  • Revert check: before the grammar change the tests fail with the reported parse error. Each part of the fix reverted on its own fails exactly its own tests.

Measured with mx check (fixture copies)

Case 11.6.6 11.15.0
interrupting timer { end workflow; } 0 errors 0 errors
non-interrupting timer { wait for timer … } 0 errors 0 errors
describe → exec already in sync already in sync
interrupting notification boundary refused (needs 11.11+), as expected 0 errors

Also in this PR: syntax help (workflow.call-workflow, workflow.boundary-event), the write-workflows skill, docs-site/src/language/workflow-activities.md, a finding file, and mdl-examples/bug-tests/1532-call-workflow-boundary-events.mdl. make build, make test, make lint, make check-findings and make check-skill-index pass.

Not done

  • Not measured: that end workflow inside a non-interrupting boundary under a call workflow gives CE1844. exec refuses it, by analogy with user tasks.
  • Existing gaps left alone:
    • the jump-target walker also skips boundary bodies under call microflow;
    • there is no 10.14 gate for boundary events on any activity;
    • the workflow.boundary-event syntax entry says MinVersion 10.6.0, where the metamodel says 10.14.0.

Generated by Claude Code

`create workflow … call workflow M.Child … boundary event interrupting timer …`
failed to parse ("mismatched input 'boundary' expecting ';'"), although the
reader, writer, describer, ALTER mutator and MCP backend all handle
Workflows$CallWorkflowActivity.boundaryEvents (10.14+, the same floor as every
other owner). DESCRIBE printed the clause for such an activity, so its output
did not re-parse.

workflowCallWorkflowStmt now takes call microflow's exact boundary-event clause
(no new tokens), the visitor fills a new BoundaryEvents field on
WorkflowCallWorkflowNode, and buildCallWorkflowActivity writes them through
buildBoundaryEvents.

The AST walkers each switched on the boundary-event owners themselves and none
knew call workflow, so WF07/08/09/10/15/18/19, the rewrite guard's count and the
11.11 notification gate would have skipped the new bodies. A single helper,
workflowActivityBoundaryEvents, now lists the owners; the two walkers that label
by owner (WF15, WF19) gained the case. On the stored side, ALTER's end-ancestry
walk lost the non-interrupting context under a call workflow and MDL-WF05 did
not see jump targets inside its boundary body; both gained the case.

Measured: interrupting and non-interrupting timer boundary events on call
workflow, mx check 0 errors on 11.6.6 and 11.15.0; describe -> exec "already in
sync" on both. A notification boundary event on call workflow is 0 errors on
11.15.0 and refused by the existing 11.11 gate on 11.6.6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
@ako
ako merged commit b21e897 into main Oct 21, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants