+{"area": "mdl/executor", "date": "2026-09-23", "symptom": "Two defects on reference-set writes in microflows. (a) `change $G (Assoc = $x)` / `create M.E (Assoc = $x)` always wrote MemberChange Type Set: there was no MDL for Add/Remove, so 'add a guest to the group' could only be written as 'replace the group's guests with this one', and DESCRIBE printed a Studio Pro Add/Remove as `Assoc = $x`, so describe -> exec silently turned it into a Set. (b) `$NewGuest = create UserGroups.Guest (Email = $Email, GuestGroup_Guests = $GuestGroup)` against `GuestGroup_Guests from GuestGroup to Guest type ReferenceSet owner Default` passed `mxcli check --references` and exec, then mxbuild failed CE0854 'Association ... is not reachable from entity UserGroups.Guest'.", "cause": "(a) addCreateObjectAction/addChangeObjectAction hard-coded MemberChangeTypeSet and formatAction ignored MemberChange.Type; the writer, reader and MCP backend already carried Type through, so the gap was grammar/AST/builder/describe only. (b) no check compared the written object's entity against the association's owner: --references only resolves the association NAME, which exists.", "file": "`mdl/grammar/domains/MDLMicroflow.g4` (memberChangeList: `add X to M` / `remove X from M`), `mdl/visitor/visitor_microflow_actions.go` (buildMemberChangeList), `mdl/executor/cmd_microflows_builder_actions.go` (memberChangeTypeOf, checkAddRemoveTarget), `mdl/executor/cmd_microflows_format_action.go` (formatMemberChange), `mdl/executor/validate_association_writes.go` (MDL-ASSOC01 static + project halves), `mdl/executor/cmd_microflows_builder_validate.go` (memberWrite hook)", "insight": "An association is stored on its OWNER (ParentPointer = FROM under owner Default; either end under owner Both), and a member change writes on the object being created/changed -- so writability is 'object entity is, or specialises, FROM (or TO when owner Both)'. The existing validation walk (validateStatements) already tracks each variable's entity; hooking one callback into its CREATE/CHANGE cases was enough, with no new flow walker. Split by where the association is declared (script -> static ValidateProgram, no project needed; project -> validateWithContext) so nothing reports twice, and treat an inheritance chain that leaves what is known as UNKNOWN, not 'not a specialisation' -- a false CE0854 on a subclass of the owner would be worse than the miss. When a round trip loses a stored enum like MemberChange.Type, check the describer before the writer: here the writer was right all along.", "refs": [], "ce": ["CE0854"], "rules": ["MDL-ASSOC01"]}
0 commit comments