Skip to content

Promote the 2026-09-27 guest-groups harvest: exec gate version mismatch, v1 auto-restore, CE0639, four bug drafts, e2e Chromium fallback - #161

Merged
MendixMau merged 17 commits into
masterfrom
claude/keen-euler-3g9ynp
Sep 28, 2026
Merged

MendixMau merged 17 commits into
masterfrom
claude/keen-euler-3g9ynp

Conversation

@MendixMau

@MendixMau MendixMau commented Sep 27, 2026 •

Copy link
Copy Markdown
Owner

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

What changed and why (one paragraph):
This PR promotes eight contrib/inbox/2026-09-27-* files and deletes each one in the same commit that consumes it. It makes five changes:

  1. Exec gate false green. mxbuild refuses a model from another Mendix version with exit 3, the reason in errors[] and an empty problems[]. The gate counted that as 0 errors and logged "pass · mxbuild clean". Now mxtk_mxbuild_error_count returns ? (unverified) for a refusal. find_mxbuild also picks the mxbuild that matches the model's _MetaData._ProductVersion instead of the newest one, and announces any fallback.
  2. v1 auto-restore. exec.sh had its own inline restore that only handled mprcontents/. It now restores through restore-mpr.sh, which covers v1 single-file, v2 and two-tree layouts. It only reports a rollback when the restore actually ran. sync-project.sh flags installed copies that are missing this arm.
  3. CE0639. The rule said CE0639 on validation feedback could not be avoided. It no longer reproduces on v0.23.0, so the rule is restamped. Feedback now goes in VAL_/SUB_ microflows, and ACT_ calls them and branches on the result. A WRONG/RIGHT pair is included, and both halves pass mxcli check. The cookbook and the build-loop handoff table are corrected to match.
  4. Four BUG-DRAFT-* ledger entries, all findable with bin/bug-lookup.sh:
    • XPath system member in the wrong case gives CE0161.
    • owner Both is ignored on modify.
    • Cross-module owner Both gives CE0066.
    • Audit-member CE0066. This one is fixed upstream; the entry adds the process point of recording mxcli --version.
  5. e2e Chromium fallback. When the Chromium that Playwright pins is missing, the e2e launchers now use PW_EXECUTABLE, then /opt/pw-browsers/chromium.

Field evidence:

  • Items 1, 2 and 4: observed on an existing-app change project (Mendix 11.12.2, mxcli v0.23.0, v1 single-file .mpr). There, 29 of 29 execs logged "mxbuild clean" against a refusing 11.14.0 Beta mxbuild, one of them over a real CE0066. The refusal's errors file is captured verbatim as tests/wave2/fixtures/mxbuild-version-mismatch.errors.json. The _MetaData shape was read off the real model.

  • Item 3: re-probed on v0.23.0. Both MDL halves pass mxcli check.

  • Item 5: field run in a cloud container that had chromium-1194 but not the pinned 1243. With the pre-fix helper, the launch fails with "Executable doesn't exist … chrome-headless-shell". With the patched helper, it launches Chromium 141.0.7390.37 and renders a page.

  • No client data anywhere in the diff. Ledger entries describe the project generically.

  • Size cap is exceeded: 22 files including 8 inbox deletions, and about 450 non-fixture lines, mostly _common.sh and exec.sh. The five commits are separable (one per item) and can be split into stacked PRs on request.

  • Test tier reached: T0, T1 and T2 (see below). T3 is left to CI.

  • New/changed instrument: the golden input is captured, not hand-written. Both layouts are covered: restore-mpr.sh handles single-tree and two-tree, and the fixtures build v1 and v2 projects. On platforms, find_java on macOS prefers JDK 21, and the version probe uses Python sqlite3 with a fallback to the newest mxbuild. Windows was checked by test-common-windows.sh.

  • New skill: n/a (no new skill; routing not touched).

  • CHANGELOG.md line appended for each item, crediting marketplace-rnd.

  • New bug entries are headed ## BUG-DRAFT-<slug>:.

Checks run (T1, scoped):

Fixture Result Positive control
tests/wave2/test-mxbuild-version-match.sh project-bin/_common.sh (new) 18/18 pre-fix: 10 fail
tests/wave2/test-bug07-08.sh project-bin/exec.sh (new cases K and L) 43/0 pre-fix: K fails 4, L fails 3
test-common-windows.sh project-bin/_common.sh 10/0 —
test-doctor-gate-selftest.sh bin/doctor.sh 28/0 —
test-bug12-sync.sh bin/sync-project.sh 60/0 —
test-bug09-13.sh skills/iterative-build-loop.md 22/0 —

bash -n and node --check pass on the changed scripts.

Not run: tests/run-tests.sh and both full suites (T3, left to CI), and render-routing --check (routing untouched).

