Skip to content

docs(wiki): digest the mdl/executor findings into nine bug-pattern pages - #356

Merged
ako merged 3 commits into
mainfrom
docs/bug-patterns-executor
Sep 1, 2026
Merged

docs(wiki): digest the mdl/executor findings into nine bug-pattern pages#356
ako merged 3 commits into
mainfrom
docs/bug-patterns-executor

Conversation

@ako

@ako ako commented Sep 1, 2026

Copy link
Copy Markdown
Owner

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/executor alone 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

page findings thesis
describe-round-trip-gaps 83 DESCRIBE is a second implementation of MDL, written in the opposite direction and validated by nothing
integration-contract-drift 30 OData / REST / mappings — the one area where neither mxcli check nor mxbuild is an oracle
duplicate-resolver-drift 23 one question answered in two places, and the two disagree
silent-property-drop 22 a typo and a real-but-unrouted property fail identically
platform-semantics-gaps 18 legal MDL, illegal Mendix — rules the grammar cannot carry
check-mxbuild-drift 17 mxcli check is a model of mxbuild, and models drift both ways
rewrite-drops-unauthored-state 13 CREATE OR REPLACE losing what the statement did not mention
unloadable-model-writes 12 load failure ≠ validation failure — no CE code, whole project down
flow-graph-geometry 10 a microflow is a graph with coordinates, and mxcli generates both

The 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 → exec is 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 check clean 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 check at 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 check and rejected by exec, 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-drop draft named mdl/executor/validate_widget_props.gowhich does not exist — and claimed the scalable remedy is "derived, not enumerated". Verifying the sources: list caught it. The real validate_widgets.go shows both halves exist and for good reason: derived for pluggable widgets (.mpk keys minus mapped keys), and a deliberately generous, drift-tested 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 attempt. Every sources: 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; else on a type split really is the (empty) flow; create really 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 carries title / 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 to SYNC_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

ako and others added 2 commits September 1, 2026 07:12
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>
@ako ako changed the title docs(wiki): digest the mdl/executor findings into four bug-pattern pages docs(wiki): digest the mdl/executor findings into nine bug-pattern pages Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant