Skip to content

Fix mxcli v0.29 compatibility; doctor advises the latest mxcli - #603

Merged
MendixMau merged 5 commits into
masterfrom
triage/mxcli-029-compat
Oct 31, 2026
Merged

MendixMau merged 5 commits into
masterfrom
triage/mxcli-029-compat

Conversation

@MendixMau

Copy link
Copy Markdown
Owner

Direct lane

What changed and why (one paragraph):
doctor --install fetches the latest mxcli, which is v0.29.0 today, and four instruments misread its output. (1) fix property-sets prints MIXED rows and exits 1, so doctor showed "could not classify" (rc 4) and sync showed it only as info, hiding a real Studio Pro merge hazard. It is now result mixed, with a WARN that names the rows and says --fix-property-sets cannot clear them. (2) The repair also exits 1 while a MIXED name remains, so exec.sh --patch rolled back a repair that had landed. The apply step now passes when only MIXED is left; FAILED still fails. (3) fix hashes now verifies MPR v1 with new wording, which exec.sh read as an error, so --patch on a Mendix < 10.18 project went unverified. exec.sh now reads both v1 forms. (4) Since v0.28, SHOW MODULES / list modules write Protected AddOn|Solution in the Source column. A first-party module set to Protected dropped out of page-scope.sh (FAULT, 0 modules) and out of the rehost module list. The export level no longer counts as an origin; Marketplace vX, Protected … stays excluded. Also in this PR: wf-add-path-terminators.py refuses below Mendix 10.21, because the terminator type doesn't exist there and writing it leaves the project unloadable (upstream versionInfo, ako/mxcli#1774). module-close.sh notes the v0.29 docker check default. The stale "stay on v0.24" pin advice is replaced. New: the normal doctor run compares the project mxcli with the latest release: a WARN with the release link and upgrade path when behind, a note when MXCLI_VERSION pins it, one quiet note when offline, and never a FAIL. --quick never makes the request, and MXTK_NO_LATEST_CHECK=1 skips it.

Impact

Row Answer
Process No new gate or human step, and nothing new blocks. The doctor advice is a WARN at most. The terminator patcher's new refusal (exit 3, nothing written) prevents an unloadable model.
Dependencies Touches project-bin/exec.sh: only the two hv_run regexes. bin/sync-project.sh: only the rc-1 message branch. bin/doctor.sh. It reads the existing asset redirect releases/latest/download/mxcli-linux-amd64; the redirect is not followed and nothing is downloaded. It also uses curl when present. No order dependency on #599–#601.
Context cost none for always-loaded text: render-routing.sh --check reads Baseline 64193 words (budget 80000) on base and head. The on-demand skills harness-architecture.md, report-schema.md and rehost-app.md gained one clause each on the Source rule.
Behaviour n/a: scripts, plus one clause in each of three on-demand skills restating the instrument's own rule.
Runtime A full doctor run (not --quick) adds one HTTPS request, capped at 5 s, about 0.3 s measured. Execs and gates: none.

Field evidence (cloud session, real public release binaries, sha256 in the CAPTURE files):

  • page-scope.sh --no-roles, real mxcli v0.29.0, captured model with its first-party module set to Protected: master FAULTs ("no first-party module"); this branch writes the module's one page.

  • doctor.sh against the same project with real v0.28.0 gives "behind the latest release v0.29.0" plus the upgrade path. With v0.29.0 it gives "is the latest release". Both read the live release redirect. The releases/latest page itself returned 403 through this proxy, which is why the check reads the asset redirect.

  • All golden input was captured, not hand-written: fix hashes v1 clean / v1 mismatch / v2 stale; property-sets MIXED-only, NEEDS+MIXED, the write, and the dry run after it; show modules / list modules for Protected and for Marketplace+Protected; fix --help / version for v0.28 and v0.29. Each mutation step and the model provenance are in fixtures/mxpatch/CAPTURE.txt, fixtures/property-sets/CAPTURE-v0.29.txt, fixtures/show-modules/CAPTURE.txt and fixtures/rehost-list-modules/CAPTURE.txt.

  • No client data anywhere in the diff (public mxcli test models only)

  • Size cap: over the cap. 16 non-fixture files, +364/−34. This is one PR on purpose: the doctor "advise latest" check must not ship before the fixes, or doctor would advise users into the breakage. Happy to split it if the reviewer prefers.

  • Test tier: T1 + T2. The scoped fixtures were run against this branch and against master as a control:

    • test-exec-hash-verify: 49/0 here, master 45/4
    • test-property-sets: 81/0 here, master 74/7
    • test-mxpatch: 44/0 here, master 43/1
    • test-page-scope-protected (new): 6/0 here, master 3/3
    • test-rehost-list-modules: 8/0 here, master 7/1
    • test-doctor-mxcli-latest (new): 12/0 here, master 4/8
    • Unchanged and still green: test-doctor-mxcli-arch, -stale-hooks, -docker-probe, -gate-selftest
    • check-portability is clean and check-scripts parses all scripts. The full suites were not run locally (CI runs them).
  • Golden input captured. Layouts: page-scope and exec resolve paths through _common.sh as before; no path logic changed. Platforms: POSIX awk split, grep -oE, and curl -w %{redirect_url} exist on macOS and Git Bash. The new fixtures use require_py/$PY.

  • CHANGELOG.md line appended

  • n/a: no new skill, no new bug entries