Not changed, reported only: the toolkit's CONV010 allowlist lacks ValidationFeedbackAction, and also NanoflowCallAction and ShowHomePageAction, which upstream has.

Two follow-up commits (independent of the five above, can be split off)

These two commits sit on top of the five above but don't depend on them. They can go to their own PR if you'd rather review them separately.

  • 7392b03 exec.sh --patch. Runs a one-off script that edits the model directly (a Python BSON patch) through the MDL chain: snapshot, baseline, version-matched mxbuild gate, restore through restore-mpr.sh, and a BUILD-LOG row. The patch is kept only if the gate verifies it. A non-zero exit, a failed gate, a gate that cannot run and an unverified result are all rolled back, and ALLOW_UNVERIFIED does not apply. The chain does not guard anything outside the .mpr. ./bin/exec.sh is allow-listed, so in auto mode Claude Code's classifier does not review the script; the header says so. sync-project.sh flags installed copies from before this change, and learned-mdl-preflight.md Step 0 has one line pointing at it.
    Field runs used a scratch copy of the real model (Mendix 11.12.2, v1 .mpr):
    • The idempotent guest-groups patch wrote 0 units and passed the gate in 182s, with the model byte-identical afterwards.
    • A script that deleted 50 units and exited 2 was restored byte-identical, with no mxbuild run.
    • A script that wrote garbage into 20 units and exited 0 failed the gate ("Expected '$ID' as the first property") and was restored byte-identical.
      Fixtures: test-bug07-08.sh project-bin/exec.sh 43/0. test-bug12-sync.sh bin/sync-project.sh reached 55 ok / 0 fail through T13, then hit a 25-minute timeout on a starved host; it has no assertions on exec.sh notes.
  • c88ddf6 install-claude-permissions doc finding. The request was to write autoMode.environment into the project's settings. That cannot work. https://code.claude.com/docs/en/auto-mode-config (checked 2026-09-27) says the classifier reads autoMode only from ~/.claude/settings.json, managed settings and --settings, and never from .claude/settings.json or .claude/settings.local.json. The settings reference gives its scope as "User or managed". So this commit writes no autoMode anywhere. The script header and agent-permission-friction.md record the finding and name the two routes that do work: /auto-mode-setup (the user's own decision) and ./bin/exec.sh --patch. No code or permission rules change. Field run on a scratch copy of the project's .claude/: install, jq validation, --check 1→0, idempotent reinstall and --uninstall all behaved as expected. test-install-claude-permissions.sh 66/0.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q

…n bindings

mxcli DESCRIBE prints IMAGE ImageUrl as a bare '{1}' and drops the bound
attribute, so a DESCRIBE-only score reported bound images as missed. The
scorer now reads ALTER PAGE bodies too and notes the DESCRIBE blind spot.
Regression fixture from real marketplace-rnd DESCRIBE output (renamed).
Field run: marketplace-rnd CatalogView_v5, 78% -> 82% with script 25.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…n a Dojo-client Mendix 11 project

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…e script

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…pstream drafts)

Hand-mined learnings from marketplace-rnd guest-groups work, triaged against the ledger,
learned-* skills and existing inbox. Includes the exec.sh false-green on mxbuild version
mismatch (29/29 rows), missing v1 auto-restore arm, XPath case CE0161, owner Both CE0066,
and ranked mxcli upstream issue drafts. Probes ran on scratch copies only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…model's mxbuild version

mxbuild of another Mendix version refuses the model. It exits 3, puts the reason in
errors[] and leaves problems[] empty. The gate counted 0 Error problems and logged
"pass · mxbuild clean". find_mxbuild picked the newest mxbuild (a Studio Pro 11.14.0
Beta), not the one that matched the model.

- _common.sh: mxtk_model_version reads _MetaData._ProductVersion (sqlite3 or python,
  read-only). find_mxbuild prefers a Studio Pro or mxcli-cache mxbuild of that version,
  and mxtk_ensure_mxbuild warns when none exists. mxtk_mxbuild_error_count returns "?"
  for 0 problems with a non-zero exit and exposes mxbuild's errors[] reason as
  MXTK_MXBUILD_WHY. find_java on mac prefers JDK 21 (JDK 25 breaks the Mendix 11 deploy
  build).
- exec.sh: such a run is gate "unverified", with the reason and the remedy in the
  BUILD-LOG row. verify-model.sh says the same.
- sync-project.sh: flags installed _common.sh and exec.sh copies that lack the fix.
- Fixtures: test-mxbuild-version-match.sh (new) and test-bug07-08.sh case K, with the
  verbatim refusal errors file as golden input. Both fail against the pre-fix scripts
  (10 and 4 failures), and the pre-fix row reads "pass · mxbuild clean".

Field run: marketplace-rnd, Mendix 11.12.2, mxcli v0.23.0, 2026-09-27 guest-groups
build. 29 of 29 Mac BUILD-LOG rows were false greens, and one hid 2xCE0066. With the
patched selection, the matching 11.12.2 mxbuild reported the CE0066 (review runs B, H,
J and K).

Promotes contrib/inbox/2026-09-27-exec-gate-false-green-version-mismatch.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…ingle-file included

exec.sh had an inline copy of the restore with only the mprcontents/ (v2) arm. On a v1
single-file .mpr, a failed gate printed "Snapshot has no mprcontents/ — refusing to
restore from it" and left the broken model in place. The attribution rebuild then
measured that same broken model and logged the script's own error as "PRE-EXISTING".

- exec.sh calls bin/restore-mpr.sh (v1, v2, two-tree; installed beside exec.sh) instead
  of its inline copy. When no restore happens, the row says "NOT rolled back", no
  attribution is run, and the recovery command matches the layout.
- An unmeasurable restored model ("?") no longer reads as "builds clean".
- sync-project.sh names the fix for installed exec.sh copies that lack it.
- test-bug07-08.sh case L: a v1 model with a failed gate ends byte-identical to its
  snapshot, and the row does not blame PRE-EXISTING. The pre-fix exec.sh fails all three
  assertions. The fixture project now installs restore-mpr.sh beside exec.sh, as
  install-manifest does, and case B's v2 restore runs through it.

Field run: marketplace-rnd, a 152 MB v1 .mpr, Mendix 11.12.2, mxcli v0.23.0, 2026-09-27
guest-groups build.

Promotes contrib/inbox/2026-09-27-exec-autorestore-no-v1-arm.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…edback goes in VAL_/SUB_, not ACT_

- learned-microflow-patterns.md: the "CE0639 unavoidable via mxcli" rule is stamped
  retested / not reproducing on mxcli v0.23.0 and Mendix 11.12.2 (BUG-47 was resolved on
  2026-08-03). The old Studio Pro workaround is kept as history. The object-only CE0091
  form (BUG-ENGALAR-05) is still flagged.
- The "correct pattern" section recommended validation feedback directly in an ACT_
  microflow. CONV010 lints that red, because ValidationFeedbackAction is not on the
  ACT_ allowlist. Replaced with the VAL_/SUB_-gives-feedback, ACT_-calls-and-branches
  recipe, as a WRONG/RIGHT pair. Both pass `mxcli check` on v0.23.0.
- mdl-cookbook-microflows.md and iterative-build-loop.md carried the same stale rule;
  both are corrected.
- Checked: lint-rules/conv010_act_microflow_content.star is not obsolete against
  upstream's re-synced rule. It keeps the per-microflow de-noising and the
  LogMessage/CreateVariable/ErrorEvent/InheritanceSplit allowlist that upstream lacks.

Field run: marketplace-rnd, Mendix 11.12.2, mxcli v0.23.0, 2026-09-27 guest-groups build
(SUB_AddGuestsToGuestGroup with validation feedback, exec gate clean; catalog probe:
87 ValidationFeedbackAction, 13 NanoflowCallAction).
Scoped check: tests/wave2/test-bug09-13.sh skills/iterative-build-loop.md, 22/22.

Promotes contrib/inbox/2026-09-27-learned-microflow-patterns-stale-ce0639.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
Promotes four contrib/inbox harvest files into bug-logs/mxcli-bugs.md as
BUG-DRAFT entries, each findable with bin/bug-lookup.sh:
- xpath-system-member-case: [CreatedDate >= $Since] passes check
  --references and fails the build with CE0161
- association-owner-ignored: create or modify association ... owner Both
  reports "Modified" and leaves the owner unchanged
- association-owner-both-cross-module-ce0066: drop + create with owner
  Both across modules leaves stale access rules, so CE0066
- audit-member-access-ce0066: fixed upstream in v0.22+; process point is
  to record mxcli --version in BUILD-LOG rows

Field run: marketplace-rnd, Mendix 11.12.2, mxcli v0.23.0, the
2026-09-27 guest-groups build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…hromium

launchBrowser and launchBrowserAt now resolve an executablePath:
PW_EXECUTABLE wins; otherwise, only when the Chromium this Playwright
pins is missing, /opt/pw-browsers/chromium if present; a configured
channel is left alone. Promotes the inbox file
2026-09-27-e2e-helpers-playwright-executable.md (deleted here).

