Sync wave 10 - #1244
Sync wave 10#1244
Conversation
A microflow or nanoflow that calls itself failed exec with "microflow not found" while check passed: the builder resolved call targets against the project only, where the flow being created is not stored yet. The builder now knows the flow it builds (name, kind, declared return type) and answers existence and return-type lookups for a same-kind call from it; loop and error-handler sub-builders carry it. A call to a missing flow, or a nanoflow calling a microflow of its own name, is still refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ment lacks (#843) Under mdl 1, create or modify nanoflow ... returns T as $Var over a nanoflow stored without ReturnVariableName (mxcli's own writer omits it without `as $Var`) refused "set it in Studio Pro". SetHeader now adds a stated header key the stored document lacks when the deps say the project's metamodel declares it (PropertyDeclarer; the codec deps answer from the metamodel version data - ReturnVariableName is 10.12+). No answer keeps the refusal. Includes the roundtrip test for both #843 halves (exec twice on PedApp, second writes nothing). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pgrade rewrites it Mendix has no date-only type and mxcli always stored `date` as a DateTime. #706 refused it in every version together with float/currency, which stopped headerless scripts that ran (mxcli-ledger's domain model, rehearsal U1) and left fmt --upgrade unable to parse them. Unlike float/currency, whose old reading stored a String, `date` stored what the author meant: a respelling. It is now registered as MDL-DEPR160 (marked on dataType and nonListDataType): without the header it builds exactly what DateTime builds and warns; fmt --upgrade writes DateTime; under mdl 1 it is refused (RemovedIn 1, like MDL-DEPR138). float, currency and the parenthesised association form stay refused. Upgrading the ledger's pre-migration 01-domain-model.mdl now yields its hand-finished committed file byte for byte. Part of #714, #706. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s` (#873) Since mendixlabs#895 a bare `commit $X;` means with events (MDL067); a flow an older mxcli stored from the same script commits without events, so re-running it turned handlers on, and inside a loop the mdl 1 splice refused it on every run (rehearsal M1: six flows in mxcli-ledger). The visitor records each commit in a create-or-modify flow (ast.Program.FlowCommits) with the edit that states `without events`. With a project (StoredCommits, backed by executor.StoredCommitEvents, loop bodies included) the upgrade matches commits to stored Commit activities by variable and pins the bare ones where every remaining stored commit of that variable is without events; a mixed or surplus case is left and reported. Without -p, fmt prints a note per flow naming MDL067. fmt now opens -p with or without --header, since the #895 change is not version-gated. Closes #873. Part of #714. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#872) `revoke all on entity E from R;` followed by the grants meant to hold rewrote the domain model on every re-run, re-minting the access rule and moving the transaction id although the rules it ended with were the ones it began with (rehearsal W3). Each statement was written and reconciled on its own, so the grant was compared with a unit the revoke had already emptied and had no stored rule to carry identity from. A run of consecutive entity grant/revoke statements is now held in memory (served through the reader overlay, which the unit listings now honour) and written once at its end, reconciled against the state before the run. Any other statement, the end of the program, a failure and disconnect end the run. Closes #872 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ernals, pattern Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A statement that added, reworded or took off an @annotation on an activity, or dropped an annotated activity, was refused under mdl 1 on every run (rehearsal M3: ledger BUILD_ScatterUrl, and the Studio Pro PedApp nanoflows ACT_Feedback_TriggerScreenshotMode / _UploadImage when their mdl 0 description is put under the mdl 1 header). The splice could only keep a replaced activity's stored notes. MicroflowMutator.RemoveNotes takes out the annotations attached to an activity with their lines, refusing a note also attached to another object. create or modify marks a replace or drop whose declared notes differ (AlterFlowOperation.ReplaceNotes); the applier removes the stored notes first and the fragment builder draws the declared ones. A note describe gives an id (shared) is still refused. Part of #859 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#859) describe never prints `on error rollback` (it is the stored default), so a statement stating it never matched its own activity in the create or modify statement diff: whenever anything else in the flow changed, the activity was dropped and written again (new $ID, curves redrawn). The comparison now reads a bare rollback clause as absent on both sides. Part of #859 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the header re-run clean (#859) TestSpliceRerun_* run in the parity suite (SPLICE_PARITY) to keep the roundtrip suite under its time limit (#870). TestSpliceRerun_PedAppNanoflowsUnderTheHeader runs every PedApp nanoflow's mdl 0 description under mdl 1; each must execute and a second execution must write nothing. Part of #859 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gs, pattern Part of #859 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
describe microflow dropped `with title = '…'`, so describe -> exec lost the override and taking it out of a create or modify was reported Unchanged: the statement diff compares against describe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- sameBuiltFlow compares a raw BSON payload with every $ID set aside: each build mints its own, so two builds of one call never compared equal and every re-run re-spliced the activity. - webServiceActionRequiresRawBSON keeps the raw form for a stored call that lacks a key the structured writer emits (ErrorHandlingType, …) or refers to its service by ID; describe printed a structured form that writes a different document. - 06b-soap-examples comes off rerunKnownFailures; the title-override take-out case joins TestFlowModify_PropertyEditsAreWritten (#869). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…874) `retrieve $L from M.Emp where [M.Emp.Name = 'y']` stored ['Name' = 'y'], a comparison of two constants that passes every check and filters nothing. Every XPath serializer read a three-part name as an enumeration value without knowing the constrained entity. The page datasource did the same, and an access rule or workflow targeting stored the qualified name verbatim, which is CE0161. FormatXPathConstraint turned the name into the literal for any constraint long enough to re-lay out. storedXPathConstraint resolves Module.Entity.Attribute to Attribute when Module.Entity is the constrained entity or an entity step of the constraint's own path. Every other three-part name keeps the enumeration reading ('Value'). All four writers use it, and so do the create-or-modify comparison against describe's form (so the re-run is Unchanged) and the page member check (which refused the re-run with CE1613). The visitor now writes qualified names as given and leaves the decision to the writer. This is a silent wrong write, so it is fixed under mdl 0 and mdl 1 alike (ADR-0011). Measured with mx check 11.14.0 on a TestApp copy: [Name = 'y'] gives 0 errors, [M.Emp.Name = 'y'] gives CE0161. Closes #874 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orm (#861) TestActionFromGen_WebServiceCall_NoRaw asserted that a five-key call describes structurally; writing that form back adds ten keys. It now uses the writer's own fifteen-key shape, and the minimal call is the raw case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… reports it (#872) ExecuteProgram flushed an open access-rule run in a defer that discarded the error, so when a statement of the run failed and the flush of the statements before it failed too, those statements had printed success and nothing landed, silently. The flush error is now joined to the statement's. Also covers the v1 unit listing's overlay check, which no test exercised. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sync mendixlabs/mxcli
Reading every three-part name the writer cannot place as an enumeration value turned constraints that used to fail loudly into silent ones. An access rule stored a short constraint verbatim, so `grant ... on Administration.Account ... where [System.User.Name = 'x']` was CE0161 on main; with the enum reading it became ['Name' = 'x'], which compares two constants and passes mx check (measured, 11.14.0 on a TestApp copy). Workflow targeting on the configured user entity had the same change. The access-rule writer has the project, so storedModelXPathConstraint resolves the entity's generalization chain as owners and leaves a name qualified with any other entity of the model as written. Workflow targeting is built without a project, so it only resolves the names of System.User / System.WorkflowGroup and path steps, and leaves every other three-part name verbatim, as on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ctivity dropped takes its note
Without ReplaceNotes on the drop, the note stayed as a free annotation and
the statement was refused ("the free annotations change"); nothing tested it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md # docs-wiki/bug-patterns/scripts-that-cannot-rerun.md
fix(security): a revoke+grant run that nets to nothing writes nothing (#872)
fmt --upgrade: date as a DateTime alias (U1) and pin stored commit without events with -p (#873)
…n-var fix: recursive flows in one statement; add a stated nanoflow return variable (#843)
fix(flow-modify): re-annotated activities and on error rollback in create or modify (#859)
…made the project unloadable (#885) `create or modify microflow|nanoflow` builds each replacement activity with the alter-flow fragment builder, which was seeded only with the types of the stored flow's parameters, declare and create outputs. A variable bound by a retrieve, a microflow call or a list operation was untyped, so a spliced `change` wrote its member bare (`Name`, not `System.User.Name`) and Mendix could not load the project ("not a valid AttributeIdentifier"); a spliced find by member became a find by an invalid expression, an aggregate lost its attribute, and a sort was refused by the AttributeRef write guard. - planFlowModify hands the declared body's full-build variable types to the fragment builder, so the splice writes what `create` writes. - storedVariables also types database retrieves and microflow-call results, for `alter microflow`. - Guards: the fragment builder refuses a member it cannot qualify (qualifiedMembersOnly) instead of writing it bare, and the write choke point refuses a bare Microflows$ChangeActionItem.Attribute. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(flow-modify): a spliced member is written qualified — bare names made the project unloadable (#885)
AI Code ReviewReview SummaryThis PR appears to be a large synchronization update ("Sync wave 10") touching multiple subsystems. While it adds valuable test coverage and follows existing patterns, its scope raises concerns about atomicity and maintainability. Minor Issues
What Looks Good
RecommendationApprove with the caveat that future work should adhere to stricter scoping guidelines. The changes are technically sound and improve robustness, but the PR's size complicates review and increases risk of subtle interactions. For similar syncs, consider:
No blocking issues identified. The PR maintains backward compatibility and follows Mendix/platform safety rules (e.g., proper GUID handling, no keyword overloading). Note: Review based on selected diff (87 files shown). Grammar changes in Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
Sync wave 10