Skip to content

Sync ako/mxcli: check -p resolves seven more reference kinds, role-based visibility, legacy grids - #1506

Merged
ako merged 34 commits into
mendixlabs:mainfrom
ako:main
Oct 14, 2026
Merged

ako merged 34 commits into
mendixlabs:mainfrom
ako:main

Conversation

@ako

@ako ako commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into mendixlabs/mxcli:main: 23 commits since #1503, landed in the fork through PRs ako#1261 and ako#1358–ako#1365.

check -p resolves more references (#1472)

Each of these passed check and exec, then failed at mxbuild (measured on 11.13.0):

  • ALTER PAGE/SNIPPET/LAYOUT targets, and the flows, pages, snippets and entities inserted or replacing widgets name.
  • DataGrid 2 column attributes against the grid's entity (CE1613).
  • Members named in an access rule's where XPath (CE1613), judged case-insensitively as mxbuild does.
  • An entity event handler's microflow.
  • Module.Enum.Key in expressions (CE1613).
  • The entities a view entity's OQL reads from (CE0174).
  • The check-syntax skill now lists what -p resolves and what it still does not.
  • MDL055 also covers widget datasource XPath: two hops ($currentObject/Mod.B/Name) is CE0161 in combo box, list view, data grid 2 and gallery (Combo box data-source XPath comparing with $currentObject/<association> passes check, then mxbuild CE0161 #1466).

Pages

Marketplace

Tests, docs, CI

claude and others added 30 commits October 14, 2026 12:16
… into the module

An association a local module owns that points at an entity of the
marketplace module was never saved by --save-edits, and the update did not
refuse over it because the module itself was unedited. The update then
deleted it: DROP MODULE removes the module's entities and DeleteEntity
cascades into every other domain model, removing cross-module associations
that reach a deleted entity by name (mendixlabs#1502).

SnapshotModule now also captures those associations as Snapshot.Dependents
(from the catalog's associations view). They are carried on the drift
report, saved as association-<Module>_<Name>.mdl, counted by the update's
local-edit gate, listed by `marketplace diff`, and named in the update
summary. They are kept out of LocallyModified: they are not edits to the
marketplace module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FWsKVhYYsv4mgsgUwEGp3z
…ields (mendixlabs#1459)

findInWidgetChildren walked a Forms$DataGrid's ControlBar.Items but not its
Columns or DataSource.SearchBar.Items, although both carry a stored Name, and
describe printed the grid as one opaque comment line. The mutator now walks
both lists (gated on $Type), and describe prints the grid's data source,
buttons, columns and search fields by stored name, every line a comment.
Tests: pagemutator drop/set Caption on a column and a search field (siblings
byte-identical); executor describe test. Stubbing either fix fails the tests
with `widget "column14" not found` / the opaque line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…bs#1461)

A row is built outside buildWidgetV3, pages.LayoutGridRow had no slot, describe
never read Forms$LayoutGridRow.ConditionalVisibilitySettings and the writer left
the null default: describe -> exec DESTROYED a Studio Pro row's condition (row
always visible). Now read, printed, built (shared childVisibility with tab pages)
and written. Columns have no such property (0/732 stored): check warns MDL-WIDGET07.
Tests fail with each fix stubbed out; describe -> exec Unchanged on pedapp/TestApp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…endixlabs#1463)

widget init named native widgets after the last id segment (image,
radiobuttons), and the registry let a different-id definition replace a
built-in keyword; check resolved through the registry while the builder's
switch owns `radiobuttons`. Native widgets are now named native<name>, the
registry refuses a different-id def under a built-in/builder-owned keyword
(warning, still reachable by id), and lookupWidgetDef skips builder-owned
keywords (set pinned to the switch by a go/ast test). Reverting the guards
brings back "has no property Image" and the native radiobuttons resolution.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
Measured on fresh 11.13.0 and 11.14.0 projects: the reported one-hop form
[Mod.A = $currentObject/Mod.B] builds at 0 errors in a combobox, list view and
data grid 2 (stored verbatim), as do the inverted form and $currentObject/Attr.
Two hops ($currentObject/Mod.B/Name) is CE0161 in combobox, list view, data
grid 2 and gallery, and check passed it: MDL055 only saw microflow retrieves.
The page validator now applies the same hop-count rule (shared matcher).
TestDatasourceXPathVariableTraversal fails with the call stubbed out (4 flagged
cases unflagged) and passes with it; the one-hop controls stay unflagged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…mendixlabs#1459)

The conformance gate parses every MDL block in a skill; the bare
`drop column14, …` fragment was one finding over the file's allowlist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…bs#1460)

ConditionalVisibilitySettings.ModuleRoles was never read by describe, had no
MDL spelling, was written empty, and was dropped by ALTER set Visible. Add
`Visible: roles (Mod.A, ...)` (combinable with an expression/attribute
condition) on widgets, tab pages and navigation-list items; check --references
resolves the roles. Tests at describe/visitor/builder/writer/mutator layers;
each fails with the drop when its fix is stubbed out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…mendixlabs#1472)

check -p --references resolved an ALTER PAGE/SNIPPET/LAYOUT down to its
document only: the INSERT/REPLACE/DROP target widget and the flows, pages,
snippets and entities the inserted or replacing widgets name went unchecked,
so a typo passed check and stopped exec. validateAlterPageReferences now runs
exec's own target resolver against the stored document (read-only) and
validateWidgetReferences over the op widgets; targets the script adds or
renames, and SET targets (the dry run's finding), stay silent.
TestAlterPageRefs_*; stubbing the pass to return nil fails all five cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…ntity (mendixlabs#1472)

Nothing checked that a datagrid column's Attribute exists on the grid's
entity — the scope rule only asks whether a name belongs to ANOTHER entity in
scope — so a typo passed check and exec and mxbuild reported CE1613 (measured
on 11.13.0). Judged for a database-source grid in CREATE PAGE/SNIPPET and in
ALTER PAGE (new grids, and columns inserted into a stored grid whose own
source is not a flow); anything not established stays silent. A header
filter's Attribute is not judged: the column builder never writes it.
TestDataGridColumnAttrs_*; stubbing the walk fails all four reported cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…abs#1472)

grantResolver resolved a grant's entity, roles and member list but never its
XPath, so `where [M.NoSuchAssoc/…]` passed check and built to CE1613 at the
access rule (measured on 11.13.0, security level Prototype). The constraint is
now judged as exec stores it, by the walk the widget and retrieve checks use;
its script-aware resolver is factored out of the retrieve check, which also
stops judging an entity the script ALTERs (the control caught that as a false
refusal). TestCheckGrantXPath_*; removing the call fails both reported cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…endixlabs#1472)

The corpus sweep of the access-rule WHERE check against PedApp refused
doctype-tests/08, whose `status` attribute is constrained as [Status = 'Open'].
Measured on 11.13.0 at security level Prototype, that builds clean, so a
member found in another case is now found. Two controls added to
TestCheckGrantXPath_ResolvableMembersPass; both fail without the fold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
)

Neither CREATE ENTITY nor ALTER ENTITY … ADD EVENT HANDLER resolved the
microflow the handler calls; exec does (buildEventHandlers) and refuses a
missing one after the statements before it are written. Check now resolves it
against the project and the flows the script creates; an unqualified name or
an empty listing stays silent. TestEntityEventHandlerRefs_*; short-circuiting
the check fails both reported cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…#1472)

`Module.Enum.Key` in an expression was never resolved: the enumeration's
values were read for E001 but the key itself was never looked up, so a
missing one passed check and exec and mxbuild reported CE1613 "The selected
enumeration value … no longer exists" (measured on 11.13.0). Every qualified
name expression of every statement is now judged against the project's
enumeration or the one the script creates; an enum the script alters,
renames or moves, one not in the project, and an excluded flow stay quiet or
warn. TestEnumValueRefs_*; disabling the walk fails all three reported cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…ixlabs#1472)

CREATE VIEW ENTITY checked column names and types only; an unknown FROM or
JOIN entity merely left its columns untyped, and untyped columns are skipped,
so the view passed check and exec and mxbuild reported CE0174 "Cannot resolve
object name" (measured on 11.13.0). The sources (FROM, JOIN, end of a path
join) are read by extractAliasMap and resolved against the project, System
and what the script creates; an empty listing or a script-created module
stays silent. TestViewSourceEntities_*; short-circuiting fails all three.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…s not (mendixlabs#1472)

The check-syntax skill said `-p` "resolves every reference"; it now lists the
reference kinds mendixlabs#1472 added and the ones a pass still does not prove
(built-in input attributes, attributes inside an ALTER PAGE insert, enum keys
in page widget expressions). Plus the finding record for the seven kinds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
fix(pages): describe and address legacy DataGrid columns and search fields (mendixlabs#1459)
Fix marketplace update --save-edits missing cross-module associations
…dixlabs#1460)

WorkflowCommons.WorkflowAttachment_New broke getput only on its
role-based visibility; it now round-trips and the harness asks for its
entry to go. Snip_WorkflowActivityRecord_Header stays listed for its
other drifts, minus the module-role visibility it no longer has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…endixlabs#1461)

The conformance gate parses every MDL block in a skill; the bare
`row (…) { … }` fragment was one finding over the file's allowlist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…labs#1463)

TestLargeSkillsWereSplit bounds a SKILL.md body at 700 lines; the
native-keyword note took custom-widgets to 707. Same content, three lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…ile (mendixlabs#1472)

TestLargeSkillsWereSplit bounds a SKILL.md body at 700 lines, and
check-syntax was already at the bound; the list of what check -p resolves
(and does not) now lives in check-syntax/reference/references-resolved.md,
linked from the paragraph it extends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
The visibility section grew, so the generated "Find it fast" ranges were
stale; `make check-skill-index` (push-test) refuses that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
…1451)

mendixlabs#1451 reports `alter entity … add attribute` rewriting a Studio Pro index
over (createdDate, changedDate) with every segment as `Type = Normal` and
still no attribute pointer, which crashes mx check in
IndexedAttribute.get_Attribute. The converter defect is the one #1401 fixed
(indexFromGen dropped Type, indexToGen hard-coded Normal); its tests pinned
the converter pair and describe, not the reported sequence.

This adds that sequence through the real write path: seed the Studio Pro
shape below the writer, add an attribute via UpdateEntity, read the raw
segments back. Reverting either half of #1401 fails it with exactly the
reported `Type = "Normal"`. writeUnitDoc is factored out of the #1119 index
GUID helper so both tests share the unit write + ContentsHash update.

Also a bug-test MDL and a finding recording that the owner/changedBy/
association segment types (Model SDK, 11.11.0) are not checkable by mx
11.12.5 or 11.14.0 at all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SsRmTMzxstdFGNtP3HLzzc
test: pin alter-entity on a system-date index end to end (mendixlabs#1451)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5 to 6.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
fix(pages): describe and write role-based widget visibility (mendixlabs#1460)
Resolve the tab-page visibility conflict with mendixlabs#1460 (role-based
visibility): childVisibility now also attaches Visible: roles (…), so tab
pages keep main's behaviour and layout-grid rows carry roles too (DESCRIBE
prints them since mendixlabs#1460, so a row would otherwise lose them on re-exec).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
The legacy-grid note (mendixlabs#1459) grew the file without
regenerating its "Find it fast" ranges, so `make check-skill-index` fails
on main and on every branch that merges it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKmbj53BC2vuUWYmgWgfQ5
fix(pages): describe and write a layout-grid row's Visible: (mendixlabs#1461)
ako added 4 commits October 14, 2026 21:07
fix(widgets): native widgets no longer take over image/radiobuttons (mendixlabs#1463)
fix(executor): MDL055 covers widget datasource XPath (mendixlabs#1466)
fix(check): resolve seven reference kinds check -p --references skipped (mendixlabs#1472)
…etup-java-6

ci: Bump actions/setup-java from 5 to 6
@ako
ako merged commit 52be22e into mendixlabs:main Oct 14, 2026
15 checks passed
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.

2 participants