Field run: marketplace-rnd, Mendix 11.12.2, mxcli v0.23.0, the
2026-09-27 guest-groups build. The cloud container had no chromium-1243,
only chromium-1194. With the pre-fix helper the launch fails ("Executable
doesn't exist ... chrome-headless-shell"); with the patched helper it
launches Chromium 141.0.7390.37 and renders a page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…store, BUILD-LOG

A Python BSON patch (for what mxcli cannot express, e.g. an association
owner change) used to run bare: no snapshot, no mxbuild gate, no restore,
no BUILD-LOG row. In auto mode Claude Code's classifier also refused
`python3 patch.py Marketplace.mpr` as "Irreversible Local Destruction".

`./bin/exec.sh --patch <script> [args]` runs it as
`<interpreter> <script> <model.mpr> [args]` (.py -> python3, .sh -> bash,
else executable; MXTK_MPR/MXTK_MODEL_DIR exported) inside the existing
chain: snapshot, baseline, version-matched mxbuild gate, restore via
restore-mpr.sh, BUILD-LOG row "patch: <name>". No mxcli check and no
module-brief advisory (neither can read a script). A patch is kept only on
a verified gate: a non-zero exit is restored at once without an mxbuild; a
gate that fails, cannot run, or reads unverified is restored as well, and
ALLOW_UNVERIFIED does not apply. The restore is now one restore_snapshot()
shared with the MDL CE-fail path. The header states what it does not
guard: anything outside the .mpr, and in auto mode the classifier does not
review a script launched through the allow-listed ./bin/exec.sh.

sync-project.sh flags an installed exec.sh that predates --patch;
learned-mdl-preflight.md Step 0 gets one line pointing at it.

Field runs (2026-09-27, scratch copy of marketplace-rnd's Marketplace.mpr,
Mendix 11.12.2, mxcli v0.23.0, v1 single-file .mpr, sha256 ca30eb97...):
- mdlsource/guest-groups/14-one-to-one-guestgroup-app.py (idempotent):
  "units written: 0", gate pass, exit 0, 182s, model sha unchanged; row
  `patch: 14-one-to-one-guestgroup-app.py | pass | applied`.
- fail-exit.py (deletes 50 Unit rows, sys.exit(2)): restored, exit 2,
  sha256 -c OK; row `not-run | patch failed | script exit 2 - rolled back`.
- corrupt.py (garbage into 20 unit blobs, exit 0): mxbuild "Expected '$ID'
  as the first property of a storage object", gate fail, restored, exit 1,
  84s, sha matches original; row `fail | patch rolled back`.
Fixtures: test-bug07-08.sh project-bin/exec.sh PASS=43 FAIL=0;
test-bug12-sync.sh bin/sync-project.sh 55 ok / 0 fail through T13 before a
25-minute timeout on a starved host (it asserts nothing on exec.sh notes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
… project

Asked to merge autoMode.environment entries into the project's settings.
The docs say that cannot work, so this ships the finding, not a fake:

- https://code.claude.com/docs/en/auto-mode-config ("Where the classifier
  reads configuration", fetched 2026-09-27): autoMode is read from
  ~/.claude/settings.json, managed settings and --settings / the Agent SDK.
  "The classifier doesn't read `autoMode` from project settings in
  `.claude/settings.json` or `.claude/settings.local.json`. Both files live
  in the repo directory, so a checked-in repo or a build step could
  otherwise inject its own allow rules."
- https://code.claude.com/docs/en/settings-reference: autoMode scope
  "User or managed".

The installer does not write ~/.claude/settings.json either (user-wide,
outside the project; that is the user's call via /auto-mode-setup). The
header now says so and names the project-level route, ./bin/exec.sh
--patch (previous commit). agent-permission-friction.md Step 2 check 2
gains the refused-patch case, with the caveat that the allow-listed
exec.sh is not reviewed by the classifier, so a patch's effects outside
the .mpr must be read first. No code change; no permission rule added.

Field run (2026-09-27, scratch copy of marketplace-rnd's .claude/):
--check before exit 1 (the project lacks the toolkit entries); install
added 11 entries to settings.json and 2 to settings.local.json; jq
validated both; --check after exit 0; reinstall "nothing to do";
--uninstall removed exactly the inserted entries, leaving an empty
"deny": [] key in each file (pre-existing behaviour, not changed here).
Fixture: test-install-claude-permissions.sh PASS=66 FAIL=0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
…g9ynp

# Conflicts:
#	CHANGELOG.md
#	bug-logs/mxcli-bugs.md
upstream-feedback.md: mxcli goes from issues-only to issue first, plus
a PR when §3a holds (issue filed, rebased on current upstream main, full
make test, field proof, one concern). New vehicle row and decision line.

bug-logs/submitted-prs/mxcli/2026-09-27-file-uploader-nested-visibility:
the format-patch, PR title and body, and send steps. #1199 was dropped
because it was already fixed upstream.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
bug-logs/upstream-log-2026-09.md indexes what was sent to mendixlabs/mxcli
and what is ready. The 7 unfiled issue drafts move into
pending-github-issues/ with project names replaced by placeholders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DyrzWc5YejD1iBLgJ7TS7q
@MendixMau
MendixMau merged commit f690449 into master Sep 28, 2026
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