diff --git a/CHANGELOG.md b/CHANGELOG.md index 2508b8bf..91ed25aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m ## Unreleased +- learn(workflow skills): **a Jump has one fixed target, so one failure handler for N steps is a child workflow, not a shared node; plus three probed workflow errors (CE0117 on a `System.Workflow` argument means map `$WorkflowInstance`, CE1613 means the called workflow's parameter must be `$WorkflowContext`, and `returns` goes before `exposed as workflow action`).** `workflow-structure-rules.md` §1 and `learned-workflow-patterns.md` §9. The §9 rows were probed on mxcli v0.26.0 / Mendix 11.15.0 with native `mx check`. The third row corrects the reading that a called microflow cannot return a value. Upstream issues: mendixlabs/mxcli#1529 (CE0117), #1530 (CE1613, and `syntax workflow call-workflow` shows the failing form), #1531 (describe drops every call workflow mapping), #1533 (`returns` parse messages). Source: a five-app lab project (Mendix 11.15, mxcli v0.26.0) — five-app lab report, WF-1 +- learn(fixture-seeding): **resetting workflow data: abort instances through the runtime (Workflow Commons admin or *Change workflow state*); if SQL is unavoidable, delete the link tables first (`system$workflow_currentactivity`, `system$workflow_workflowdefinition`, `system$workflowusertask_assignees`, `system$workflowusertask_targetusers`, `system$workflowusertask_targetgroups`, plus the `system$workflowendedusertask_*` equivalents; names read from a Mendix 11.15 database), and reset a context object only after its instances are gone.** A seed reset that deleted workflow rows by SQL failed on those links (WF-5). Text only, `ondemand` skill. — five-app lab report, WF-5 - fix(e2e/helpers): **`navTo` throws `navigation item "" not found` instead of clicking nothing.** A missing menu item was a silent no-op, so when the target page was also the persona's home page the landing guard stayed green and a broken-control journey (a control that must FAIL) passed. The parent group stays soft (an open flyout needs no click); the item itself must be found. The message names the active user and the visible menu items, so the reader can tell a renamed item (fix the journey) from a role that cannot open the page (fix the grants). Callers: journey steps fail with the message, design-audit rung 7 records a fault, full-app-walkthrough records a failed `nav` step (the walk stops only when the step is `fatal`), monkey's `land` swallows the error and still checks `.mx-page`, so monkey is unchanged. `tests/wave2/test-navto-missing-item.sh` (stub page, no browser) fails on master (absent item resolves) and passes here. Field report: a five-app lab project (Mendix 11.15, mxcli v0.26.0), TK-012 — MendixMau - learn(rest-between-mendix-apps): **new on-demand skill for two or more Mendix apps you build that read each other over REST (app-to-app, microservices).** The contract decisions to write down before the first script (pull vs push, versioned path, key + version rule, cursor paging, `since` with overlap, error shape incl. the runtime's 560, auth in the operation microflow as of mxcli v0.24 per BUG-152, fixed ports, one owner per fact), 17 publisher and consumer rules for honest "as of"/stale/"never read" states, and a six-rung cross-app test ladder with a per-change/slice/release cadence; a signal-stopped test run is BUG-157. The 26-row failure register behind it is `process/rest-between-mendix-apps-register-2026-10.md`. Routed ondemand for architect, mdl, test and review at stages 3–6. Field evidence: three demo apps, mxcli v0.24–v0.26, Mendix 11.15, 2026-10-07 to 2026-10-12, domain names generalised — MendixMau - fix(docs-numbering): **the pre-commit doc numbering check no longer fails every merge commit.** A merge stages all the other side's files, so the check examined docs the merge never touched and tripped on the existing "15-step" prose in `skills/source-triage.md:240` (plus two siblings that fail `--all`), which sent agents to `--no-verify`. During a merge it now examines only files that differ from both parents. The doc prose is left alone (an anecdote, not a drift). `tests/wave2/test-docs-numbering.sh` T11 fails on master's script. — agent report of `--no-verify` merges diff --git a/skills/fixture-seeding.md b/skills/fixture-seeding.md index 939929b1..0e0a4804 100644 --- a/skills/fixture-seeding.md +++ b/skills/fixture-seeding.md @@ -201,6 +201,20 @@ the answer is "re-copy the Run Locally database", say that in the project's own "re-run the seed script", the seed script has to be idempotent, which most hand-written ones are not. +### Workflow data: abort through the runtime, link tables first if SQL + +A seed reset that deletes workflow rows by SQL fails while the link tables still point at them. +On Mendix 11.15 (names read from a database, not from docs) they are +`system$workflow_currentactivity`, `system$workflow_workflowdefinition`, +`system$workflowusertask_assignees`, `system$workflowusertask_targetusers` and +`system$workflowusertask_targetgroups`. Finished tasks keep their own links, with rows: +`system$workflowendedusertask_assignees`, `_targetusers`, `_targetgroups`. There is no +`usertask_targets` table. List the real names first (`information_schema.tables`) rather than +trusting this list on another version. Abort instances through the runtime (Workflow Commons admin, or a microflow +with *Change workflow state*); if SQL is unavoidable (local database only), delete the link tables +first. Reset a context object only after its instances are gone: a deleted context object makes an +instance incompatible, and that cannot be resolved (Mendix docs, *Workflow versioning*). + ## What seeding buys - set expectations Journeys PASS / FAIL / INVALID on two public template apps, same set, empty vs seeded database: diff --git a/skills/learned-workflow-patterns.md b/skills/learned-workflow-patterns.md index 83cc969a..f51d44bf 100644 --- a/skills/learned-workflow-patterns.md +++ b/skills/learned-workflow-patterns.md @@ -653,6 +653,9 @@ varying **only** the suspected cause — see [[sandbox-ab-tool-defect-probe]]. | **CE0053 / MDL040** | `DECLARE $L List of Mod.Entity = empty;` | Use `$L = CREATE LIST OF Mod."Entity";` | | **CE0108** | A `RETRIEVE` inside an `IF` shadows the named return variable, leaving it out of scope on the `ELSE` path | Use early `RETURN empty;` on failure branches so only the success path reaches the named-return retrieve | | **MDL-WF04** | Standalone `ANNOTATION` in a workflow activity flow (produces an unloadable model) | Use a plain MDL comment | +| **CE0117** at a *Call microflow* whose microflow takes a `System.Workflow` parameter | You passed a variable the workflow does not have (`Workflow = $Workflow`). `check --references` passes it. Only native `mx check` refuses it (mxcli v0.26.0, Mendix 11.15.0, probed 2026-10-15; upstream mendixlabs/mxcli#1529) | Map it to `$WorkflowInstance`: `call microflow M.ACT_X(Workflow = $WorkflowInstance, Ctx = $WorkflowContext)`, which builds clean (same probe). Don't look the instance up through `System.Workflow_ParentWorkflow` instead. That lookup has to guess when more than one child is in progress | +| **CE1613** "The selected parameter '…' no longer exists" at a *Call workflow* | The called workflow's parameter is named something other than `$WorkflowContext` (`parameter $Task: …` with `(Task = …)`). `check --references` passes it. `describe workflow` drops every call workflow mapping, correct ones included (mendixlabs/mxcli#1531), and `mxcli syntax workflow call-workflow` still prints the failing form (`Request = $WorkflowContext`, v0.27.0; #1530), so do not copy that example (mxcli v0.26.0, probed 2026-10-15) | Every workflow that is called declares `parameter $WorkflowContext: …`, and the call maps `(WorkflowContext = …)`. Keep the `.mdl` file as the source; don't round-trip the call through `describe` | +| parse error on a workflow call microflow: `mismatched input 'returns' expecting BEGIN` (v0.26.0) or `mismatched input 'returns' expecting STRING_LITERAL` (v0.27.0, mendixlabs/mxcli#1533) | `exposed as workflow action …` written before `returns …` | Write `returns Boolean as $Ok` first, then `folder` and `exposed as workflow action`. A called microflow *can* return a value: a Boolean gives the activity `true`/`false` outcomes and an enumeration one outcome per value plus empty (Mendix docs, *Call microflow*). "Exposed call microflows return nothing" is a wrong reading of this parse error (probed 2026-10-15) | | **MPR006** | Empty container — compiles, crashes at runtime | Give every container content, or drop it | | **MPR010** | Widgets not wrapped in a `LAYOUTGRID` | Wrap them | | Workflow stuck | No `complete_task` button for one of the task's outcomes | Add the missing outcome button | diff --git a/skills/workflow-structure-rules.md b/skills/workflow-structure-rules.md index 13caf127..ff9a6e1c 100644 --- a/skills/workflow-structure-rules.md +++ b/skills/workflow-structure-rules.md @@ -55,6 +55,27 @@ Two failures this prevents, both invisible to `mxcli check`: The main flow is `Start → … → End`. New activities go after the start and before the end (or before a *Jump*, when the main flow ends on one). +**A *Jump to* has one fixed target. It cannot return to whichever step sent it there.** So "every +failing step goes to one shared failure node, then retries the step that failed" is not a +workflow you can draw: the retry needs a different target for each step, and there is no +"return to caller". A five-app lab project (Mendix 11.15, mxcli v0.26.0) drew exactly that for +seven calls. The Stage 3 count (§12) refused it, and the redesign cost a resolution round plus a +resync of the blueprint and three BRDs. When one failure handler must serve N steps: + +- put the step and its retry or attention loop in a **child workflow** that each step reaches + through *Call workflow*. The child holds one handler, and its backward jumps stay inside the + child, so every target is fixed; +- the child ends **normally** and writes its result on its own context (an outcome attribute). + The parent reads it in a decision after the call. A sub-workflow returns nothing, and if it + *fails* or is aborted, the parent fails too (Mendix docs, *Call workflow*). Failure must + therefore be data, never an error; +- a jump in the parent aborts a running child (same page). Keep jumps in the parent to the + points where no child is running. + +The alternative, one copied tail per step, multiplied a 7-call parent to 21 calls and 43 +decisions in that project's count. Count the child design and the copied-tail design (§12) +before you choose. + ## 2. Boundary events — type decides the terminator A boundary event hangs on one parent activity. Only these can carry one: *wait for