Not in this PR: retiring wf-add-path-terminators.py outright (mxcli writes the terminator itself since v0.22) is a removal and needs a separate decision.

Review: pending independent review


Generated by Claude Code

On mxcli v0.29.0, which doctor --install fetches by default, four
instruments misread the new output:

- fix property-sets MIXED rows: doctor now classifies them as "mixed"
  instead of rc 4 "could not classify".
- The repair exits 1 while only MIXED remains. The apply step no longer
  lets exec.sh --patch roll back a repair that landed.
- fix hashes now verifies MPR v1 with new wording. exec.sh reads both
  forms, so --patch on Mendix < 10.18 is verified again.
- SHOW/list modules "Protected AddOn|Solution" in Source (v0.28+):
  page-scope and the rehost module list keep first-party Protected
  modules.

Also in this change:
- wf-add-path-terminators.py refuses below Mendix 10.21.
- module-close notes the v0.29 docker check default.
- The stale v0.24 pin advice is gone.
- New: the normal doctor run advises when the project mxcli is behind
  the latest release, respects MXCLI_VERSION pins, stays quiet offline
  and never fails.

Golden input was captured from the real v0.28.0/v0.29.0 binaries
(CAPTURE files hold the sha256s and mutation steps). Against master the
new cases fail: exec-hash-verify 4, property-sets 7, mxpatch 1,
page-scope-protected 3, rehost-list-modules 1, doctor-mxcli-latest 8.

Field run: page-scope.sh and doctor.sh against the real v0.29.0 and
v0.28.0 binaries on the captured model. Master page-scope FAULTs on the
Protected model and the fix counts its page. The doctor advice read
v0.29.0 from the live release redirect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LeNWZV2sVH62vkgfYh5u5
`printf | grep -q` under pipefail can SIGPIPE printf and flip the
result; test-pipefail-grep-q.sh flagged sync-project.sh:1702. Same
pattern as the rest of the file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018LeNWZV2sVH62vkgfYh5u5
A ~/.curlrc with `location` made curl follow the asset redirect and
download the whole binary: 106,696,864 bytes measured, then "not
checked". `curl -q` as the first argument skips .curlrc. Measured with
HOME pointing at a .curlrc that sets `location`: without -q, 106696864
bytes downloaded and no redirect_url; with -q, 0 bytes and the
redirect names v0.29.0.

test-doctor-mxcli-latest 12/0.

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

Copy link
Copy Markdown
Owner Author

Independent review: MERGE (after one fix, re-reviewed at 9bb03e4c).

  • Fixed: the latest-version check now runs curl -q, so a ~/.curlrc with location can no longer make it follow the redirect and download the binary. Measured: 106,696,864 bytes before the fix, 0 after, and the redirect still names v0.29.0.
  • Behaviour change, intended: an unpinned project whose mxcli is behind the latest release now gets a WARN on a normal doctor run, so doctor exits 1 instead of 0 and the receipt verdict becomes warn, which status.sh shows.
    • The callers I found ignore that exit code (init-project.sh uses || true).
    • --quick never runs the check, so exec.sh and session-check.sh are unaffected.
    • MXCLI_VERSION=<version> turns the WARN into a note; MXTK_NO_LATEST_CHECK=1 skips the check.
  • Also new: a model with only MIXED property-set rows gets a sync warning on every sync, because mixed is never cached as settled. This is intended: it is a real merge hazard.
  • Left as is (low, optional):
    • On MPR v1, the rewrite-credit path in exec.sh has no file path to compare. mxpatch refuses v1, so this doesn't arise in practice.
    • The sqlite URI in wf-add-path-terminators.py is not percent-encoded. It fails open with a note.
    • The terminator refusal reuses exit 3.

Generated by Claude Code

@MendixMau
MendixMau merged commit 41e0137 into master Oct 31, 2026
2 checks passed
MendixMau pushed a commit that referenced this pull request Oct 31, 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