docs(wiki): digest the mdl/executor findings into nine bug-pattern pages - #356
Merged
Conversation
The bug-pattern layer had three pages, all synthesised on 2026-05-24 from the ~24 findings that existed then. mdl/executor alone now holds 248, and no page mentioned the area at all. Four classes, covering roughly 134 of the 248: - describe-round-trip-gaps (83 findings). DESCRIBE is a second implementation of MDL, written in the opposite direction and validated by nothing: mxbuild never sees its output, and a describer that drops a property still produces a valid model at 0 errors. Four shapes in increasing order of how long they survive — won't parse, silently drops, invents a clause nobody wrote, destroys structure. - unloadable-model-writes (12). Load failure is not validation failure: no CE code, no document named, and Studio Pro will not open the project. The recurring cause is a reference whose SHAPE is wrong, the recurring remedy is refusal in both passes, and `mx check` at 0 errors is not evidence the project opens. - silent-property-drop (22). A typo and a real-but-unrouted property fail identically, because the grammar accepts `Key: value` generically and a permissive allow-list turns every unrouted name into a silent drop. - check-mxbuild-drift (17). `mxcli check` is a model of mxbuild and drifts both ways. The false-positive direction stopped being cosmetic when exec began refusing on check errors. One correction made while syncing, and recorded in the log: the silent-property-drop draft named a source file that does not exist and claimed the remedy is derived rather than enumerated. Reading the real validate_widgets.go showed both halves exist and for good reason — derived for pluggable widgets, a guarded hand-maintained union for built-ins, which have no .mpk to subtract from. Declaring a source without reading it is exactly what the sources: discipline exists to prevent, and it produced a wrong claim on the first try. Seed table and SYNC_LOG updated, per the maintain-wiki contract. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Second pass over the area. With the four from the previous commit, 205 of the 248 mdl/executor findings (83%) now belong to a named class. - platform-semantics-gaps (18). MDL is deliberately SQL-shaped and permissive; Mendix's expression language, XPath dialect, microflow variable model and entity rules are each narrower, with no syntactic marker. Also records that several reports in this class were measured and closed as correct behaviour — quoting escapes parser keywords and not platform-reserved names, `else` on a type split really is the empty flow, `create` really is non-idempotent. - duplicate-resolver-drift (23). The most common structural cause in the area, and the one whose symptoms look least alike: check vs exec, legacy vs modelsdk, write vs read, per-doctype copies. The tell is that the fix for the reported instance is obviously incomplete. - rewrite-drops-unauthored-state (13). Guard-don't-drop stated as a failure class: the loss is invisible at every checkpoint, the most expensive variant is identity rather than content, and a delete-then-create replace opts out of every protection there is. - flow-graph-geometry (10). A microflow is a graph with coordinates and mxcli generates both. Geometry fails ugly, wiring fails invalid, and a flow that looks redundant is often load-bearing. - integration-contract-drift (30). The one area where neither mxcli check nor mxbuild is an oracle, so a silent downgrade can return HTTP 200 and every signal reads as success. Every sources: path verified to exist and every [[wiki-link]] verified to resolve before committing — the check that caught a fabricated source in the previous pass. Seed table extended and five rows appended to SYNC_LOG.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Step 3b — the pattern pages.
docs-wiki/bug-patterns/had three pages, all synthesised on 2026-05-24 from the ~24 findings that existed then.mdl/executoralone now holds 248, and no page mentioned the area at all.205 of the 248 (83%) now belong to a named class, across nine new pages.
The classes
mxcli checknor mxbuild is an oraclemxcli checkis a model of mxbuild, and models drift both waysCREATE OR REPLACElosing what the statement did not mentionThe three worth reading first
DESCRIBE has no oracle. mxbuild never sees DESCRIBE output, so a describer that drops a property produces a valid model at 0 errors on both sides. The write path is checked; the read path is not. That is why the class accumulates, and why it bites hardest where the feature is used most —
describe → edit → execis mxcli's copy operation. Four shapes, by how long they survive: won't parse, silently drops, invents a clause nobody wrote, destroys structure (a list view's 4 specialization templates went to 0,mx checkclean on both sides).Load failure is not validation failure. No CE code, no document named, Studio Pro will not open the project. The recurring cause is a reference whose shape is wrong; the recurring remedy is refusal in both passes; and
mx checkat 0 errors is not evidence the project opens, because mxbuild's deserializer tolerates properties Studio Pro rejects.One question, two answers is the most common structural cause and the one whose symptoms look least alike. A forward reference accepted by
checkand rejected byexec, a guard that is inert on one engine, a property read by one describer and not its twin — same defect, different clothes. The tell is that the fix for the reported instance is obviously incomplete.A correction, made while syncing and recorded in the log
The
silent-property-dropdraft namedmdl/executor/validate_widget_props.go— which does not exist — and claimed the scalable remedy is "derived, not enumerated". Verifying thesources:list caught it. The realvalidate_widgets.goshows both halves exist and for good reason: derived for pluggable widgets (.mpkkeys minus mapped keys), and a deliberately generous, drift-tested union for built-ins, which have no.mpkto subtract from.Declaring a source without reading it is exactly what the
sources:discipline exists to prevent, and it produced a wrong claim on the first attempt. Everysources:path and every[[wiki-link]]in the second pass was verified before committing.Also worth recording: several reports in this area were measured and closed as correct behaviour — quoting escapes MDL's parser keywords and not Mendix's platform-reserved member names;
elseon a type split really is the(empty)flow;createreally is non-idempotent in the SQL sense the language is modelled on. Those needed a better message or a doc fix, not code.Contract
Per
maintain-wiki.md: every page carriestitle/category/last-synced/sources, opens with a Do not duplicate guardrail pointing at canonical homes, and is concept-first — no recipes, no CE tables. Seed table extended by nine rows; nine rows appended toSYNC_LOG.md.What is left
43 executor findings (17%) are still unclassified — a long tail with no shared mechanism. Then the areas no page mentions at all:
cmd/mxcli(95),mdl/backend(83),mdl/grammar(53),mdl/visitor(28).🤖 Generated with Claude Code