Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
4018715
fix(syntax): document every DROP statement in a drop topic (#1911)
claude Nov 3, 2026
98d061e
fix(syntax): list every built-in expression function with its types (…
claude Nov 3, 2026
5b052c3
docs(skills): correct check-syntax's forward-reference rule; move Stu…
claude Nov 3, 2026
a45edcb
fix(messagedefinition): describe names the referenced attribute after…
claude Nov 3, 2026
89cda23
fix(check): warn when toString of a Decimal is written to a short Str…
claude Nov 3, 2026
ced4bd8
fix(parser): name the malformed argument in a data-source parse error…
claude Nov 3, 2026
0cc8e2b
feat(microflow): author a queued call's retry policy (in queue … retr…
claude Nov 3, 2026
c5b1ce2
fix(version-gates): name the queued-call retry types in the in-queue …
claude Nov 3, 2026
2d1b473
fix(check): no MDL-WIDGET10 on text/number/date filter attributes (#1…
claude Nov 3, 2026
23ce090
test(check): pin no MDL-WIDGET10 on dynamictext Content (#1865)
claude Nov 3, 2026
ff4d6c5
fix(lint): MPR008 names the loop when a loop box overlaps (#1839)
claude Nov 3, 2026
1d4097b
fix(describe): cite mendixlabs/mxcli#923 in the flow warnings (#1005)
claude Nov 3, 2026
4cf3d02
fix(describe): print a blank call external action argument as `= noth…
claude Nov 3, 2026
2b1a669
fix(describe): keep one merge when a described decision is rebuilt (#…
claude Nov 3, 2026
e4aadd4
fix(describe): describe a note linked to the start event or another n…
claude Nov 3, 2026
b11fca0
fix(pages): delete button deletes a grid's selection as `delete $grid…
claude Nov 3, 2026
35b120a
fix(pages): describe of an AccessibilityHelper re-executes (#904)
claude Nov 3, 2026
4e2c3f8
fix: describe writes a text holding $$ as a string literal (#1003)
claude Nov 3, 2026
f2f1551
fix: database from $ctx/… resolves multi-hop paths like an associatio…
claude Nov 3, 2026
3a35c38
fix: refuse an association hop that does not start at the context ent…
claude Nov 3, 2026
da5c9f5
Merge remote-tracking branch 'origin/main' into claude/wonderful-hypa…
claude Nov 3, 2026
81686c7
fix(microflows): retrieve … offset n without a limit keeps its offset…
claude Nov 3, 2026
bd86d7c
Merge pull request #1944 from ako/claude/wonderful-hypatia-x7mmyq
ako Nov 3, 2026
f0c071d
docs: page-patterns Delete buttons delete the grid's selection (#1932)
claude Nov 3, 2026
fb1c1c8
Merge pull request #1946 from ako/claude/issue-triage-prioritization-…
ako Nov 3, 2026
3d40493
feat(microflows): send external object and delete external object (#1…
claude Nov 3, 2026
afe1624
feat(microflow): send external object / delete external object statem…
claude Nov 3, 2026
35398f6
fix(executor): refuse a rebuild that drops an activity MDL cannot exp…
claude Nov 3, 2026
b077092
Merge branch 'mendixlabs:main' into main
ako Nov 3, 2026
970ca18
docs(proposal): associations to include on a call external action arg…
claude Nov 3, 2026
e84b7f5
brain: plan and check answer when the .mpr does not exist yet
claude Nov 3, 2026
af50bd5
fix(mcp): localhost dials 127.0.0.1 first; pin exec/-c --mcp never wr…
claude Nov 3, 2026
cdd5621
Merge pull request #1947 from ako/claude/issue-triage-prioritization-…
ako Nov 3, 2026
0f36578
fix(microflows): refuse a rebuild that would delete unsupported activ…
claude Nov 3, 2026
5c6ae9f
Merge remote-tracking branch 'origin/main' into claude/vibrant-knuth-…
claude Nov 3, 2026
89222c1
Merge origin/main: take #1947's send/delete external object statements
claude Nov 3, 2026
bf3d6d0
brain: start a brain before the project, and have mxcli new adopt it
claude Nov 3, 2026
6f254d7
fix(nanoflow): refuse send/delete external object in a nanoflow (#1939)
claude Nov 3, 2026
8f8f874
Merge pull request #1954 from ako/claude/wonderful-hypatia-x7mmyq
ako Nov 3, 2026
e834c27
Merge pull request #1945 from ako/claude/vibrant-knuth-8b6spq
ako Nov 4, 2026
e4baec6
Merge pull request #1955 from ako/claude/dreamy-wozniak-nht5af
ako Nov 4, 2026
76b63bc
docs(proposal): warn on an omitted include associations clause; how t…
claude Nov 4, 2026
cf8a7b4
brain: edit and move an entry without changing its id
claude Nov 4, 2026
9339f57
brain: record which document, and where in it, an entry came from
claude Nov 4, 2026
04cac6a
Merge pull request #1957 from ako/claude/wonderful-hypatia-x7mmyq
ako Nov 4, 2026
7f56db0
fix(modelsdk): workflow annotation storage name is Workflows$Annotati…
claude Nov 4, 2026
c79ad0c
fix(workflow): claim a user task with the name the project's Mendix v…
claude Nov 4, 2026
237ae1e
fix(syntax): read topic versions from sdk/versions; document list fea…
claude Nov 4, 2026
95206c2
fix(check): before Mendix 10.1 a page or snippet parameter supplies a…
claude Nov 4, 2026
55b4d8f
fix(pages): keep a 9.x widget's database source type on rewrite (#1208)
claude Nov 4, 2026
fcde1e0
Merge pull request #1962 from ako/claude/wonderful-hypatia-x7mmyq
ako Nov 4, 2026
6a1f6e1
Merge pull request #1958 from ako/feature/1949-brain-before-project
ako Nov 4, 2026
fed66af
Merge origin/main: keep main's unsupported-activity guard, reduce thi…
claude Nov 4, 2026
6538d30
docs(write-microflows): the drop + create refusal is main's, without …
claude Nov 4, 2026
3c16bd2
Merge pull request #1960 from ako/feature/1950-brain-edit-move
ako Nov 4, 2026
5ebaefc
Merge pull request #1961 from ako/feature/1951-brain-provenance
ako Nov 4, 2026
0300327
Merge pull request #1959 from ako/claude/issue-triage-prioritization-…
ako Nov 4, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-03", "symptom": "A brain could be started before its project only by accident: store commands took -p and used filepath.Dir of a path nothing opened; `brain init <dir>` accepted the directory and silently ignored it; and `mxcli new` refused any directory that already held the brain", "cause": "No way to name a brain's directory (`brainProjectPath` required -p, and `init` declared no Args), and `cmd_new.go`'s non-empty check plus `moveProject`'s rename-then-os.CopyFS fallback assumed an empty destination", "file": "`cmd/mxcli/cmd_brain.go` (`resolveBrainLocation`, `brainLocatedCommands`), `cmd/mxcli/newproject_paths.go` (`checkNewProjectDestination`, `mergeProject`)", "insight": "**A feature that works only because nothing opens a path is one Stat away from gone — and the fallback that seems to support it is unsafe.** os.CopyFS merges into an existing directory (MkdirAll on dirs, O_EXCL on files), so moving a project onto a brain appeared to work; the first shared file stopped it half way, leaving App.mpr moved and the stage gutted. The merge test passes against that accident; only the conflict test (6 files where there were 4) proves the pre-check. Adoption is kept to exactly docs/brain (with mxcli's marker) and .mxcli/brain, so `new` never merges into someone's files. Test helpers that drive the shared rootCmd must reset -p/-C, or a -C from one run turns the next run's -p into 'both passed'", "refs": ["ako/mxcli#1949"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-03", "symptom": "`brain plan` and `brain check` fail with `CONNECT LOCAL '…/App.mpr': failed to connect: mpr file not found` when the brain was started before the project, although init/capture/promote/brief all work against the same nonexistent -p path", "cause": "Both commands call `openBrainResolver(projectPath)` and `brainFatal` on any error; the store commands only ever use `filepath.Dir` of -p", "file": "`cmd/mxcli/cmd_brain.go` (`openBrainResolverOrNoModel`), `cmd/mxcli/brain/check.go` (`NoModel`, `Unverifiable`, `checkSlice`)", "insight": "**A null resolver needs its own state, and the existing state switch silently decides what it means.** Returning NotFound reports the whole store stale; adding a state without touching `checkSlice` is worse, because that branch counts every non-NotFound state as BUILT (so NotIndexable does not under-report) — a project that does not exist read 100% built. The test asserts Built 0, not just exit 0; stubbing the guard gives Built:1. Only os.IsNotExist selects NoModel: a corrupt .mpr still errors, or it would read as merely unbuilt. Verified end to end: same store, `-p Nothing.mpr` 0 of 1, `-p PedApp.mpr` 1 of 1", "refs": ["ako/mxcli#1948"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli/syntax","date":"2026-11-03","symptom":"`mxcli syntax drop` showed three unrelated topics (drop-if-exists, layout.drop, workflow.drop); DROP ASSOCIATION was only inside domain-model.association's text, and DROP ENTITY / MICROFLOW / NANOFLOW / SNIPPET were in no topic at all","cause":"each DROP was left to its document type's topic, with nothing holding the set to the grammar; the segment-match fallback answers a verb with whatever path happens to contain it","file":"cmd/mxcli/syntax/features_misc.go (drop topic), cmd/mxcli/syntax/drop_statements_drift_test.go","insight":"For 'statement X is undocumented' reports, diff the grammar rule against `mxcli syntax --json` before writing prose: the rule's alternatives are the complete list (one grep found four more undocumented drops than the report named). Then pin it with a drift test that reads the .g4 (widget_keywords_drift_test.go is the template), mapping shared *Kw sub-rules to their first (canonical) alternative so deprecated aliases are not demanded in the docs.","refs":["ako/mxcli#1911","mendixlabs/mxcli#1716"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli/syntax","date":"2026-11-03","symptom":"`mxcli syntax expression` named no isNew, add*/subtract* or trimTo* function although `mxcli check` accepted and type-checked all of them","cause":"the only expression topic was hand-written around specific pitfalls (regex, *Between, braces); the authoritative list of built-ins lived only in mdl/exprcheck funcTable","file":"mdl/exprcheck/signatures.go, cmd/mxcli/syntax/features_expression_functions.go","insight":"When the checker already holds a measured table, render the docs from it (exprcheck.Functions()) instead of adding the reported names by hand: one change documented ~90 functions with the exact types E005 enforces. Leave out rows marked unverified — hour()/dayOfYear() etc. are CE0117 on a real build, and documenting them would send readers into a build failure.","refs":["ako/mxcli#1866","mendixlabs/mxcli#1708"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-04", "symptom": "No way to change a brain entry's wording: every correction was drop + capture, which minted a new id and orphaned the old handle; editing the id-stable way exposed that duplicate detection compared stored ids, so the edited wording re-captured was accepted twice and the original wording collided with the edited entry's handle ('already carries entry 66dcf4' quoting text that no longer says that)", "cause": "`Queue.Append` and `Store.Promote` deduplicated on `existing.ID == e.ID`, which is only a content check while an id still matches its text; resolve and rename already broke that, edit breaks it routinely", "file": "`cmd/mxcli/brain/edit.go` (`ContentKey`, `Store.Update`, `Queue.Update`, `AssignFreeID`), `cmd/mxcli/brain/staged.go`, `cmd/mxcli/brain/store.go`, `cmd/mxcli/cmd_brain.go` (`brainEditCmd`, `brainMoveCmd`)", "insight": "**Once an id is a handle, identity and content are two keys, and every comparison has to say which one it means.** Duplicate = same ContentKey; collision = same id with different content, solved by deriving a fresh id (content + counter) at capture rather than refusing a legitimate new fact. Routing is the other trap: a decision follows its anchors only if it was where its anchors put it, or an entry pinned to project.md is evicted by an edit. Stubbing AssignFreeID reproduces the exact predicted error through the CLI. Harness gotcha found on the way: cobra StringSlice flags APPEND across runs of the shared rootCmd, so a second `capture -a X` in one test captured [X, X] and silently became a different entry — reset every flag to DefValue, and Changed, between runs", "refs": ["ako/mxcli#1950"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-11-04", "symptom": "A brain entry could not record where it came from (which document, which lines), so a requirements UI could neither show the source line behind a requirement nor answer which parts of a document produced none", "cause": "`Entry` had no provenance field, and the shard's one metadata line is matched by an exact regex (`metaLine`), so extending that line would make every older build report such entries MALFORMED and fail `brain check`", "file": "`cmd/mxcli/brain/source.go` (`NormalizeSource`, `missingSources`), `cmd/mxcli/brain/shard.go` (`renderEntry`, `parseEntry`, `sourceLine`), `cmd/mxcli/cmd_brain.go` (`brainSource`)", "insight": "**When a format is shared across versions, place new data where the OLD reader already preserves it.** The Source line goes directly after the metadata line: an older parser takes it as the first body line and keeps it on rewrite (measured: main e4baec63 checks such a store OK and its drop rewrites the line back as `\\n\\nSource: …`), while lines between title and metadata are silently discarded by old rewrites. The new parser must therefore accept the line after blank lines too — and only as the FIRST non-blank line, or a body that mentions a source becomes provenance. Removing the blank-line skip makes the old-rewrite test read the source as body. Provenance is not content: excluded from ContentKey, stored project-relative, refused outside the project or when missing, and a later-missing file fails check like an anchor naming nothing", "refs": ["ako/mxcli#1951"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli/syntax","date":"2026-11-04","symptom":"`show features` had no `mxcli syntax` topic; 8 of 115 topics carried a hand-written MinVersion that disagreed with sdk/versions (boundary event 10.6.0 vs 10.14.0, view entities 10.18.0 vs 10.21.0, notify 11.7.0 although the statement is 10.0), data-transformer had none; `list features for version 10.20.0` and `list features in workflows` were parse errors","cause":"two version tables maintained by hand with no join; NUMBER_LITERAL lexes one dot, and the area slot took IDENTIFIER though the area names are lexer keywords","file":"cmd/mxcli/syntax/registry.go (Features, Register refuses MinVersion), cmd/mxcli/syntax/versions.go, cmd/mxcli/syntax/features_versions_test.go (ledger), sdk/versions/registry.go (Lookup, Keys), mdl/grammar/domains/MDLCatalog.g4 (featureVersion, identifierOrKeyword)","insight":"Remove the second table instead of syncing it: topics name registry features ('area/name') and versions are filled from the registry at lookup, and Register panics on a hand-written MinVersion, so drift cannot reappear. Close the reverse direction with a shrinking ledger test (every registry key referenced by some topic, or listed with a reason). A topic spanning several features lists each with its own version; use the FIRST feature as the topic's MinVersion, not the lowest — 'lowest' made data-transformer read 11.4 (the transform action) though its document is 11.9. When documenting a statement, run every documented form: two of the four `list features` forms did not parse.","refs":["ako/mxcli#1367"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend", "date": "2026-11-03", "symptom": "`mxcli mcp capabilities -p App.mpr --mcp http://localhost:7782/mcp` on Windows failed with `dial tcp <LAN IP>:7782: i/o timeout`, still after the host.docker.internal fix; `--mcp-dial 127.0.0.1:7782` connected. The same report said `exec --mcp` / `-c --mcp` wrote the .mpr and mprcontents/ and skipped the .mpr.lock refusal (mendixlabs/mxcli#1684)", "cause": "dialPlan dialled the URL host verbatim, so `localhost` went through the resolver, which on the reporter's machine answered with a LAN address first; Studio Pro on Windows listens on 127.0.0.1 only and answers 400 to any Host header but localhost. The write-to-disk claim does not reproduce: the CLI with --mcp sends ped_create_document and leaves .mpr + mprcontents/ byte-identical with the lock present, and an un-routed statement is refused by the MCP backend's unsupportedBackend; the trace that showed no PED call was the tracer wiring fixed earlier (2026-11-01-mcp-trace-lists-no-ped-call)", "file": "mdl/backend/mcp/client.go (dialPlan)", "fix": "A localhost endpoint dials 127.0.0.1:<port> first, then localhost:<port> via the resolver (a ::1-only server), then host.docker.internal; the request URL, and so the Host header, stays localhost", "insight": "Before fixing 'writes the file instead of the server', run the real binary with the reporter's exact flags against a logging fake server and a hash of the model files, with the lock file present: one run separated what the server received from what the trace printed. Pin it with a child-process test (runMainStreams) and prove the test by forcing the fault back in (factory ignoring --mcp plus the guard off), which reproduces the report verbatim: exit 0, `Created constant`, no PED call, files changed. Do not 'restore' the lock refusal for --mcp: it guards the local Writer, which the MCP backend never opens (ConnectReadOnly); with --mcp the lock is always present, so refusing on it would make --mcp unusable", "refs": "ako/mxcli#1833, mendixlabs/mxcli#1684", "test": "mdl/backend/mcp/client_dial_test.go; cmd/mxcli/mcp_exec_no_file_write_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-03","symptom":"ako/mxcli#904: describe → exec of an AccessibilityHelper failed. Half 1 (describe emitted `content { }`, MDL-WIDGET26 \"`content` is not a container of `accessibilityhelper` — it declares: attr, template\") no longer reproduces on main — fixed by mendixlabs/mxcli#1400. Half 2 still did: an attributesList item `attr (attribute: 'aria-label', …)` made check --references, which exec runs first, report \"widget '': Attribute 'aria-label' is bound but there is no enclosing data container providing entity context\"","cause":"walkWidgetsWithContext asked GetAttribute() of every AST node, including object-list ITEMS, whose properties are the item's own; AccessibilityHelper's item has a string property literally named `attribute` (the HTML attribute's name)","file":"mdl/executor/validate_page_context.go (walkWidgetsWithContext)","fix":"skip the binding check on a child whose type is a container keyword of the enclosing widget's definition (unstoredContainerKinds, already used by the CE0495 rule for the same item-vs-widget question)","test":"TestAccessibilityHelper_ItemAttributeIsNotABinding (+ RealUnboundAttributeStillReported control, SlotKeywordIsTemplate regression for half 1)","insight":"**Reproduce each half of a multi-part report on main before fixing**: the headline error (MDL-WIDGET26) was already gone, and the half that remained is in a different layer — only check --references (project needed) refuses; plain check and exec --no-check both accept and round-trip it (mx 11.12.1: exec → describe → exec 'Unchanged page', mx check 0 errors). The item-vs-widget question had already been answered once in the same file for duplicate names; a second rule walking the same tree did not ask it. Housekeeping: knownUnsupportedContainers (ATTRIBUTE/ATTR/EVENT, #239) was stale since widgetTypeV3 gained `| keyword`; the test now asks the parser instead of keeping a list","refs":["ako/mxcli#904","mendixlabs/mxcli#1400","#239"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-03","symptom":"A page data source `$Order/M.Flag_Account/M.Flag` (or `database from $currentObject/…` with the same path) passes `check` and `exec` writes it, although M.Flag_Account joins Flag and Account and cannot be followed from an Order","cause":"resolveAssociationSourceHops checked an author-supplied destination against the association's ends, and that the association exists, but never that the association touches the entity the hop starts from. A derived destination was safe by accident: resolveAssociationDestination finds none when the start is off the association, so only the spelled-out `Assoc/Dest` form slipped through","file":"`mdl/executor/cmd_pages_builder_v3.go` (resolveAssociationHops, isEndOrSpecialization), `mdl/executor/validate_assoc_hop_start.go` (MDL-ASSOCDS03)","insight":"A destination check alone is not a hop check: an association has two ends, so naming either one passes it from anywhere. Check the START against the ends too, accepting a specialization (Administration.Account over System.User's associations). At check time report only what is provable — walk the start's generalization chain through the script's entities and the loaded models and stay silent at the first entity in neither (System entities are not loaded), the same rule as provablyNotSpecializationOf","refs":["#834"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-03","symptom":"describe microflow printed an unbound call external action argument stored as Argument: \"\" (Studio Pro 11.16, an optional OData parameter left blank) as `additional = )` / `additional = ,`, which does not parse, so every mdl 1; create or modify of the microflow was refused with MDL-V1-REBUILD \"the description does not parse\".","cause":"formatAction's CallExternalAction branch printed every mapping through describeExpr, which renders \"\" as nothing at all. The call microflow / call nanoflow branches had already been fixed for the same stored state with describeCallArgument (`= nothing`), and the visitor refused `nothing` outside those two calls.","file":"mdl/executor/cmd_microflows_format_action.go (CallExternalAction branch -> describeCallArgument); mdl/visitor/visitor_argument_binding.go (isBlankableCallArgument now admits CallExternalActionStatementContext)","insight":"Before designing a spelling for a stored state, grep how the language already spells it on a sibling: `Param = nothing` existed for exactly Argument \"\" on flow calls, with the same three-way distinction (blank / the value `empty` / no mapping). The issue's suggested fix - omit the mapping and have the builder re-create \"\" for a nullable parameter from the contract - would also round-trip, but only with the OData contract at hand, changes what omitting a parameter means, and is a second spelling of a state that already had one. `empty` (11.14) and \"\" (11.16) are both real stored states; the control test keeps `= empty` byte-identical. Not measured on mxbuild here: whether 11.16 accepts a \"\" argument on a NON-nullable parameter (a flow call gives CE0127).","refs":["ako/mxcli#1915","ako/mxcli#1914","mendixlabs/mxcli#1073"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"mdl/executor","date":"2026-11-03","symptom":"`database from $currentObject/M.A1/M.A2` (a List View or pluggable database source over two associations) is refused with `entity \"M.A2\" in datasource … does not exist`, while the association source `$currentObject/M.A1/M.A2` builds; `database from $ctx/M.A1/M.E` with E an existing entity off A1 is written as stated","cause":"buildDatabaseOverAssociationV3 (ako/mxcli#721 L5) walked the path two segments at a time — association, destination — and only checked the destination exists. resolveAssociationSourceHops had been taught every multi-hop spelling and the end-of-association check (mendixlabs/mxcli#1467), but it was not shared, so the second builder kept the old reading","file":"`mdl/executor/cmd_pages_builder_v3.go` (resolveAssociationHops, buildDatabaseOverAssociationV3)","insight":"When an issue names a defect in \"the builder\", grep for every function that splits the same path: the one the triage comment cited had been fixed by another issue, and its twin, written later for a different datasource kind, still had the bug. Make both read the path through one function rather than porting the fix, so the two cannot drift again","refs":["#834","mendixlabs/mxcli#1467"]}
Loading
Loading