From 4f5734e263d909302d85b896d14a13619d9b7827 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 23 Oct 2026 15:30:50 +0000 Subject: [PATCH 1/2] trim(preflight): move STOP-row narrative out of the baseline; add Kind column (lazy-load PR 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pure move plus an index, skills/learned-mdl-preflight.md only: - retired STOP rows (1c 2 3 5 6 6b 7 8 9 10 11 13 15 17 27) collapse to one line naming their numbers and pointing at the history file; - version notes and every live row's root-cause narrative beyond one failure clause move to process/baseline-incident-history.md Β§ PF1, verbatim; - new Kind column at the end of each row (page/microflow/access/workflow/any). Protected text stays: every live row's If/Then, Step 0, the gotchas, the final self-check, the workflow DECISION STOP and the #879 read-first pointer. check-moved-text: 43 of 43 removed lines found. render-routing --check: baseline 73946 -> 72891 words, in sync. test-mdl-scan.sh: 52 passed, 0 failed. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr --- CHANGELOG.md | 1 + process/baseline-incident-history.md | 51 ++++++++++++++++++++ skills/learned-mdl-preflight.md | 70 +++++++++++----------------- 3 files changed, 78 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43dfd52e..d8c535fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m ## Unreleased +- process(preflight): **`learned-mdl-preflight.md` moves its STOP-row narrative out of the baseline and gains a `Kind` column (page / microflow / access / workflow / entity / any)** β€” lazy-load PR 1. The 15 retired rows collapse to one line listing their numbers, the version notes move, and each live row keeps its If/Then text plus one failure clause; the full rows, retired rows and version notes are in `process/baseline-incident-history.md` Β§ PF1, verbatim (`check-moved-text.sh`: 43 of 43 removed lines found). The workflow `DECISION` STOP and the #879 read-first pointer stay in the skill. `Kind` sits at the end of each row so `mdl-scan`'s `| πŸ”Ž` markers still match. Baseline 73,946 β†’ 72,891 words (βˆ’1,055). β€” maintainer (Option C lazy-loading plan) - fix(progress-report): **`progress-report.py` no longer crashes with `TypeError: '<' not supported between instances of 'dict' and 'dict'` when two exec'd scripts share a leading number** (#513). `script_phases()` sorted `(number, phase dict)` pairs, so `10-data.mdl` and `10b-data-flows.mdl` (or one script logged under two paths), both matched to a plan phase, compared the dicts and every `exec.sh` run ended with `WARN: progress-report.html not updated`. It now sorts on (number, script name) only; an unmatched numbered script still takes the phase of the nearest lower-numbered matched one, ties broken by name. Fixture: `test-progress-report.sh` T17 (fails 3/3 on master). β€” jopterhorst (#513) - new(canvas): **`project-bin/mf-canvas-facts.py` prints how a microflow or nanoflow lies on the Studio Pro canvas: labels on top of each other, lines through objects, note lines leaving the side that faces away, flows that run right-to-left or curl, captions wider than their shape, and decision captions that ask the opposite of their true branch (SENSE).** It prints facts, one line each, and no verdicts; read-only (it reads units through `mxpatch.py`), exit 2 when a flow could not be read. `verify-module.sh` runs it per module as an info rung (1c, log `14-canvas-facts.log`; a missing script, Python or `.mpr`, an exit 2 or a timeout is an INFO row reading NOT MEASURED, never a gate). Fixture `tests/wave2/test-mf-canvas-facts.sh` runs on a model mxcli v0.27.0 wrote (units and `.mpr` captured); `test-verify-module-446.sh` gains V8 for the rung. Calibration is from Studio Pro 10.24 screenshots, not verified on Studio Pro 11. Field evidence, measured 2026-10-21 on one Mendix 10.24 app: 1,588 flows read in one pass; on the 36 flows an mxcli-built branch added or changed in one module, OVERLAP 19, LINE 27, NOTE-SIDE 17, LEFTWARD 3, TURN 4, SENSE 9 before repair β€” saingge - learn(preflight, teamserver-alignment): **a flow's return-type change and its callers' update go in one script (STOP row 33), and Studio Pro 10.24.18's "Merge feature branch" merges `origin/`, not the local branch.** On a copy of a Mendix 10.24.18 app with mxcli v0.27.0, the first script alone left `mx check` with CE0112 at a caller stored the way Studio Pro stores a call, while `check` and `exec` stayed silent; Studio Pro's own git log shows the merge of the remote branch. Text only; baseline-routed, +101 words. β€” saingge diff --git a/process/baseline-incident-history.md b/process/baseline-incident-history.md index 9a941b3a..72562bc8 100644 --- a/process/baseline-incident-history.md +++ b/process/baseline-incident-history.md @@ -442,3 +442,54 @@ the remedy for a bad microflow layout stays the one in this file: no `@position` _From `skills/learned-mdl-preflight.md`; moved verbatim 2026-10-14._ - ~~`marketplace install` on a split-model project (#879)~~ β€” **RESOLVED in v0.21.0, STOP LIFTED (probed 2026-09-10).** Install no longer shells out to `mx module-import`; it copies units with mxcli's own writer and MPR v2 survives. The destructive path is now opt-in behind `--allow-format-change`, so the failure can only happen on purpose. Measured on a real 501-unit project: 501 β†’ 1075 `.mxunit`, `.mpr` 84 KB β†’ 156 KB (an index, not the 35 MB blob #879 produced), native mxbuild **0 errors**. **Read `bug-logs/mxcli-bugs.md` β†’ the #879 entry before your first install** β€” the corruption is gone, and three *new* operational traps replaced it (packages do not carry their dependencies; two `mxcli fix` repairs are mandatory, not advisory; a bundled widget can silently fail to land and the installer cannot self-repair it). + +## PF1 β€” `learned-mdl-preflight.md`: version notes, retired rows, full root causes (2026-10-23) + +_From `skills/learned-mdl-preflight.md`; moved verbatim 2026-10-23 (lazy-load PR 1). The skill keeps every row's If/Then text, one failure clause per live row and a `Kind` column; below is the table as it stood before the move, retired rows included._ + +Re-probed on mxcli v0.24.0 / Mendix 11.13.0 (2026-09-30); rules that now work or that `mxcli check` catches were removed. + +**Version context:** a retired row keeps its number (other skills cite `STOP #n`) and says why it went. If in doubt about a rule, retest on your version and stamp the result in `bug-logs/mxcli-bugs.md`. + +**Version notes (mxcli β‰₯ v0.20.0):** +- ALTER PAGE addresses DataGrid2 columns by **derived** name (bound attribute, else caption β€” MDL-WIDGET16); a bare column name in REPLACE is refused in favour of `grid.column`. +- **Still corrupting, STOP stays:** workflow `DECISION` activities (BUG-76 β€” project unloadable, `EnumerationValueIdentifier`). **v0.24.0 narrows it:** the bare-enum form is refused by `MDL-WF03` (never force it with `--no-check`), and a Boolean decision with `true`/`false` outcome keywords builds at 0 native errors β€” `learned-workflow-patterns.md` Β§8 Warning 1. +- ~~`marketplace install` on a split-model project (#879)~~ β€” **RESOLVED in v0.21.0, STOP LIFTED (probed 2026-09-10).** The destructive path is now opt-in behind `--allow-format-change`, so the failure can only happen on purpose. **Read `bug-logs/mxcli-bugs.md` β†’ the #879 entry before your first install** β€” the corruption is gone, and three *new* operational traps replaced it (packages do not carry their dependencies; two `mxcli fix` repairs are mandatory, not advisory; a bundled widget can silently fail to land and the installer cannot self-repair it). Probe measurements: `process/baseline-incident-history.md` Β§ MP1. +- The 10–12-writes-per-session cap from BUG-97 is downgraded to snapshot-plus-read-back: 16 sequential writes were clean on v0.20.0. + +| # | If your script will… | Then… | Root cause | +|---|---|---|---| +| 1 πŸ”Ž | Use `visible:` or `editable:` **conditional expressions** on containers **inside a `datagrid customContent` column** | **STOP β†’ Studio Pro by hand** | mxcli writes blank `AttributeIdentifier` β†’ `StorageLoadException` on SP open. **BUG-18, still open on v0.13.0** (found 2026-07-03 after v0.13.0 release). **Primary real-world trigger: per-value badge pattern** β€” multiple containers with `Visible: [State = ENUM.Value]` inside a column. mxbuild passes clean; SP load fails. *Re-probe 2026-09-30 (v0.24.0): `mx check` 0 errors and the BSON is identical to the plain-container case; Studio Pro load could not be tested, so the STOP stays.* Safe CLI alternative: `dynamictext (Attribute: "State")` renders enum caption natively. Do NOT use `ContentParams: [{1} = toString("State")]` inside customContent β€” resolves as attribute path β†’ CE1613. Per-value colours: set them in Studio Pro. | +| 1b | Put `Editable:` on an input widget in `CREATE PAGE` | **Write it as an expression, `Editable: []` β€” never the quoted string `Editable: ''`.** (`Visible: []` and `ALTER PAGE … SET Visible/Editable = []` work.) | v0.24.0: the quoted form is dropped with no message β€” `describe` shows no `Editable` β€” so the field is silently always editable. `check` and `exec` are both silent; read the page back with `describe page`. | +| 1c | *(retired 2026-09-30 β€” ALTER PAGE SET Visible/Editable stores correctly, `mx check` 0 errors)* | | | +| 2 | *(retired 2026-09-30 β€” settings and security-level writes work in the CLI)* | | | +| 3 | *(retired 2026-09-30 β€” dropping an attribute that has grants works)* | | | +| 4 | Bind a widget to the `AutoChangedBy` system attribute | **STOP β†’ omit it, or bind `AutoChangedDate` instead** | v0.24.0: `check` passes, then `mx check` gives `[CE1613] The selected attribute 'Mod.Entity.changedBy' no longer exists`. `AutoChangedDate` binds clean. `mxcli lint` does not flag it. | +| 5 | *(retired 2026-09-30 β€” scalar arguments from a page button to a microflow work; an unbound parameter is CE1571)* | | | +| 6 | *(retired 2026-09-30 β€” COMBOBOX in association mode works)* | | | +| 6b | *(retired 2026-09-30 β€” `DropdownFilter` in association mode works)* | | | +| 7 | *(retired 2026-09-30 β€” cross-module association traversal as a datasource works)* | | | +| 8 | *(retired 2026-09-30 β€” `CREATE ASSOCIATION` on an existing name is refused; use `create or modify association`)* | | | +| 9 | *(retired 2026-09-30 β€” inline association-set in CHANGE/CREATE works, cross-module too β€” set it from the owner side, see `learned-microflow-patterns.md`)* | | | +| 10 | *(retired 2026-09-30 β€” `mxcli check` refuses `count()` (MDL044) and exec will not run it; write `length($list)`)* | | | +| 11 | *(retired 2026-09-30 β€” an association path as XPath comparand works)* | | | +| 12 πŸ”Ž | Put anything but a bare attribute or a quoted literal in a `dynamictext`'s `ContentParams` β€” `toString(Attr)`, `$currentObject/Attr`, `if … then … else`, any function | **Bind a bare attribute (`{1} = Attr`) or a quoted literal, nothing else.** A computed label becomes data: a stored or derived String attribute, bound bare. Tone variants go in `DynamicClasses`, which takes a real expression (and there *needs* the prefix: `'if $currentObject/State = Enum.Value then ...'`). | v0.24.0 (BUG-142): every unquoted value is stored as an attribute path, so an expression is CE1613 at mxbuild ("The selected attribute '.' no longer exists"). `check` now refuses the `toString`, `concat` and `$currentObject` forms, but **`if … then … else` passes `check` and `exec`** and fails only at `mx check`; `mxcli lint` does not flag it. A bare Boolean renders "Yes"/"No", not `true`/`false`. `Attribute: Attr` is the documented shorthand for the bare form (`learned-datagrid-customcontent-binding.md`). | +| 13 | *(retired 2026-09-30 β€” `check` refuses an unqualified association name in a retrieve XPath (CE0161) and exec refuses; write `Module.Assoc`)* | | | +| 15 | *(retired 2026-09-30 β€” quoted attribute names in CHANGE work; `describe` normalises them)* | | | +| 14 | Narrow an existing entity grant (fewer attributes or rights than the rule already has) | **`revoke` first, then `grant` the narrower set.** A lone narrowing `grant` merges into the existing rule instead of replacing it (BUG-145). | v0.24.0: revoke + re-grant no longer drops another role's grant (`mx check` 0 errors); the merge on a lone `grant` remains. | +| 17 | *(retired 2026-09-30 β€” uppercase `AND`/`OR` with `!=` builds at 0 errors)* | | | +| 18 | Write **any workflow MDL** β€” `CREATE`/`ALTER WORKFLOW`, a `CALL MICROFLOW` step, a `JUMP TO`, user-task outcomes | **STOP β†’ read [[learned-workflow-patterns]] first, then script. Create every callee microflow in an EARLIER script than the workflow that calls it.** Read the BRD lifecycle + wireframe before writing a single outcome. | v0.24.0: with the callee already in the model, `check` and `exec` refuse a call-microflow with an unmapped parameter, a missing callee, and a `JUMP TO` that is not a real activity name (MDL-WF05). With the callee created **in the same script**, `check --references` skips the call and `exec` auto-fills the `WITH` mapping β€” a non-context parameter gets `(Name = '$WorkflowContext')` β€” and `mx check` fails with CE0117 at the call. A context-typed parameter auto-maps fine. `mxcli lint` does not flag it. Earlier incidents: 2026-07-24 Γ—2, 2026-08-21, 2026-08-31 (`learned-workflow-patterns.md` Β§7, Β§13, Β§14, Β§21). | +| 16 πŸ”Ž | Write an access-rule XPath constraint with a **path expression inside the `[%CurrentUser/...%]` substitution token** β€” `[Assoc = '[%CurrentUser/Module.OtherAssoc%]']`, especially crossing module boundaries | **Never put a path inside the CurrentUser substitution. Keep it bare (`'[%CurrentUser%]'`) and do the ENTIRE multi-hop/cross-module traversal on the left-hand side instead**, qualifying the entity name at every module crossing (same rule as the "cross-module association expression paths" MDL gotcha, extended here to access-rule XPath constraints, not just microflow expressions). Was: `[Decision_Partner = '[%CurrentUser/PLM.Account_Partner%]']`. **Fix (confirmed working):** `[PLM.Decision_Partner/PLM.Partner/Administration.Account_Partner = '[%CurrentUser%]']` β€” walk Partnerβ†’Account fully on the left, compare directly to the (already-an-Account) CurrentUser token. | This is genuinely invalid Mendix XPath, not an mxcli-specific bug β€” `CE0161` "Error(s) in XPath constraint" is Mendix correctly rejecting it every time it's checked, which is why it kept resurfacing across three separate incidents on a PLM parts-flow project (2026-07-22/23, `bug-logs/mxcli-bugs.md`) that were originally misdiagnosed as mxcli corrupting the domain model on unrelated grant rewrites. In fact the "unrelated entity broke too" symptom was just two independently-broken rules (both using the same invalid CurrentUser-path form) surfacing together once a full `mx check` ran β€” not one rule corrupting the other. Once rewritten to the correct bare-CurrentUser/full-LHS-chain form, the earlier "Studio Pro GUI only, module-wide" restriction no longer applies β€” **confirmed mxcli-safe 2026-07-23** via `test-05-currentuser-xpath-chain.mdl` (rebuilt all 4 role grants on the affected entity through mxcli exec, reproducing the corrected XPath verbatim, `mx check: 0 errors`). Use mxcli directly for this pattern; no GUI fallback needed. | +| 21 | `DROP` + `CREATE`, `create or modify` or `create or replace` any document **another script also edits** β€” an aggregator microflow, an after-startup chain, a navigation profile | **STOP β†’ `describe` the live document first, diff your restatement against that dump, and name in the script header which call sites you preserved. A new owner adds `-- supersedes: