Skip to content

Lift the marketplace-install STOP (#879 fixed in v0.21.0), and two UI learnings from the same run - #36

Open
MendixMau wants to merge 4 commits into
masterfrom
claude/mxcli-project-setup-clhy8g
Open

Lift the marketplace-install STOP (#879 fixed in v0.21.0), and two UI learnings from the same run#36
MendixMau wants to merge 4 commits into
masterfrom
claude/mxcli-project-setup-clhy8g

Conversation

@MendixMau

Copy link
Copy Markdown
Owner

Direct lane (changes to skills/, bug-logs/, bin/, project-bin/, project-tests/, pipelines)

What changed and why (one paragraph):

This toolkit told four days of sessions that mxcli marketplace install would corrupt their project. It stopped being true on 2026-09-06. mendixlabs/mxcli#879 is closed in v0.21.0 — install no longer shells out to mx module-import; it copies the module's units with mxcli's own writer, so MPR v2 survives, and the destructive path is opt-in behind --allow-format-change. The ledger entry is retitled RESOLVED (old content kept verbatim under a HISTORICAL RECORD heading, superseded prevention rule marked v0.20.0-and-earlier rather than deleted), the STOP in learned-mdl-preflight.md is lifted, and bug-lookup.sh 879 now leads with the fix. Three new traps replaced the old one and are documented with their repairs: packages don't carry their dependencies (the failure reads as 406 individual CE1613 element errors, not "module missing"), the two mxcli fix repairs the installer prints are mandatory rather than advisory, and a bundled widget can silently fail to land with the installer unable to self-repair it. The PR also carries two UI learnings from the same overnight run — see below.

Field evidence — which real project this ran against / was observed in, and what it measured or fixed there:

A change-governance (MOC/PSSR) app replacement, 2026-09-10, mxcli v0.21.0, Mendix 11.14.0, 501-unit split-model project.

Marketplace fix, confirming run — four modules installed (MxModelReflection 9.1.0, Encryption 11.1.2, CommunityCommons 11.5.1, Email_Connector 6.4.3):

501 -> 1075 .mxunit files     split format preserved
.mpr 84 KB -> 156 KB          an index, not the 35 MB blob #879 produced
native mxbuild                0 errors
app boots; two e2e journeys unchanged (33/33, 12/12)
  • The four-day gap is the finding, not a footnote. v0.21.0 shipped 2026-09-06; the project carried "marketplace install is BLOCKED, needs a human in Studio Pro" until 2026-09-10 — with both .mpk files already downloaded and sitting in the project root the whole time, because the blocker was never the download. retesting-learned-rules.md exists for precisely this and nobody ran it. A STOP is a claim about a binary version, and it expires.
  • Reusable beyond this bug: the entry now carries the zero-risk way to re-probe a formerly-corrupting command on a real project — git clone --depth 1 file://$(pwd) into a scratch dir, install into the clone, count .mxunit and run mx check there, decide from the measurement. Cheaper than the documented recovery, and it answers what a changelog cannot.
  • Trap 1 — dependency closure for Email Connector 6.4.3 is MxModelReflection + Encryption + CommunityCommons (checks at 0 errors); SAML 4.2.3 additionally pulls UserCommons. Aggregation one-liner included.
  • Trap 2mxcli fix widgets changed 128 units (CE0463), mxcli fix design-properties 12 (CE6087).
  • Trap 3widgets/RichText.mpk landed on the probe and not on the real run (33 vs 34 widgets, 3 × CE0462 over an otherwise clean model); re-run refuses with "already installed"; repair is unzip -o -j from the already-downloaded .mpk. Count widgets/ before and after every install.
  • Still needs Studio Pro, now scoped rather than assumed: SAML + UserCommons install cleanly but leave CE0066 ("Entity access is out of date"). No mxcli fix security exists, and forcing the recompute with an MDL GRANT was tried and does not clear it.

The two UI commits in this branch, same project, 2026-09-10learned-css-that-never-applied.md (new skill) and a section added to learned-mdl-cannot-express.md. Two UI passes on the same day and the same design system, the first called "poor" and the second "much better"; the authoring did not improve, the closing check did — pass 1 verified that the script executed, pass 2 verified that the pixel changed. Measured: .ds-tablewrap/table.ds-table had never matched an element because DataGrid2 renders <div class="tr"> and there is no <table> on any page; three guessed top-bar selectors matched zero elements; .mx-listview-empty lost to Atlas's 0,2,1 from ~11,000 lines earlier; and four complete semantic tint sets plus a five-step elevation scale sat in ds.css, correct and bound to zero widgets — the design system was finished and the app was grey. Also records that the spec's per-row-tone fix prescribed DynamicRowClass, a property that exists in neither MDL nor Studio Pro, and that :has() off an already-bound DynamicCellClass delivered it across three pages with zero MDL.

  • No client data anywhere in the diff
  • For a new/changed instrument: no instrument changed in this PR — documentation, ledger and skills only
  • For a new skill: routing row added (bin/lib/skill-routing.tsv + bin/render-routing.sh) — learned-css-that-never-applied routed baseline for mdl/review/gate at stages 5–6; render-routing.sh --check reports surfaces in sync, baseline 75,320 words of 80,000
  • CHANGELOG.md line appended in this PR, crediting the source project or person
  • New bug entries headed ## BUG-DRAFT-<slug>: — n/a, no new bug entries; this PR resolves an existing filed issue (#879) and adds no numbered entry

Generated by Claude Code

The scorer already excludes <td>, because a wireframe's table cells are
sample rows and a page that correctly binds them contains none of that
literal text. The same is true of a bound value anywhere else, and there
the structure gives nothing away: an <h1> holding a record's number and
name looks exactly like an <h1> holding page copy.

Measured on a MOC/PSSR app replacement's project detail page: 54%, all
three misses being sample values the page could not contain — the
record's own title, and a mocked attachment's filename twice. The page
was right, the denominator was wrong, and that number was about to be
read off as a gate verdict.

So the marker is declared, not guessed. An element carrying
class="bound" leaves the text corpus and the class denominator. Guessing
was the alternative and it does not work: a heading is bound or it is
not, and only the person who drew the screen knows which.

Fixture grows to 18 assertions, including that a bound heading leaves
the DENOMINATOR and not merely the missed list — otherwise the score
would be 1 of 2 and still look clean. Known-bad control without the
marker fails 5 of 18. The same page scores 100% with it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jj5uvTmmcBQT8Uu3asm21M
…elity.js

From the moc-app-replacement project's overnight session: 4 of 8 admin
pages went unstyled and unreachable through two build scripts because
neither the per-script UI loop nor the module-close review actually ran
the fidelity harness that already exists in this toolkit. Proposes
adding an explicit "run page-fidelity.js now" step plus a reachability
question to ui-loop.md -- not applied directly, per this repo's own
baseline-test-before-rewrite rule for behaviour-shaping skills.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jj5uvTmmcBQT8Uu3asm21M
…nd the first did not

A change-governance app went through two UI passes on the same day, on the same
design system. The user called the first "poor" and the second "much better".
The CSS authoring did not get better in between. The closing check did.

  Pass 1 verified that the SCRIPT EXECUTED.
  Pass 2 verified that THE PIXEL CHANGED.

Every green signal in pass 1 was true and irrelevant: mx check clean, lint
clean, MDL suite green, two journeys green, the design port reporting its
tokens correctly landed in the right file — over an app whose grid header was
white on white and whose entire table stylesheet had never matched an element.

New skill, learned-css-that-never-applied.md. Deliberately NOT a restatement of
ui-loop.md ("judge from the screenshot") or check-design-reaches-app.sh ("did
the classes arrive"). Both are right and both were already here. A screenshot
tells you something is wrong; it cannot tell you whether your rule matched
nothing, matched too much, or matched and lost. That is the missing rung.

Three ways a perfectly correct rule paints nothing, all three met in one run:

  1. MATCHES NOTHING. ds.css styled .ds-tablewrap / table.ds-table. DataGrid2
     renders a row as <div class="tr">; there is no <table> on any page. Not
     one table rule had ever applied, through a full design port and two build
     phases. Separately, three top-bar selectors were guessed in one sitting
     and all three matched zero elements; one read of the live element chain
     named the real carrier.
  2. MATCHES TOO MUCH. The instinct after (1) is to widen. .mx-page painted the
     nav bar with the page ground: white menu text on a white bar.
  3. LOSES THE CASCADE. .mx-listview-empty named the right element, sat ~11,000
     lines after Atlas, and still lost — Atlas's 0,2,1 against a bare class's
     0,1,0, so source order was never consulted. And that rule sets
     border-style:none/background:transparent: Atlas is ERASING the element,
     not failing to style it.

The diagnostic is two reads before touching the rule: computed style, then a
parentElement walk only if the element was not found. The three possible
answers have three different fixes, which is the point — a blind rewrite would
have been wrong in all four field misses, and in case 2 the rewrite WAS the
outage.

Completion criterion carries a denominator, per authoring rule 4: every
component class a pass claims to have shipped gets one computed-style read
against a named element in the running app, or is reported unverified. The run
that justifies that wording had row tone implemented, screenshotted, and
looking fine while rendering a rejected project amber — two value reads caught
it, the eye did not.

Also records the check that comes first and that no CSS instrument can see,
because nothing is wrong with the CSS: at the moment the user called the UI
poor, four complete semantic tint sets, a five-step elevation scale and a
styled empty state were all present, all correct, and bound to ZERO widgets.
The design system was finished and the app was grey. Measure it as "N of M
component classes have at least one carrier in the model" — a zero-carrier
class is never fixed by rewriting it, only by binding it. Three of the five
improvements the user reacted to were pure binding of CSS already in the file.

Second, into learned-mdl-cannot-express.md: when MDL cannot set a class, CSS
usually can. The spec carried per-row tone as an M-sized MDL task prescribing
DynamicRowClass — a property that exists in neither MDL nor Studio Pro, written
months earlier against an imagined API. Whatever class MDL CAN bind is a hook
the stylesheet reads from anywhere in that subtree, so :has() off the
already-bound DynamicCellClass gave three pages row tone with zero MDL. Written
as a positive recipe rather than a prohibition (authoring rule 3): the failure
it retires is stopping at "MDL has no such property" when the requirement was
never about MDL.

Routed baseline for mdl/review/gate at stages 5-6, on this repo's own rule that
a skill living only in the situational table goes unnoticed by projects not
hunting for it — and not being reached is exactly what this one records.
render-routing.sh --check: surfaces in sync, baseline 75206 words of 80000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jj5uvTmmcBQT8Uu3asm21M
…0.21.0

This toolkit told four days of sessions that `mxcli marketplace install` would
corrupt their project. It stopped being true on 2026-09-06.

mendixlabs/mxcli#879 is closed in v0.21.0. Install no longer shells out to
`mx module-import`; it copies the module's units with mxcli's own writer, so
MPR v2 survives. The destructive path is opt-in behind --allow-format-change,
so the corruption can now only be produced deliberately.

Re-probed 2026-09-10 on a real 501-unit split-model project, four modules:

  501 -> 1075 .mxunit files     split format preserved
  .mpr 84 KB -> 156 KB          an index, not the 35 MB blob #879 produced
  native mxbuild                0 errors
  app boots; two e2e journeys unchanged (33/33, 12/12)

The cost of not re-probing is the finding here, not a footnote. The project
that found the fix carried "marketplace install is BLOCKED, needs a human in
Studio Pro" in its register for four days after it stopped being true — with
both .mpk files already downloaded and sitting in the project root the whole
time, because the blocker was never the download. retesting-learned-rules.md
exists for exactly this and nobody ran it. A STOP is a claim about a binary
version, and it expires.

So the entry now also carries the zero-risk way to re-probe a formerly
corrupting command on a REAL project, which is reusable well beyond this bug:
git clone --depth 1 file://$(pwd) into a scratch dir, install into the clone,
count .mxunit and run mx check there, decide from the measurement. Cheaper
than the documented recovery, and it answers what a changelog cannot.

The ledger entry is retitled RESOLVED with the old content kept verbatim below
a HISTORICAL RECORD heading, and the superseded prevention rule marked as
applying to v0.20.0 and earlier rather than deleted — a ledger entry that
vanishes reads as a bug never found, and projects pinned to older binaries
still need it.

THREE NEW TRAPS REPLACED THE OLD ONE. All live on v0.21.0, none self-announcing:

1. Marketplace packages do not carry their dependencies, and the failure does
   not say "module missing" — it says 406 individual CE1613 element errors.
   The entry carries the aggregation one-liner that turns that wall into a
   shopping list. Email Connector 6.4.3's closure is MxModelReflection +
   Encryption + CommunityCommons, which checks at 0 errors.

2. The two `mxcli fix` repairs the installer prints are mandatory, not
   advisory: 128 units and 12 units changed on the confirming run. Both
   subcommands exist precisely because Mendix's own tools would collapse
   MPR v2 without them.

3. A bundled widget can silently fail to land, and the installer cannot
   self-repair it. widgets/RichText.mpk landed on the probe and not on the
   real run — 33 widgets against 34, 3 x CE0462 over an otherwise clean model
   — and a re-run refuses with "already installed". Repair is to unzip it out
   of the .mpk the installer already downloaded. Count widgets/ before and
   after every install.

One thing genuinely still needs Studio Pro, and it is now scoped rather than
assumed: SAML + UserCommons install cleanly but leave CE0066 ("Entity access
is out of date"). There is no `mxcli fix security`, and forcing the recompute
with an MDL GRANT was tried and does not clear it.

bug-lookup.sh 879 now leads with the fix rather than the STOP.
render-routing.sh --check: surfaces in sync.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jj5uvTmmcBQT8Uu3asm21M
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