Sync mendixlabs/mxcli main into ako/mxcli main - #689
Merged
Merged
Conversation
An entity access rule carries a 'default rights for new members' setting (None / ReadOnly / ReadWrite) that decides what access a newly added attribute or association inherits. A rule enforcing a safe default - so that adding an attribute can never silently grant write access - cannot be written today, because the value is neither stored in the catalog nor exposed to Starlark. The builder already reads it: entityAccessFromMemberRights derives read/write from rule.DefaultMemberAccessRights and then discards the value. This stores it instead. Modelled on XPathConstraint, which is likewise a property of the rule rather than of the access type and is already repeated across the rows one rule produces. Non-entity permissions (microflow, page, OData) write NULL.
A 'Call REST service' activity has a 'Use a timeout' toggle and a timeout in seconds. Neither reaches a custom lint rule, so the rule 'every outbound REST call must have a timeout' cannot be written: a rule can identify a RestCallAction but learns nothing about how it is configured. Storage names verified against a real MPR with 'mxcli bson dump': "TimeOutExpression": "300" "UseRequestTimeOut": true Note the seconds are stored as an expression string, not an integer, and that UseRequestTimeOut was not read at all - microflowActionFromGen built a RestCallAction without it, so the value was lost on read. Changes: read UseRequestTimeOut in microflow_read_actions.go, carry it on sdk/microflows.RestCallAction, store both it and the existing TimeoutExpression on the activities table, and expose them as use_request_timeout / timeout_expression. Follows the ServiceRef/ActionRef precedent. Read side only. microflow_write.go currently writes UseRequestTimeOut as a hardcoded true, which will silently flip a false back to true on rewrite - a separate bug, left alone here to keep this change scoped to linting.
A while loop builds the same Microflows$LoopedActivity as a for-each loop, which has no Caption property, so @caption on it was dropped by exec. MDL042 was raised only in the LoopStmt case; it now lives in checkCaptionOnLoop and is called for WhileStmt too, pointing to @annotation instead.
…adicts Review follow-up on mendixlabs#1188. MDL042 now tells the author a loop's @caption is dropped because the activity has no Caption property -- while two files away the builder still ran case *microflows.LoopedActivity: // LOOP / WHILE activities can carry a caption just like splits activity.Caption = ann.Caption and the describer still emitted @caption for one. Nothing read either back: generated/metamodel -- the arbiter -- declares no Caption on Microflows$LoopedActivity, microflow_write.go sets none on the gen object, and the reader therefore cannot populate one. The next contributor reads the builder, concludes the new warning is wrong and deletes MDL042, reopening mendixlabs#1187 from the other side. Measured before deleting anything, with the UNMODIFIED branch build against a Mendix 11.6.6 project: `@caption` on a loop and on a while are both absent from `describe microflow` after `exec`, while `@annotation` on either round-trips. So the value died at the gen boundary and the assignment only ever populated an in-memory field. That is also why the code survived: three tests asserted it. They tested the semantic object, never storage, so they passed throughout and would have failed on the correct fix. Inverted rather than deleted, each naming the measurement: TestLoopCaptionPreserved -> TestLoopCaptionNotStorable TestWhileLoopCaptionPreserved -> TestWhileLoopCaptionNotStorable TestEmitObjectAnnotations_LoopCaption -> ..._LoopCaptionNotEmitted The describe test's real value was mdlQuote escaping, which TestMdlQuote_* already covers directly, so retargeting loses nothing. Reinstating the assignment fails the two builder tests -- checked. Also adds the bug-test script the checklist asks for, covering both captions (MDL042 x2) and both @annotation forms (silent), and keeps sdk/microflows LoopedActivity.Caption with a comment saying it cannot be stored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
From the review of mendixlabs#1188. The fix added MDL042 for a @caption on a while loop -- telling the author the loop activity has no Caption property -- while the builder two files away still assigned one, under a comment saying loops can carry captions, and the describer still emitted it. Nothing read either back. The part worth recording is why such code survives: it had three tests. All asserted the caption was carried, all against the semantic object and none against storage, so they passed throughout and failed only when the dead code was removed. A reviewer who stops at "the tests pass" concludes the capability is real. The canonical fix therefore carries the measurement step -- exec then describe on a real project with the UNMODIFIED build, so the deletion rests on the stored document rather than on reading the codec -- and the instruction to invert those tests rather than delete them, keeping any half still true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…caption-mdl042 fix(check): report MDL042 for @caption on a while loop (mendixlabs#1187)
…gs-row-32 docs(review): record the dead-code-beside-a-new-diagnostic pattern
…timeout feat(lint): expose the Call REST service activity's timeout
The matrix claimed two shipped document types were unavailable, which is the
failure its own "Keeping this honest" note warns about -- a row claiming a gap
that has since been filled sends people to Studio Pro for work mxcli can do.
- Microflow rules sat under "Not Yet Implemented" ("no MDL surface at all")
while CREATE [OR MODIFY] RULE ships with a skill, rules.mdl, a
`microflow.rule` syntax topic, a CATALOG.RULES view and rule REFS edges.
- Message definitions likewise: SHOW / DESCRIBE / CREATE OR MODIFY / DROP /
ALTER all ship, with tests and examples.
Both now have rows in Core Document Types instead.
Layouts were recorded as read-only in four places -- the row's CREATE, OR
MODIFY, DROP, ALTER, Examples, Tests, Skills and Syntax cells were all N, and
three gap lists repeated "Read-only". All eight are Y. OR MODIFY was verified
at exec rather than parse: `create or replace` reports Created then Unchanged,
and `create or modify` over the stored layout reports Unchanged.
Sixteen Examples cells corrected against the doctype-tests listing, including
two that cited the wrong file -- Task Queues and Scheduled Events both pointed
at 21 (import/export mappings) and the mapping rows pointed at 06 (the REST
client).
Rule counts are measured, not remembered: 19 built-in (`lint --list-rules`
with no project rules dir) and 31 Starlark (`.claude/lint-rules/*.star`). Four
different wrong pairs were in circulation across five live docs, one claiming
41 built-in rules. CHANGELOG and the dated eval proposal are left alone: they
are records of a past state, not claims about the present.
The guard could not have caught any of it. TestCapabilityDocsDoNotClaim...
reads only the "Not Yet Implemented" section and checks a hand-maintained list
of seven capabilities naming neither rules, message definitions nor layouts.
So the list is hoisted to `shippedCapabilities`, extended with all three, and a
second test asserts that "Missing Syntax Topics" may not list a capability
whose `mxcli syntax` topic resolves -- a flat contradiction, which is what
makes it mechanically assertable. It is deliberately not extended to the
Skills and Examples gap lists, where an entry can be true at the same time as
a syntax topic exists (Regular Expressions has a topic and no skill).
Checked by reinstating all three false claims: two tests fail, naming each.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
From the review of mendixlabs#1181. A column added to createTables without bumping CatalogSchemaVersion: the version guard only drops tables when the version CHANGES, and CREATE TABLE IF NOT EXISTS never adds a column, so every user with a cached catalog keeps a table the new SELECT cannot read. Measured: activities_for yielded 302 activities on main and 0 on the branch against the same cache file, with `no such column: UseRequestTimeout` and `mxcli lint` exiting 1. `mxcli report` runs the same rules through the same LintContext and never calls QueryErrors(), so there the same stale cache scores the project silently. The canonical fix carries the reproduction, because the obvious attempt does not reproduce it: the cache has to actually be REUSED. Building it with one `-p` spelling and running the new binary with another invalidates on "MPR path changed" and rebuilds, and a default lint run builds a fast catalog with zero activities — either way the run is green and the bug invisible. Confirm the output says "Loading cached catalog … (from cache)" first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…trix-audit docs(matrix): audit the feature matrix against what actually ships
…gs-row-33 docs(review): record the unbumped catalog-schema-version pattern
…mber-rights feat(lint): expose the access rule's default member access rights
Resolve the only conflict, CHANGELOG.md [Unreleased]: keep this fork's mendixlabs#750 Changed/Fixed entries and add upstream's mendixlabs#1187 while-loop MDL042 entry to the Fixed list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QDNtypktPBXPyyTChWGKrb
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.
Summary
Brings the 14 upstream commits from
mendixlabs/mxclimain(up to86d395ee, mendixlabs#1179) into this fork. The sync was blocked by a single conflict.Upstream changes included:
@captionon awhileloop (@caption on a while loop is dropped with no MDL042 — only for-each loops are warned mendixlabs/mxcli#1187), and the dead loop-caption code is removedConflict resolution
The only conflict was in
CHANGELOG.md→## [Unreleased]. Both sides added entries there:### Changed/### Fixedentries (DynamicClasses and OData credentials as expressions)### Fixedentry for@captionon awhileloop (@caption on a while loop is dropped with no MDL042 — only for-each loops are warned mendixlabs/mxcli#1187)I kept all of the fork's entries and added the upstream bullet at the end of the fork's
### Fixedlist. Every other shared file merged without a conflict, includingmdl/executor/validate_microflow.go,mdl/linter/context.go,sdk/microflows/*, the quick-reference docs and the findings.jsonl(merge=union).Validation
make build: passesmake test: passes, no failuresmake check-findings: passes (1233 records)go vet ./mdl/... ./sdk/...: only warns about unreachable code in the generatedmdl/grammar/parser/mdl_parser.goMerge with a merge commit, not squash, so that
mainrecords the upstream commits as ancestors and the next sync starts from this point.🤖 Generated with Claude Code
https://claude.ai/code/session_01QDNtypktPBXPyyTChWGKrb
Generated by Claude Code