diff --git a/CHANGELOG.md b/CHANGELOG.md index ff60ea83..b32b4f07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m ## Unreleased +- learn(microflow-patterns): **the microflow header grammar, in one line.** `create microflow M.Name ()` keeps its parentheses even with no parameters, `returns` follows them, and placement is `folder '…'` (not `in`). The wrong shape fails `check` with three errors that point at `returns` and `List of` instead of the missing `()`, which cost a check cycle on a field build (mxcli v0.26.0, Mendix 11.15.0). Upstream draft for a clearer message: `BUG-DRAFT-microflow-header-grammar`. (#361) — joshuamoesa, from an existing-app connector project - process(build): **Stage 5 drafts the ready set in parallel and applies serially.** The runbook dispatch row said "sequential within a module", which serialised drafting even for independent scripts; it now points to `iterative-build-loop.md` → Gate cost, the single statement of the rule. The unit is the build-plan row: every `BUILD` row whose "Depends on" rows are all applied, minus overlapping writers (two rows that replace, alter or drop+create the same document never share a ready set, and no row is drafted while it overlaps a queued unapplied one; `brd-to-build-plan.md` has Produces name every document a row writes), runs at once, its scripts in order, one `mdl-agent` per script. Applies stay one at a time through `bin/exec.sh`, and the ready set is recomputed after each. A queued draft made before a sibling apply landed is re-checked with `mxcli diff --format struct` (preflight STOP rule 23); any removal line (checked against `describe` per BUG-146) or STOP rule 21 target means re-draft, never patch, because a stale restatement of a shared document is exactly rule 21's silent seed-call loss and passes `check --references`. Report `ready set N, drafted N, applied k`; the `mdl-agent` template says a drafter never applies and never depends on an unapplied draft. Field evidence: none yet. — MendixMau - fix(platform-link): **CLI commits now show their changed documents in Studio Pro History.** Studio Pro's History → Model changes pane reads a `ModelChanges` array from the commit's `refs/notes/mx_metadata` note. Trap 6c's hand-written template set it to `[]`, so every mxcli/agent commit showed "Model changes 0" (field project: 270 of 270 notes empty). New `project-bin/mx-metadata-note.py` (stdlib only) computes the array from the commit's changed `.mxunit` files, in Studio Pro's entry shape: Status, UnitID, UnitType, UnitName and Module (walked up the `.mpr` Unit tree). It has `changes` / `write` / `backfill` / `sync ` subcommands. `install-project-hooks.sh` now also installs post-commit and post-rewrite hooks that write the note and never block, and `--check` covers them, so `sync-project.sh` rolls them out to wired projects. Notes are published with `mx-metadata-note.py sync ` after the branch push. Push config is never touched. With mxcli v0.26+ in the project root the hooks call `mxcli git note --write` instead (mendixlabs/mxcli#1337); the Python script is the fallback for older pins, and on 160 field commits both wrote the same 3,594 entries. Trap 6c rewritten. Measured against Studio Pro's own notes, 51 commits in 5 apps: 3387/3389 entries exact on all five fields. Field run on a 357-commit Mendix 11.15.0 app: 158 notes backfilled and pushed, and Studio Pro History lists the documents per revision. Review fixes: an earlier revision added `HEAD` + the notes ref to `remote..push`. It was dropped because any push refspec replaces `push.default`. A branch tracking a differently named upstream got a new same-named branch on Team Server where `simple` refuses, a missing local notes ref failed the whole push, and nobody knows whether Studio Pro's own push reads that config. The installer now only fetches the remote's notes (non-forced). It removes that exact `HEAD` + notes pair if present, and leaves and reports any other entry. `sync` handles a remote with no notes ref (it used to exit 1) and retries a rejected push once after re-merging. A note that already lists changes (Studio Pro's) is never overwritten by `write`/`backfill` without `--force`, and `sync` keeps a colleague's non-empty note over ours. The mxcli probe greps `git note --help` for `--write`. Hooks and docs call the script through `resolve_py`. Fixture `tests/wave2/test-mx-metadata-note.sh` (40 cases, over real captured template units; single- and two-tree layouts, amend, backfill and `--force`, push exit codes identical to a no-hooks clone, leftover-refspec cleanup, sync to an empty remote and its retry, notes fetch at install, a diverged notes merge; green under `init.defaultBranch` master and main). — field project (Mendix 11.15 app), MendixMau - learn(fixture-seeding): **explore the data structure first, choose rows by use case, scan actions for resets before any run.** Two seeding runs on public template apps: seeding raised journey passes 33 -> 58 and 20 -> 51 of the same sets (FAIL 93 -> 68, 163 -> 132; INVALID unchanged), and a "Reset all demodata" journey wiped accounts so 104 of 127 journeys reported `The username or password you entered is incorrect`, identical on empty and seeded databases. Skill gains three questions a seed must answer, a use-case checklist, a destructive-action scan, a generic traps table with symptoms, measured expectations and a denominator checklist; routing trigger now fires on seed/test/demo data and empty pages. Independent review fixes: object ids follow the Mendix bigint pattern with a business-key guard (no uuids), associations are seeded where the page's path stores them, four new traps (enum names, inheritance chain, calculated attributes, view/external entities), and the port-offset and container-label traps moved to `harness-architecture.md`. — MendixMau diff --git a/bug-logs/mxcli-bugs.md b/bug-logs/mxcli-bugs.md index c068c838..d12d6bfd 100644 --- a/bug-logs/mxcli-bugs.md +++ b/bug-logs/mxcli-bugs.md @@ -6950,3 +6950,49 @@ Two related findings from reading the v0.26.0 source (not field-run): matching the project. Recipe and the rule-set comparison to run before any diff: `skills/lint-that-actually-runs.md` → "Linting a copy of the model". `lint-gate.sh`'s collapse guard catches this inside the gate. Nothing catches it when lint is run directly. + +## BUG-DRAFT-microflow-header-grammar: a microflow header without `()` fails `check` with three parse errors that point at `returns` and `List of`, not at the missing parentheses (2026-10-14) + +> **NOT YET FILED.** The grammar is as designed; the ask upstream is a clearer message. + +**Discovered:** 2026-10-14, on an existing-app change project (a connector app), while drafting a small list-transforming microflow: no parameters, returns a list, lives in a sub-folder, loops over the list and sets one attribute. +**Reproducible:** yes, on every such header. **mxcli version:** v0.26.0. **Mendix:** 11.15.0. macOS. + +**What happens.** The natural-language header shape + +``` +create microflow M.Name returns List of M.E in '' … +``` + +fails `mxcli check` with + +``` +line 11:2 missing '(' at 'returns' +line 11:10 missing ':' at 'List of' +line 12:2 mismatched input 'in' expecting ')' +``` + +The parser takes `returns` as the start of a parameter, so the second and third messages describe a parameter list that was never written. The agent spent a check cycle guessing. + +**Fix (built clean: check, exec, mxbuild, lint ratchet):** + +``` +create microflow M.Name () + returns List of M.E + folder '' +begin + … + loop $M in $L begin + change $M (A = ); + end loop; + … +end; +``` + +1. The parameter parentheses are mandatory even when empty. +2. Placement is the `folder '…'` clause, not `in`. +3. A list member is changed inside `loop … begin … end loop;` with `change $var (…)`; there is no `foreach`/`for`. + +**Expected:** when `returns` follows the microflow name directly, `check` says "parameter list `()` required before `returns`" instead of three cascading errors. + +**Toolkit side:** `learned-microflow-patterns.md` → "Additional MDL Syntax Rules", first bullet. diff --git a/skills/learned-microflow-patterns.md b/skills/learned-microflow-patterns.md index 82e48a79..f49c5ba6 100644 --- a/skills/learned-microflow-patterns.md +++ b/skills/learned-microflow-patterns.md @@ -252,6 +252,7 @@ An `@annotation` sits immediately before the statement it explains — an activi ## Additional MDL Syntax Rules +- **Microflow header:** `create microflow M.N ()` keeps its `()` even when empty, then `returns`, then `folder '…'` (not `in`). The `check` errors point at `returns`/`List of`. BUG-DRAFT-microflow-header-grammar. - **Cross-module association `change` from the non-owner side (CE0854):** `check` and `exec` pass it; `mx check` gives `[CE0854] Cross-module association 'Mod.Assoc' is not reachable from entity 'ModB.Entity'`. Change from the owner side — see "Association Direction — Setting in Microflows". - **`validation feedback $Obj message '...'` with no attribute → CE0091:** `check` and `exec` pass it; `mx check` gives `[CE0091] No member selected.` Always name the attribute: `validation feedback $Obj/Attr message '...'` (that form builds at 0 errors). **Where it goes:** in a `VAL_`/`SUB_` microflow, never an `ACT_` one — see the next section. - **Microflow canvas layout — omit layout annotations (LESSON-01+02, corrected 2026-09-25):**