Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
79186ce
fix(pages): validate the widgets inside a placeholder block
claude Sep 21, 2026
f5961fa
fix(pages): resolve the image a static or dynamic image widget names
claude Sep 21, 2026
855b4f0
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-11…
claude Sep 21, 2026
832e9c8
feat(settings): manage workflow groups via MDL
claude Sep 21, 2026
e2270da
Merge pull request #580 from ako/claude/mxcli-issue-1149-5kpac3
ako Sep 21, 2026
d614dbf
fix(executor): resolve a retrieve's sort hop across ancestors and mod…
claude Sep 21, 2026
fe5a740
feat(mdl): let a sort column name the association it navigates
claude Sep 21, 2026
f501046
Merge pull request #581 from ako/claude/mxcli-issue-272-3vyyk7
ako Sep 21, 2026
10d6892
fix: session-auth OData needs X-Csrf-Token, and the vega pack said it…
claude Sep 21, 2026
71851f7
fix(check): report the members a script removes from the project (MDL…
claude Sep 21, 2026
95c1841
Bind a pluggable widget's textTemplate to an attribute (#575)
claude Sep 21, 2026
240c5aa
fix(executor): keep validation rules `create or modify entity` cannot…
claude Sep 21, 2026
3ed95a4
fix(mpr): reconcile a unit re-inserted under the ID of one just deleted
claude Sep 21, 2026
568f7be
test: regression case and finding for re-exec identity stability
claude Sep 21, 2026
65d7981
fix(view entity): write the OQL document in place instead of replacin…
claude Sep 21, 2026
839e6c2
Read text templates in the generic pluggable DESCRIBE path (#575)
claude Sep 21, 2026
b97c9ca
Merge pull request #582 from ako/claude/fix-issue-1152-av85p2
ako Sep 21, 2026
1237b5c
fix(view entity): do not judge a pass-through length mxcli does not know
claude Sep 21, 2026
31baaf5
Merge remote-tracking branch 'origin/main' into claude/fix-585-fabric…
claude Sep 21, 2026
c4f2cd6
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-56…
claude Sep 21, 2026
e2d3c64
Merge pull request #589 from ako/claude/mxcli-issue-562-32ev1o
ako Sep 21, 2026
f4b7e5c
Merge pull request #591 from ako/claude/fix-583-unchanged-insert
ako Sep 21, 2026
2494a86
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-55…
claude Sep 21, 2026
8db90cc
Merge pull request #590 from ako/claude/mxcli-issue-556-pe3m07
ako Sep 21, 2026
65f1ee7
Merge pull request #592 from ako/claude/mxcli-issue-574-ovqmv8
ako Sep 21, 2026
d554f29
Merge remote-tracking branch 'origin/main' into claude/fix-585-fabric…
claude Sep 21, 2026
14b7125
Merge pull request #593 from ako/claude/fix-585-fabricated-length
ako Sep 22, 2026
a23c6b9
Merge remote-tracking branch 'origin/main' into claude/mxcli-issue-57…
claude Sep 22, 2026
616e2d2
Measure the System module's String lengths (#584)
claude Sep 22, 2026
5abfcd1
Merge pull request #594 from ako/claude/mxcli-issue-575-yiyium
ako Sep 22, 2026
24495a1
Merge pull request #595 from ako/claude/funny-keller-rrm17w
ako Sep 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .claude/skills/fix-issue/findings/mdl-backend.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,5 @@
{"area": "mdl/backend", "date": "2026-09-20", "symptom": "`describe page` → `exec` over a **Studio Pro-authored** page reports `Replaced page`, not `Unchanged` — the rebuild is not semantically equal to what was stored, so ADR-0008's elision cannot fire and the unit churns in version control on every re-run. `mx check` is 0 errors either way. Measured on ako/TestApp Rules.RuleAction_NewEdit at 11.14.0: fourteen differences", "cause": "Four independent classes, all 'the rebuild writes a constant where Studio Pro stores a value': (1) `pageToGen` hardcoded Autofocus/CanvasWidth/CanvasHeight; (2) save_changes/cancel_changes/close_page/delete_object never wrote `DisabledDuringExecution`, and save_changes wrote `SyncAutomatically` true; (3) `AttributeRef.EntityRef` emitted only on the navigated branch; (4) `Forms$PageVariable` had only the one name field set, so the other five keys were never marked dirty", "file": "`mdl/backend/modelsdk/page_write.go` (`carryStoredPageHeader`, `bsonInt`), `widget_write.go` (four action cases + two `RegisterTypeDefaults`), `modelsdk/codec/defaults.go` + `encoder.go` (new `FalseFields`)", "insight": "**mxcli round-tripping its own output proves NOTHING about this class** — measured: the MDL bug-test reports `Unchanged` on the unfixed build too, because mxcli writes the page and mxcli describes it, so its constants agree with themselves. The reference must be a Studio Pro document; a committed CI fixture only works if it is one. **A population selected by name can confirm whatever it excluded**: the first sweep filtered `$Type` on `endswith(\"ClientAction\")`, got a tidy 'True on 82 of 82', and so missed `Forms$NoAction` (False on 83 of ~7,300) and `Forms$MicroflowAction` (5 of 81) — scan by the PROPERTY, not by a name pattern. **Hardcoded looked safe and was not**: CanvasWidth takes seven distinct values across 67 pages and the hardcoded 1200 matched 4, so a round trip moved the canvas of 63. **The int width bit this fix once**: Studio Pro stores both canvas dimensions as int64 while the gen setter takes int32, so the natural `.(int32)` assertion matched nothing — and the first unit test passed anyway because its own fixture wrote int32, i.e. the test encoded the assumption under test (bson-numeric-width). Prefer `TypeDefaults` over patching each construction site: `Forms$PageVariable` is built in three places. Remaining after the fix: 1 of 14, a pluggable-widget Object property — CE0463 territory, deliberately out of scope", "refs": ["#541", "#529"]}
{"area": "mdl/backend", "date": "2026-09-20", "symptom": "An access rule on an entity carrying `AutoOwner` (or `AutoChangedBy`) made mxbuild report the whole module as **CE0066** \"Entity access is out of date\" \u2014 and `UPDATE SECURITY`, the documented repair for exactly that error, printed `Reconciled 1 access rule(s) in module Mod` and left the error standing. Four lines reproduce it on a clean production-security app: `alter entity M.Fab add attribute Owner: AutoOwner;` + `update security;`. The original reporter bisected 9 entities and 36 rules one grant at a time behind a ~40s `mx check` to find it, because CE0066 names only the module.", "cause": "mxcli wrote a MemberAccess for the implicit `System.owner` / `System.changedBy` association, in TWO places that had to agree: the GRANT handler (`cmd_security_write.go`) and `ReconcileMemberAccesses`. Mendix maintains those members itself and treats a rule naming one as out of date. The audit DATE members were already known to work this way (issuetracker #20) \u2014 the owner/changedBy pair was assumed to be the opposite case because they are associations rather than attributes, and Mendix really does add them implicitly. Fixed by writing no entry for any of the four, and by REMOVING a stored one in the reconcile (an explicit case before the foreign-module branch, which otherwise preserves `System.*` forever on the grounds that System is not loaded).", "file": "`mdl/backend/modelsdk/domainmodel_security_write.go` (isAuditMemberRef, ReconcileMemberAccesses), `mdl/executor/cmd_security_write.go`", "insight": "**The decisive probe was removing the entry, not adding anything.** CE0066 says 'out of date', which reads as 'something is missing' and sends you looking for a member to add; the model had one too many. A build flag (`MXCLI_PROBE_NO_SYSOWNER`) that dropped the entry took the module from CE0066 to 0 errors in one mxbuild run and settled it. The same repo's earlier finding had already written the rule down \u2014 *'Ask mxbuild what it wants instead of inferring symmetry'* \u2014 and this defect is that exact inference, made in the same file for the sibling members. **A fix here is not done when the new writes are correct**: `update security` exists to repair a project an older mxcli damaged, so the reconcile has to remove the entry, not merely stop adding it. Measured separately: a stale `System.owner` entry survived even after the flag was turned off, because `!assocRefBelongsTo` preserved it as an unverifiable foreign-module reference.", "refs": ["#554", "#524", "issuetracker #20"]}
{"area": "mdl/backend", "date": "2026-09-20", "symptom": "`DROP ENTITY` left every CROSS-MODULE association pointing at the deleted entity in place. Dropping the local BY-ID (FROM) end made mxbuild 11.14.0 unable to LOAD the project: `System.AggregateException \u2026 (The given key '<guid>' was not present in the dictionary.)` at `StreamingBsonUnitReader.ResolvePostponedProperties()` \u2014 no CE code, no document named, so the obvious reading is 'the project is corrupt, restore from git'. Dropping the BY-NAME (TO) end is milder and still wrong: CE1613 at the cross-module association. `show associations` shows a raw GUID where the parent entity should be.", "cause": "`removeAssocsReferencing` swept `dm.AssociationsItems()` and asserted `*genDm.Association` per item, so the SEPARATE `CrossAssociations` collection was never looked at. Fixed with `removeCrossAssocsReferencing`, matching BOTH ends because a cross-module association addresses them differently \u2014 FROM by element id (local), TO by qualified name (another module) \u2014 called in DeleteEntity locally and in its cascade over the other domain models.", "file": "`mdl/backend/modelsdk/domainmodel_alter.go` (removeCrossAssocsReferencing, DeleteEntity)", "insight": "**Reported against a view entity; nothing about it was view-entity specific.** The reporter met it dropping view entities (whose associations are DERIVED from OQL, so there is no CREATE ASSOCIATION to undo) and filed it that way. The first probe \u2014 a view entity and its source entity in the SAME module \u2014 did not reproduce at all, and that negative is the useful one: it says the variable is cross-module, not view-ness. A plain `create association A.X from A.X to B.Y` plus `drop entity A.X` reproduces the identical crash. Two lessons: when a repro fails, vary the dimension the report did not mention before doubting the report, and treat a collection-typed `.(*T)` assertion in a cascade as a place where a sibling type hides. mxbuild's diagnostic distinguishes the two ends for free \u2014 a dangling 16-byte pointer is a LOAD crash, a dangling qualified name is CE1613 \u2014 so testing only one end proves half the fix.", "refs": ["#553", "#556"]}
{"area": "mdl/backend", "date": "2026-09-21", "symptom": "`alter settings workflows add group 'Auditors'` reports \"Added workflow group: Auditors (3 group(s))\" and writes nothing \u2014 `show workflow groups` still lists 2, and `mx check` is 0 errors either way", "cause": "`UpdateProjectSettings` overlays the workflows part field by field onto the PRESERVED raw part, so a child LIST that nothing rebuilds is carried through from disk unchanged. Adding `Groups` to the semantic model and to the read path is not enough; the write needs `settingsoverlay.WorkflowGroups(ws, rawPart)`. Identical shape to the enabled-language list the same function already documents", "file": "`mdl/backend/modelsdk/settings_write.go` + `mdl/settingsoverlay/settingsoverlay.go` (`WorkflowGroups`)", "insight": "For anything under Settings$ProjectSettings, the executor's success message proves NOTHING \u2014 it reports the in-memory model, and the overlay is where a list quietly fails to land. Assert on the re-read document, not the handler's output. Two more things a reference project settles in one dump and a guess gets wrong: the `Groups` typed-array marker is 2, not the 3 every other settings child list uses (`ArrayMarker` preserves a stored one, but the fallback matters on a fresh list), and the element's `$ID` is the RUNTIME's identity \u2014 a booted 11.13.0 app keys `system$workflowgroup.modelguid` on it, byte-identical once the .NET GUID field order is undone, so re-minting it on a description edit would orphan every group membership with a perfectly valid model. Control: deleting the one overlay call reproduces the symptom verbatim. mendixlabs/mxcli#272", "refs": ["mendixlabs/mxcli#272"]}
{"area": "mdl/backend", "date": "2026-09-21", "symptom": "`CREATE OR MODIFY VIEW ENTITY` that changed ONLY the OQL printed `Unchanged view entity: \u2026` while `describe entity` showed the new query stored. Changing the attribute list as well reported `Modified` correctly, which is why it hid. Also: the OQL document's unit was replaced under a FRESH GUID on every run, even a byte-identical one, so an MDL-generated project could never come back clean in git (one of the four units #556 measured).", "cause": "A view entity's OQL lives in a separate `DomainModels$ViewEntitySourceDocument` unit, and the executor DELETED it and INSERTED a fresh one on every write. `ReportMutation` downgrades the verb when writes were offered and none landed, but the counters are incremented only at the update choke points (`writer_core.go` reconcileWithStored / MoveUnit) \u2014 `InsertUnit` is not counted at all. So the domain-model unit was offered and correctly elided, the OQL write was invisible, and the report believed the half it could see. Fixed with `WriteViewEntitySourceDocument`, which keeps the stored unit's id and goes through `UpdateRawUnit` \u2192 reconcile: an identical query is elided, a changed one lands and is counted, duplicates are still cleared.", "file": "`mdl/backend/modelsdk/move_view_write.go` (WriteViewEntitySourceDocument, encodeViewEntitySourceDocument), `mdl/executor/cmd_entities.go`", "insight": "**The first fix that comes to mind \u2014 count InsertUnit \u2014 would have swapped a false \"Unchanged\" for a false \"Modified\".** Measuring before changing is what caught it: re-running a BYTE-IDENTICAL script still re-minted the source document's unit id, so counting inserts would have made every view-entity statement report Modified forever. The right fix was the one ADR-0008 already mandates (wire the write path to canon.Reconcile), and it fixes the churn and the verb together. Generalisation worth remembering: any content that reaches storage through `InsertUnit` is invisible to the elision check, so a statement whose only landing write is a NEW unit can still be mis-reported \u2014 `MoveUnit` has a comment explaining it was counted for exactly this reason, and insert/delete were missed. Control the fix on the identical re-run, not just the changed one.", "refs": ["#583", "#556", "#910"]}
Loading
Loading