Describe round trip: delete close page, $[%…%] returns, navigation-list items (#950) - #959
Merged
Merged
Conversation
…race (#951) SaveToFile now writes to a temp file in the cache's directory (VACUUM INTO, manual-copy fallback into the same temp file) and renames it over the cache. buildCatalog and refresh catalog communities no longer remove the cache first. Opening a cache at the current schema version no longer writes to it: a write on a file renamed underneath an open connection fails with SQLITE_READONLY_DBMOVED. File-backed connections get a busy_timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Starlark rule reading a struct field this mxcli does not expose is now reported at info level as "rule <ID> needs a newer mxcli (<detail>)"; other rule failures stay errors. Every rule failure is marked RuleFailure, kept out of BuildReport's score, summary and categories, and listed in its own "Rules That Could Not Run" section (ruleFailures in JSON). A configured rule severity no longer applies to the rule's own failure, and a rule file failing to load on an undefined name hints at a newer mxcli. Part of #952. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sync rules and CLAUDE.md (#952) - init and every sync write .ai-context/mxcli-tooling.json; any -p command warns once on stderr when the binary is provably older (releases by number, nightlies by tag date, mixed by build date, dev builds never). - init --sync-skills (alias --sync) refuses from an older binary instead of downgrading, and now also refreshes the bundled lint rules (by file name; user rules untouched) and the CLAUDE.md/AGENTS.md section between new mxcli:begin/end markers, keeping project notes outside them. - The bootstrap script compares the PATH binary and ./mxcli with the stamp before using them, downloads MXCLI_TAG instead of linking an older binary, and downloads through a temp file so a symlinked ./mxcli is never written through. Binaries <= v0.24.0 cannot read the stamp; the script is their guard. - init and new create mdlsource/ with a README. Closes #952. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docker check ran mx update-widgets on the user's project with only the MPRv2 storage snapshotted, so an MPRv1 .mpr was rewritten permanently, and mx check itself rewrote theme-cache/ and created deployment/sass/ on both formats, with or without --no-update-widgets. Both mx steps now run on a temporary copy (build output, caches and VCS folders skipped), mx output is rewritten to the project's own paths, and the output says that widgets were normalised on a copy and what that hides (#568, #646). docker build keeps its snapshot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nto itself (#951) Check copies the project's directory, so a missing .mpr (or a path in /tmp) would copy an unrelated directory: fail early instead, and give the existing fake-mx tests a project file of their own. With TMPDIR inside the project the walk met its own copy and recursed until the path was too long; skip it. Trim the custom-widgets skill back under the 700-line limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A control-bar button of a data grid nested inside a data view or list view passing $currentObject was refused as CE1571, but there the control bar's $currentObject is the enclosing object and mxbuild 11.13 builds it clean. The walk now carries whether an ancestor data container supplies an object context; the grid's own data source still never scopes its control bar, so a top-level grid is still reported. Part of #953 (item 2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CE0582 is the React client's error. Measured on mxbuild 11.13.0: a
staticimage and a classic dropdown on a NativePhone_Default page build
clean, the same widgets on an Atlas_Default page are CE0582. A textbox
on an enumeration is CE2421 on both, so MDL-WIDGET39 is unchanged.
Nothing recorded a layout's platform: ListLayouts left Layout.Native
false for every layout, and LayoutType cannot tell the platforms apart.
- backend: Native is the content wrapper's type (NativeLayoutContent)
- catalog: layouts.Platform ("Web" / "Native"), schema 18
- linter: NativePages() joins pages.LayoutRef to layouts without the
Marketplace filter (the native layouts live in Atlas_Core); MPR012
skips those pages; Starlark layout.platform
- check: MDL-WIDGET40 skips a page whose layout resolves as native
Part of #953 (item 3).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A microflow or nanoflow whose only content is `return <expr>;` computes its value in the end event, which ActivityCount does not count. A non-Void return type is the witness that the end event returns a value, so those flows are no longer reported. Part of #953 (item 4). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One finding per entity x role x CREATE/DELETE (111 on a mid-sized app) becomes one per entity, listing the de-duplicated roles per right. The test runs both the .claude and the embedded copy of the rule. Part of #953 (item 5). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`lint` had -m, `report` only --exclude. `report --modules A,B` applies the same LintContext module filter and scores only the findings located in a selected module, so project-wide findings do not weigh on a module score. The selection is printed in markdown, HTML and JSON output. Part of #953 (item 6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The visitor set ActionV3.ClosePage for `delete close page` but the page builder's delete case did not copy it, so a describe -> exec round trip stored ClosePage=false: the button stopped closing its page, with check, exec and mx check clean. Audited the other page-action cases: save and cancel already copy it; no other visitor flag is dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The return formatter prefixed $ to any stored return value without one of + ' " ( ), so [%CurrentUser%] became $[%CurrentUser%] and `if ... then ... else ...` became `$if ...`, neither of which parses. Restore the sigil only for the shape a legacy writer stripped it from: a bare name with an optional attribute path. The other $-adding sites in describe prefix variable-name fields, not expressions. Strikes two TestApp WorkflowCommons microflows from the allowlist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Item actions were printed by a private copy of the page-action renderer in the legacy `show_page 'M.P'` form, which does not parse; they now use the shared client-action renderer, as buttons do, for every action kind. With that fixed, exec refused the description because Studio Pro leaves items unnamed, and the writer then wrote Name "" and no visibility slot where Studio Pro stores no Name key and a null ConditionalVisibilitySettings. An unnamed item is now accepted, described as `item (...)` and written as Studio Pro writes it (mx check 11.14.0: 0 errors). Strikes TestApp's Rules.Entity_Menu from the allowlist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
describe -> check -> exec -> describe on PedApp for a delete-close-page button (stored ClosePage compared, plain delete as control), a flow returning [%CurrentUser%], and a navigation list with an unnamed item. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…MDL063 covers nanoflows Two calls to a void action carrying the same output name (Studio Pro names a JavaScript action's after the action, $RefreshEntity) are accepted by mxbuild 11.13.0, but check reported MDL063 (microflows) or 'already declared in this scope' (nanoflows), and describe called the model invalid. Measured: a void call's output name is inert - a later declare of the name builds clean, a use is CE0109. The return type is resolved from the script or, with -p, the project; an unresolvable action still counts. describe keeps printing the stored `$X =`: Studio Pro stores the name with UseReturnVariable=true, and the bare form would write an empty name. MDL063 now runs for nanoflows too (flow-wide, as measured in mxbuild): a duplicate output across if/else branches passed check and was CE0111. The check-time body validator no longer reports duplicate names for flows - it scoped them per branch and counted void calls; rules keep it. Part of #953 (item 1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… errors check --references accepted a Java action argument naming no parameter (CE1613 in mxbuild) whenever the script also had a semantic error: the reference tier was skipped, and a flow's body errors were returned instead of its reference errors. Both are now reported. call microflow / call nanoflow arguments are checked against the callee's parameters too (CE1613, measured on 11.13.0), and an action or flow known to take no parameters reports any named argument. Part of #953 (item 7). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…into c23-955 # Conflicts: # CHANGELOG.md
…to c23-958 # Conflicts: # CHANGELOG.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to c23-957 # Conflicts: # CHANGELOG.md # mdl/linter/report.go
A rule that could not run has no module; ScopeToModules dropped it, so a --modules report hid the failure that #952 lists separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… c23-959 # Conflicts: # CHANGELOG.md
This was referenced Oct 3, 2026
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.
Closes #950
All three items are fixed. Each is proven by describe → check → exec → describe, with the stored value compared and not only the re-described text.
1.
delete close pagelost ClosePage on write (silent)buildClientActionV3Base'sdeletecase now copiesaction.ClosePage. The visitor sets it and the writer writes it, but the builder dropped it.with (…)settings (confirmation, progress, DisabledDuringExecution) go throughapplyActionSettings, which is generic.2.
return $[%CurrentUser%];$to anything that had none of the characters+'"(). That also turnedreturn if … then … else …intoreturn $if …, which hit two TestApp WorkflowCommons microflows.$only to a bare name with an optional/path, which is the shape a legacy writer stored without the$.$do so to variable-name fields, not to expressions. They are safe and unchanged.3. Navigation-list items
extractNavigationListItemActionnow uses the shared client-action renderer, so actions print asshow page M.P,call microflow …,sign outand so on.item (…).Namekey and writes a nullConditionalVisibilitySettings. This matches all 6 Studio Pro-authored items in TestApp. Before this, a describe → exec ofRules.Entity_Menustill rewrote the snippet.mx check(11.14.0) on a TestApp copy with unnamed items written by exec: 0 errors.Harness
mdl/roundtrip/describe_reparse_950_test.go(PedApp). For each of the three cases it runs describe →checkReferences→ exec → describe, checks that nothing was written, and checks the stored ClosePage per button. A plaindeletebutton is the control.snippet Rules.Entity_Menumicroflow WorkflowCommons.SUB_Workflow_AverageHandlingTimemicroflow WorkflowCommons.SUB_WorkflowTask_AverageHandlingTimeTest plan
make buildgo test ./mdl/executor/ ./mdl/backend/modelsdk/ ./mdl/visitor/ ./cmd/mxcli/: okgo test -tags integration ./mdl/roundtrip/ -run 'TestTestAppRoundTrip$|TestPedAppRoundTrip$|DescribeUsesCanonicalSpellings|DescribeIsValid|TestDescribeReExecutes_950|Pluggable': okmake lint(includes check-conformance): okmake check-findings: okdelete close page→bson dumpshows ClosePage true on that button and false on the plaindeletebutton; describe → exec gives "Unchanged".describe snippet Rules.Entity_Menu→check --references→ exec → describe gives identical output and "Unchanged".mxcli docker checkon the result: 0 errors.Revert checks. Each fix was removed in turn and the tests were run again:
ClosePagecopybDelClosestores ClosePage=false. Unit test: "describe printeddelete close page, which builds ClosePage=false".$rulereturn [%CurrentUser%];. Unit test:$[%CurrentUser%]does not parse (token recognition error at: '$[').show_page 'Rules.BusinessRule_Overview'.Nameon unnamed items in the writerTestTestAppRoundTrip/snippet_Rules.Entity_MenureportsItems[n]/Name: added.Follow-ups (not changed here; each needs a syntax decision)
complete task: the builder always writesClosePage: trueandCommit: true, and describe prints neither. A Studio Pro outcome button with either one off would be flipped by a describe → exec. All 4 such buttons in TestApp have both true, so this is latent today.close page/show page/create object: the number of pages to close (NumberOfPagesToClose/NumberOfPagesToClose2) is written as""and has no MDL form. All stored values in TestApp are"", so this is also latent.🤖 Generated with Claude Code