feat(microflow): @position on a flow parameter, and stop moving hand-placed ones - #370
Merged
Conversation
…placed ones A Microflows$MicroflowParameter is a stored node with real geometry (RelativeMiddlePoint + Size 30;30) that Studio Pro lets you drag, but no MDL annotation reached it. Two consequences, the second the more serious: a generated flow's parameter block landed wherever the writer put it, and an existing hand-aligned one was MOVED by any rewrite — including a describe -> exec of mxcli's own output. Measured on a real nanoflow, a parameter at -77;0 came back at 200;53; on a 1971-unit project, 20 of 28 parameters sat off the derived grid and so were moved. The cause was a four-point chain: the semantic type had no position field, so neither reader carried one, so both writers could only recompute 200+idx*100;53 inline, and the grammar had no slot to state one. The placement rule is @start's, unchanged (mendixlabs#884, mendixlabs#951): a parameter sitting exactly where the layout would have put it is mxcli's own arithmetic handed back, carries no intent, and is re-derived; one anywhere else was placed by a person, survives a rewrite, and is emitted by DESCRIBE. Carrying stored coordinates over unconditionally is the trap that rule exists to avoid — inserting a parameter would strand the existing ones on the old grid while the new one landed on top. The arbitration lives in the readers, so a non-nil Position means intent everywhere downstream; it is a pointer because 0;0 is a coordinate a person can choose. Syntax needed one grammar line (annotation* on microflowParameter), with no ANTLR ambiguity, so the block-level @parameters(...) alternative is unnecessary. @position is the only annotation a parameter takes; anything else — a typo of it above all — is refused as MDL059 rather than parsing and doing nothing, in check, exec and the LSP. Covers microflows, nanoflows and rules (shared parameter grammar) on both engines. The four near-duplicate describers now share one helper, so the annotation cannot appear from one command and not another. Verified on mxbuild 11.13: authored positions stored verbatim, the unannotated control still deriving to 200;53/300;53, describe -> exec reporting Unchanged, 0 errors. Control: with the read-side carry stubbed, -77;0 -> 200;53 returns and DESCRIBE emits nothing. Refs: ako/mxcli#993 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017s476QkXr9CFMvKspVzcvu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the gap reported upstream as
mendixlabs/mxcli#993: a parameter is a stored node with real geometry that Studio Pro lets you drag, and no MDL annotation reached it.The report was half of the story
Filed as a feature request — a generated flow's parameter block lands wherever the writer puts it. Measuring it turned up the more serious half: an existing hand-aligned flow was moved, by a describe → exec of mxcli's own output.
200+idx*100;53was mxcli's derived grid, so anything off it was placed by a person: 20 of 28 parameters, in 20 of 27 flows of a real 1971-unit project. Every one was moved by any rewrite.Cause was a four-point chain — the semantic type had no position field, so neither reader carried one, so both writers could only recompute the index formula inline, and the grammar had no slot to state one.
The placement rule is
@start's, unchangedNot a new policy:
authoredStartPosition(mendixlabs#884, mendixlabs#951) already settled this for the StartEvent, and the reasoning transfers with the node family — including the trap. Carrying stored coordinates over unconditionally pins the node, so inserting a parameter would strand the existing ones on the old grid while the new one landed on top of them.So: a parameter sitting exactly where the layout would have put it is mxcli's own arithmetic handed back, carries no intent, and is re-derived. One anywhere else was placed by a person, survives a rewrite, and is emitted by DESCRIBE. That is why an ordinary description does not grow a line per parameter.
Two decisions worth a reviewer's eye:
Positionmeans intent everywhere downstream and no consumer has to re-derive.Positionis a pointer, because0;0is a coordinate a person can choose — two flows in the reference project use it. A zero-value check would have been a real bug, andTestAuthoredParameterPositionKeepsOriginpins it.Syntax
One grammar line (
annotation*onmicroflowParameter), no ANTLR ambiguity, so the block-level@parameters(...)alternative the reporter offered as a fallback is unnecessary.@positionis the only annotation a parameter takes. Anything else — a typo of it above all, which would otherwise parse and discard exactly the placement being asked for — is refused as MDL059 incheck,execand the LSP.Covers microflows, nanoflows and rules (shared parameter grammar) on both engines. The four near-duplicate describers now share one helper, so the annotation cannot appear from one command and not another.
Verification
On mxbuild 11.13, against a real project:
300;100,200;100,140;-60,60;-40);200;53/300;53, and DESCRIBE emits no line for it;Unchangedfor all four flows: an exact fixed point;mx check: 0 errors;-77;0 → 200;53returns and DESCRIBE emits nothing. Unit tests fail with the reported symptom.Full suite green,
gofmtclean,make check-findingspasses.Two limits, stated
-2563;35across saves is good evidence it honours them.ExportLeveland reset a sequence flow'sDestinationControlVector. Unrelated, pre-existing, not fixed here — worth its own issue. Noting it because an earlier read of this round trip treatedUnchangedon a second exec as proof the first write changed only the position; it proves the round trip reaches a fixed point, not that.Generated by Claude Code