Skip to content

Sync ako/mxcli: typed retrieve constraints, security reference checks, model-level MDL-MAP04 - #1336

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

ako merged 34 commits into
mendixlabs:mainfrom
ako:main

Conversation

@ako

@ako ako commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into mendixlabs/mxcli:main: 4 commits since #1334, landed in the fork through PRs ako#1021, ako#1023 and ako#1027.

Check

  • Retrieve constraints comparing an attribute with a variable of an incompatible type are reported by check --references (Retrieve XPath comparing an attribute with a variable of another type (enum vs String, String vs DateTime, Integer vs String) passes check; mx check CE0161 #1325). Examples are Kind = $Filter with $Filter a String, or Email >= $Since with a DateTime; these were CE0161 at build time. The compatibility table is measured on mxbuild 11.14.0 over 8 attribute × 8 variable types, and it is not plain type equality (a String variable against a DateTime attribute builds clean; Integer/Long/Decimal mix freely).
  • GRANT / REVOKE and user-role statements resolve what they name. That covers entities, documents, members, module roles and user roles, against the project and what the script has created so far. All of these printed "Check passed!" before, and create user role / alter user role … add / create demo user wrote unknown roles for mxbuild to report as CE1613.

Lint

claude and others added 24 commits October 7, 2026 17:57
The lint rules cannot import the executor, and a model-level MDL-MAP04
(mendixlabs#1319) needs to decide a mapping's root shape exactly
the way the builder and the check-time rule do. The executor keeps thin
delegating wrappers so its call sites and tests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BCeVsRwSYaVoEtimYbKJAi
… mistyped variable

A retrieve constraint comparing an attribute with a variable of another
type (`Kind = $Filter` with $Filter a String, `Email >= $Since` with a
DateTime, `Visits = $Text` with a String) passed `check --references`
and exec, then mx check reported CE0161 "Error(s) in XPath constraint."
(mendixlabs#1325).

The reference pass now types each `attribute <op> $var` comparison from
the retrieved entity (script declaration or stored domain model) and the
flow's parameters and declared variables. The compatibility table is
measured on mxbuild 11.14.0 over 8 attribute x 8 variable types for `=`
and `>=`: it is not type equality — a String variable against a DateTime
attribute builds clean, Integer/Long/Decimal mix freely, and an
enumeration needs the same enumeration. Untyped sides stay silent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EsWAxrmEd7MBkay2zNpXNS
…odel (MDL-MAP04)

mendixlabs#1319: an import activity already in the model that
stores Studio Pro's First (ForceSingleOccurrence / Range.SingleObject)
over an OBJECT-rooted mapping passed lint ("No issues found.") and
mx check (0 errors), then threw
  key not found: Path(QName(None,),None,)
when it ran. check's MDL-MAP04 refuses the statement, but only in a
script, so activities written by v0.24.0 or with exec --no-check were
found by nothing.

lint now runs MDL-MAP04 against stored import-from-mapping and REST
returns-mapping activities. It keys on the mapping's root shape via the
shared types.JsonMappingRootIsList, so a list-rooted mapping's
legitimate First (same flag pair) is not reported, and a shape that
cannot be established is left alone.

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

`validation feedback $Input/Input_Person` named an association by its bare
name, but the builder decided attribute vs association from the dot count
alone, so it wrote the attribute reference G45.Input.Input_Person and mx
check failed:

  [CE1613] "The selected attribute 'G45.Input.Input_Person' no longer exists."

A dotless member now resolves as an attribute in the generalization chain
first (unchanged), then as an association the entity or an ancestor owns
(new DeclaringAssociationRef, searching Associations and CrossAssociations in
each link's module), else keeps the old spelling. The result is the same
BSON the qualified $Input/G45.Input_Person produces.

Verified on Mendix 11.14.0: pre-fix binary reproduces the reported CE1613,
fixed binary checks at 0 errors (both mdl 0 and mdl 1 scripts).

Fixes mendixlabs#1322

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014WGYmiHmEHxNSfCt2XjHVu
`mxcli check -p --references` resolved none of a security statement's
references: a grant on System.Nope or M.Nope, to M.NopeRole, on a missing
microflow/nanoflow/page/service, or naming a missing member all printed
"Check passed!". exec refused the grants after the earlier statements were
written, and wrote the unknown roles of `create user role`, `alter user
role … add` and `create demo user` into project security unresolved, for
MxBuild to report as CE1613.

validateGrantReferences walks the program in statement order and resolves
each statement's entity, document, member, module roles and user roles
against the project and what the script has created so far — including the
<Module>.User role exec auto-creates with the first document of a role-less
module. It refuses what exec refuses, form by form: an unknown role on a
document REVOKE, which exec reports as a no-op, still passes, and so does a
System module role in a user role; a grant on any System entity is refused,
as exec refuses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings in #1020 (signature-type checks, same validate.go) and resolves the
findings-file conflict GitHub's server-side merge reports for appends to
mdl-executor.jsonl.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…is read as the name (mendixlabs#1282)

`call java action M.A(Flow = M.SUB_Target⏎  );` was reported storing the
line break in the reference (CE1613 "The selected microflow
'MyModule.SUB_Target⏎' no longer exists"). The visitor keeps whitespace
before `)` on the argument as an ast.SourceExpr; the Microflow-typed path
switched on that wrapper. #898 had since trimmed the stored text, so on
this tree the same script is instead refused by check --references and
exec as "not MyModule.SUB_Target" (mendixlabs#1210's guard saw a SourceExpr, not a
QualifiedNameExpr), and `Flow = empty⏎)` was refused too.

javaActionArgumentValue unwraps the SourceExpr for the refusal, the
`empty` marker and the stored name. Expression (basic) arguments keep
their source text unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F6s3o3b9ZxCtX2Fgw2MRMc
`create published odata service M.S ( …, Authentication: (basic,
session, microflow M.F) )` replaces the trailing `authentication …`
clause (R9), matching the published REST service. The property also
takes `none`, which the clause could not say, and `alter published
odata service … set ( Authentication: … )` now sets it — before, the
only way to change a service's authentication was to restate it. Left
out, create-or-modify and alter keep the stored setting.

The clause is a registered alias (MDL-DEPR139): it builds the same
statement, warns, is refused from mdl 2, and `fmt --upgrade` moves it
into the list, on its own line when the list is one property per line.
A clause naming a method MDL has no keyword for is reported, not
rewritten. The examples, skills, syntax help and quick references are
migrated with it, so the conformance gate holds.

describe prints the property in the stored order. A setting MDL cannot
state (a microflow without the Microflow method, or the reverse) is now
a comment: printing `Microflow M.F` for it added the method on replay.

describe → exec of ako/TestApp's three Studio Pro OData services writes
no unit. mx check on 11.14.0 (security production) is clean for
(session, basic) with a role, none without roles, and a service
switched to none by alter.

Follow-up to mendixlabs#1331.

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

`Entity[a][b]` inside a constraint was a parse error — "missing ']' at '['"
when the path ended on the step, "mismatched input '/' expecting ';'" when
it went on — because xpathStep admitted at most one predicate. Mendix
accepts the form.

xpathStep now takes any number; ast.XPathStep.Predicate becomes Predicates,
in source order, and every serializer and walker loops over them. They are
kept apart rather than and-ed, so describe reproduces what was written and
a `[reversed()]` step predicate is never folded into a condition.

Control: before the fix the new test failed with the reported errors, and
ParseXPathConstraint returned ok while dropping the second predicate.
mx check (11.6.6): 0 errors for the two-predicate form and for the
single-predicate `and` control.

Refs mendixlabs#1281

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lo6eVewuCWHhHZZrE9LPoy
A lint rule had no way to read the enabled project languages: strings()
has a row for every stored translation, and a fresh en_US-only app already
carries nl_NL texts, so enabling a language changed nothing a rule could
see, and a rule calling languages() failed with "undefined: languages".

languages() returns one `language` struct (code, is_default,
check_completeness) per language enabled in the project settings, read
through LintReader.GetProjectSettings like project_security(). It needs
no full catalog build; a failed settings read fails the rule rather than
answering [].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CEhfut5q23z8UtgD762ZPc
Open question 1 of the published REST authentication proposal is done on
this branch: the OData clause is now the Authentication property, with
the clause as alias MDL-DEPR139.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M7kpwBjefUzJwfyembWZKh
activities_for() and CATALOG.ACTIVITIES returned every microflow,
nanoflow, Java action and JavaScript action call with action_ref="" and
every delete with entity_ref="", although refs_from() had both targets
(mendixlabs#1305). describeAction had cases only for REST/web
service/OData calls and create/retrieve.

- ActionRef is the called document for a microflow, nanoflow, Java or
  JavaScript action call.
- EntityRef is a delete's entity, resolved through the same per-flow
  variable map refs_from()'s delete edge uses (buildVarEntityMap).
- New QueueRef column / queue_ref field: the task queue a microflow or
  Java action call runs in, so a loop-scoped rule can skip a call that
  runs asynchronously.
- A JavaScript action call gets a refs `call` row (JAVASCRIPT_ACTION),
  so show callers and refs_from() see it.

Catalog schema bumped to 23. Control: the HEAD binary on the issue's
repro prints exactly the reported empty rows; with describeAction's new
cases removed, TestActivityCallAndDeleteTargets fails with every target
"".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FuqAgqwKgZXJWEUZWbZSpV
Add MDL-MAP04 lint rule to detect import activities on object-rooted mappings
Validate retrieve constraint operand types against mxbuild rules
fix(check): resolve what GRANT/REVOKE and user-role statements name
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

AI Code Review

Review Summary

This PR syncs changes from ako/mxcli:main to mendixlabs/mxcli:main, implementing three key improvements:

  1. Type validation for retrieve constraints (issue Retrieve XPath comparing an attribute with a variable of another type (enum vs String, String vs DateTime, Integer vs String) passes check; mx check CE0161 #1325)
  2. Reference resolution for GRANT/REVOKE and user-role statements
  3. Model-level lint rule for MDL-MAP04 (issue lint misses import-from-mapping activities stored as First on an object-rooted mapping (runtime: key not found: Path(QName(None,),None,)); MDL-MAP04 only checks scripts #1319)

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • Thorough implementation: Each feature properly wired through the full pipeline where applicable
  • Comprehensive testing: Extensive test cases using real fixtures (PedApp) covering edge cases
  • Code quality: Proper refactoring to eliminate duplication (mapping shape helpers moved to shared package)
  • Documentation: Updated skill files, syntax help, and built-in rules documentation
  • Atomic commits: Each logical change in its own commit
  • Error handling: Clear, actionable error messages with helpful hints
  • Integration: Proper connection to existing validation/lint pipelines

Recommendation

Approve - The PR successfully addresses the reported issues with high-quality implementations that follow project patterns and improve the tool's ability to catch problems early. All validation is properly integrated, tests are comprehensive, and documentation is updated appropriately. No critical issues identified.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

AI Code Review

Review Summary

This PR syncs changes from ako/mxcli:main to fix three specific issues:

  1. Retrieve operand type validation (Retrieve XPath comparing an attribute with a variable of another type (enum vs String, String vs DateTime, Integer vs String) passes check; mx check CE0161 #1325) - adds check --references detection for type mismatches in retrieve constraints
  2. Grant/REVOKE reference resolution - makes check --references validate security statement references against the project
  3. MDL-MAP04 lint rule enhancement (lint misses import-from-mapping activities stored as First on an object-rooted mapping (runtime: key not found: Path(QName(None,),None,)); MDL-MAP04 only checks scripts #1319) - extends existing lint rule to detect problematic import activities already in the model

The changes are well-scoped, thoroughly tested, and follow the project's architectural patterns. No critical issues were found.

What Looks Good

  • Comprehensive test coverage: New unit tests for all three fixes, integration tests using real PedApp fixture, and MDL example files demonstrating the bugs
  • Proper full-stack wiring:
    • Grant reference validation: Added to validate.go (microflow/nanoflow paths) with corresponding executor handler
    • Retrieve operand validation: Added to validate.go with test coverage
    • MDL-MAP04 lint rule: Registered in cmd_lint.go, uses shared helpers from mdl/types, includes model-level checking
  • Thoughtful refactor: Moving import-mapping root-shape helpers to mdl/types eliminates duplication between lint rule, builder, and check-time validation
  • Clear documentation: Updated skills and CHANGELOG.md explain the changes
  • Robust error handling: Validation functions properly handle disconnected states and edge cases

Minor Issues

  1. Inconsistent error message formatting in validate_grant_refs.go:

    • Some error messages use past tense ("does not exist") while others use present tense ("is not found")
    • Suggestion: Standardize on present tense for consistency with other mxcli validation messages
  2. Missing module existence check in grant reference validation:

    • While the validation checks role existence within a module, it doesn't explicitly validate that the module itself exists
    • However: The test cases show it does catch non-existent modules (e.g., "NopeMod.User" reports role not found), suggesting the implementation implicitly handles this by checking the module's role list
  3. Slightly complex control flow in grantResolver.recordAutoDocumentRole:

    • The nested conditions for detecting when to auto-create <Module>.User role are correct but dense
    • Not critical: The logic aligns with platform behavior and is well-tested

Recommendation

Approve the PR. The changes:

  • Fix real user-reported bugs with Mendix Studio Pro compatibility
  • Follow the project's validation patterns (lazy loading, statement-order processing)
  • Include appropriate test coverage at unit, integration, and example levels
  • Maintain backward compatibility (no breaking changes to MDL syntax)
  • Address the specific overlap concerns (no duplication with existing features)

The PR successfully implements the required full-stack validation for the fixed issues while maintaining the project's quality standards. The minor issues noted are documentation/refinement opportunities that don't block merging.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

feat(odata): published OData authentication as a property
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

AI Code Review

Review Summary

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

  • File length in mdl/executor/validate_grant_refs.go: At 651 lines, this file is quite long and may impact maintainability. While the complexity is justified by the comprehensive reference validation logic, consider splitting it into smaller focused files (e.g., separate validators for entity grants, microflow grants, user roles) in a follow-up refactor.

What Looks Good

  • Thorough bug fixes:
  • Excellent test coverage:
    • New unit tests for all validations (validate_retrieve_operand_types_test.go, validate_grant_refs_test.go).
    • Integration test using PedApp fixture for grant references (check_grant_references_pedapp_test.go).
    • Comprehensive lint rule tests (import_range_object_mapping_test.go).
    • OData authentication tests covering visitor, executor, upgrade, and describe roundtrip scenarios.
  • Full-stack consistency:
    • OData authentication changes properly span AST (ast_odata.go), visitor (visitor_odata.go), executor (cmd_odata.go), and tests.
    • Mapping shape logic centralized in mdl/types/mapping_shape.go shared by builder, check, and linter.
    • No missing pipeline components for modified features.
  • Correct MDL syntax handling:
    • Property definitions correctly use colon (Authentication: ...).
    • AS keyword only used in appropriate mapping contexts (not present in this PR).
    • Statements read as English with standard CRUD verbs.
    • No keyword overloading or symbolic syntax.
  • Atomic commits: Each commit addresses a single concern (retrieve types, grant references, lint rule, OData

Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

AI Code Review

Review Summary: This PR syncs changes from a fork implementing three main features: typed retrieve constraints (#1325), security reference checks (grant/revoke statements), and model-level MDL-MAP04 lint rule. It also includes unrelated OData authentication property improvements. The changes follow good practices with thorough testing and full-stack wiring where applicable.

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

claude and others added 3 commits October 8, 2026 04:45
Every expression spelling of a column's `Visible:` — `$showPrices`,
`if … then … else …`, `not(…)`, `[cond]` — passed check and exec and was
stored as `true`, so the column was always visible. The visitor lowers an
expression to the key VisibleIf and keeps only plain values under
Visible; the column writers read only visible/Visible.

- types.ItemPropertyAliases: `visible` <- `VisibleIf`, used by the widget
  engine on create and by ALTER `set (Visible: …) on grid column(…)`,
  which refused it as "column property VisibleIf not found". Widget defs
  regenerate at generator version 18.
- columnSpecProperties: ALTER insert/replace column hands the builder
  Visible (and DynamicCellClass in any case) as the string it reads; a
  `Visible: false` bool was dropped there too.
- describe prints the bare expression, which now round-trips.
- MDL-WIDGET43: a column's visibility is evaluated once for the grid, with
  no row object, so $currentObject there is CE0117 (measured on 11.14.0).
  check refuses it on create, insert and set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P65SqmwwvbWdJVRwhYiMQw
fix: store a bare association name in validation feedback as an association (mendixlabs#1322)
fix: a Microflow-typed Java action argument followed by a line break is read as the name (mendixlabs#1282)
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

AI Code Review

Review Summary

This PR syncs changes from ako/mxcli:main to mendixlabs/mxcli:main, implementing three main features:

  1. Typed retrieve constraints validation (issue Retrieve XPath comparing an attribute with a variable of another type (enum vs String, String vs DateTime, Integer vs String) passes check; mx check CE0161 #1325) - validates attribute/variable type compatibility in XPath constraints
  2. Security reference resolution (grant/revoke statements) - resolves referenced entities/roles against project state
  3. Model-level MDL-MAP04 lint rule (issue lint misses import-from-mapping activities stored as First on an object-rooted mapping (runtime: key not found: Path(QName(None,),None,)); MDL-MAP04 only checks scripts #1319) - detects import activities storing "First" over object-rooted mappings

The changes are well-scoped, thoroughly tested, and follow project conventions. No critical issues were found.

What Looks Good

  • Complete validation coverage:
    • Retrieve operand types validation handles all type combinations per mxbuild 11.14.0 measurements
    • Grant/reference validation covers all security statement types (entity/microflow/nanoflow/page/OData/REST/service) and user/role statements
    • MDL-MAP04 lint rule correctly identifies the runtime failure scenario and provides helpful remediation
  • Thorough testing:
  • Proper architectural layering:
    • Validation logic placed in executor layer (consistent with other validations)
    • Lint rule shares mapping shape logic with builder via mdl/types/mapping_shape.go
    • OData authentication property refactor properly handles deprecation and backward compatibility
  • Documentation updates:
    • CHANGELOG entries
    • Skill updates for JSON mappings, OData sharing, and lint rule writing
    • Quick reference and internals documentation updated
  • Atomic commits: Each sync commit addresses a single concern (retrieve types, grant references, MDL-MAP04/refactor)

Minor Issues

  1. In mdl/executor/validate_grant_refs.go:

    • Line 415: g.recordAutoDocumentRole(s.Name.Module) could be simplified to g.recordAutoDocumentRole(s.Name.String()) since QualifiedName.String() returns the module part when name is empty (though current usage is correct)
    • Line 528: Comment says "the statement's exec refuses an unknown role" but the function handles both grant and revoke - minor wording inconsistency
  2. In mdl/executor/validate_retrieve_operand_types.go:

    • Line 45: The comment mentions String variable against DateTime attribute builds, but the compatibility table shows this is actually allowed (correctly implemented in code)
    • Line 147: xpathOperandTypeName could use a guard clause for enumeration to reduce nesting
  3. In mdl/linter/rules/import_range_object_mapping.go:

    • Line 100: The violation message repeats the mapping name twice ("stores Studio Pro's First (%s), but %s is object-rooted") - slightly redundant but not incorrect
    • Line 128: Suggestion mentions $X = import from mapping ... ($Json); but should note that $Json needs to be defined elsewhere (though this is implied by context)
  4. In documentation updates:

    • docs-site/src/internals/catalog-schema.md: Added authentication_set column but no explanation of its purpose (though self-evident from context)
    • docs/01-project/MDL_QUICK_REFERENCE.md: Minor wording improvements possible in OData authentication section

Recommendation

Approve. The changes are:

  • Correctly implement the requested features per issue descriptions
  • Follow the full-stack validation pattern (though these are validation/lint only, no new MDL syntax)
  • Include comprehensive test coverage
  • Maintain backward compatibility (especially for OData auth property refactor)
  • Follow project architecture and code style guidelines
  • Have appropriate documentation updates

The minor issues noted are trivial and do not affect correctness. No changes are requested.


Note: As this is a sync PR, the changes were previously reviewed in the fork repository. This review focuses on verifying the changes meet mxcli's contribution standards as outlined in CLAUDE.md. All validation and linting changes are properly scoped and tested.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

ako added 2 commits October 8, 2026 07:26
fix: write a DataGrid 2 column's Visible expression
@ako
ako merged commit 313c7ef into mendixlabs:main Oct 8, 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