Skip to content

new(canvas): mf-canvas-facts.py prints how a microflow lies on the Studio Pro canvas - #534

Closed
saingge wants to merge 1 commit into
MendixMau:masterfrom
saingge:new/canvas-facts
Closed

saingge wants to merge 1 commit into
MendixMau:masterfrom
saingge:new/canvas-facts

Conversation

@saingge

@saingge saingge commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Branch new/canvas-facts, one commit (3edf954) on origin/master 393d253. Lane 3 (direct). First of a stack of three: this PR, then learn/canvas-readability (the skill that judges the facts), then fix/canvas-note-sides (a repair for one fact). Merge in that order.

What changed and why

A microflow can build, pass its tests and still be hard to read in Studio Pro: labels on top of each other, a line through an object, a note line that leaves the side facing away from its object, a decision whose true branch answers "no" to its caption. mxbuild, mxcli check and lint see none of it.

project-bin/mf-canvas-facts.py reads the microflow and nanoflow units through mxpatch.py (the toolkit's one BSON reader), draws the boxes, labels, notes and lines the way Studio Pro does, and prints one line per fact: OVERLAP, LINE, NOTE-SIDE, LEFTWARD, TURN, CAPTION, SENSE. It prints facts, not verdicts, and writes nothing. Exit 0 measured, exit 2 could not measure (a named flow that is not there, a unit that does not decode, no model); the flows that did decode are still printed.

verify-module.sh runs it per module as an information rung (step 1c, log 14-canvas-facts.log; master's steps are 0, 0b, 1, 1b and 2 onward, and the logs 09-13, 20-21, 30, 39, 40, 50, 51, so neither collides). A missing script or .mpr is a FAULT row that says to run bin/sync-project.sh, never a skip. mf-canvas-facts.py goes in MXTK_PROJECT_BIN.

Calibration (label width about 5.5 units per character, 3 caption lines of about 16 characters on an activity, 2 lines of about 10 on a decision, the side numbering of notes and objects) is from Studio Pro 10.24 screenshots and stored models. It is not verified on Studio Pro 11. The script header says so.

Size: one counted file is the instrument, 391 lines, with its 89-line test; the whole PR is 5 counted files and 517 lines against the 400-line cap. It cannot be split further: a script without its fixture breaks field-proof rule 1, and the verify-module rung is 17 lines that exist only to run it. The judging skill is the next PR in the stack.

Impact

Row Answer
Process One information rung added to verify-module.sh. It never gates (kind info; its exit 2 lands in FAULT like any instrument that could not run). No new human step, no new stage artifact.
Dependencies Shared files touched: project-bin/verify-module.sh, bin/lib/install-manifest.sh, CHANGELOG.md. The rung reads mf-canvas-facts.py (this PR), mxpatch.py and mxunit_bson.py (both already on master) and the project's .mpr (found by find_mpr, as the catalog step already does). Python via resolve_py. The routing row and the skill the script header points to are the next PR in the stack. This stack and the model-scope stack both add a line to bin/lib/install-manifest.sh (the same MXTK_PROJECT_BIN list); whichever merges second keeps both lines.
Context cost none: no routed or always-loaded file touched. bin/render-routing.sh --check on base and head: both "Baseline: 75510 words (budget 80000)", every stage line identical.
Behaviour n/a: scripts only.
Runtime One Python pass over the module's flows at the module end, budget 300 s, info kind. Not timed on a large project here: the field run below read 1,588 flows in one pass, but its wall time was not recorded.

Field evidence

Re-measured 2026-10-21, read-only, by running this script over the app's model at the project commit before its note-line repairs (a git archive copy, so nothing in the project was touched). One Mendix 10.24 app, 1,588 flows read in one pass: 36 added or changed by an mxcli-built branch in one module, 1,548 drawn by hand in Studio Pro, 4 touched by the branch elsewhere (in neither group). On the 36: OVERLAP 19, LINE 27, NOTE-SIDE 17, LEFTWARD 3, TURN 4, SENSE 9, CAPTION 148. At the end of the branch, after its repair commits: OVERLAP 3, LINE 7, TURN 4, CAPTION 113, the rest 0. The earlier figures in the commit message (LINE 9, NOTE-SIDE 0) did not reproduce and are replaced. These are one app's counts; the judging skill in the next PR labels them that way.

The polarity word list for SENSE had \bun[a-z]+, which also matched "unit", "unique", "under", "until" and "union", so a caption containing one was read as already negated and SENSE stayed quiet. It is now an explicit set of un- words with a negative sense (unable, unassigned, unavailable, unchanged, unchecked, undefined, unfilled, unfinished, unknown, unmatched, unpaid, unread, unready, unresolved, unsaved, unselected, unsent, unset, unused, unvalidated, unverified). An unlisted un- word now errs towards printing a SENSE prompt, not towards hiding one. The fixture's word-list case gained "Unit found?", "Unique?", "Under limit?" and "Until done?" (must not read as negated) and "Unknown?", "Unsaved?", "Unset?" (must). Positive control: the new case fails (13 of 14) against the previous script. SENSE recount on the same archive: the 36 mxcli-written flows still 9 hits (all real, unchanged); the hand-drawn flows 15 hits became 18, the 3 new ones all being uniqueness captions ("Unique?") over an = empty test of an existing-record variable, all fine (empty means unique). Every other fact count in the app is unchanged.

Checklist

  • No client data anywhere in the diff (leak guard plain and with LEAKGUARD_BASE=origin/master, then a read of every added line).
  • Size cap: not met. 5 counted files, 517 lines; the reason is above.
  • Test tier: T1 + T2. Fixtures run: test-mf-canvas-facts.sh (new) and test-verify-module-446.sh (changed, V8 added). T2 is the field run above.
  • Golden input captured, not written: the five units and the .mpr dump that mxcli v0.27.0 exec capture-canvas.mdl produced on a copy of the toolkit's public mxpatch model (fixtures/canvas-facts/CAPTURE.txt). Each fact has a negative control in the same model. The three golden verify-446/*.summary.tsv were regenerated by the fixture's own CAPTURE= mode and gain one INFO row each.
  • Both layouts: the script takes the .mpr, its directory or mprcontents/; the fixture runs the first and the last. The rung passes whatever find_mpr returns, which is the existing path for single-tree and app/ checkouts. The fixture project is the single-tree shape only.
  • Both platforms: only macOS (Python 3.14, bash 3.2) ran here. The script is stdlib Python with no platform call; bin/check-portability.sh is clean. Not run under Git Bash.
  • CHANGELOG.md line under ## Unreleased, credited.
  • [n/a] New skill (next PR); new bug entries (the PR after).

Verification

Run in a worktree at the branch head, macOS, mxcli v0.27.0 was used only to capture the fixture.

bash tests/wave2/test-mf-canvas-facts.sh project-bin/mf-canvas-facts.py
  ok   exit 0: measured
  ok   [guard] fact lines equal the first run's capture (facts-v0.27.0.out)
  ok   NOTE-SIDE / OVERLAP / SENSE fire; their negative controls do not
  ok   [guard] 'inactive?', 'incomplete?', 'expired?', 'unknown?', 'unsaved?' read as negated questions; 'active?', 'found?', 'unit', 'unique', 'under', 'until' do not
  ok   [guard] a named flow that is not there is a FAULT (exit 2), never a clean run
  ok   [guard] a unit that does not decode is a FAULT, and every other flow is still measured
  PASS=14 FAIL=0
# positive control: same fixture against a project-bin without the script
  PASS=3 FAIL=18

bash tests/wave2/test-verify-module-446.sh project-bin/verify-module.sh
  ok   V6: the summary's last row is the run's verdict (verdict CLEAN)
  ok   V8: mf-canvas-facts installed: an INFO row, log 14-canvas-facts.log
  ok   V8: mf-canvas-facts not installed: a FAULT row that says how to install it
  SCORE: 8/8
# master's verify-module.sh: 6/6.  This branch's verify-module.sh with the OLD test: V6 fails (verdict INCOMPLETE),
# because the fixture project had no mf-canvas-facts.py and the rung faults. The test now stubs it.
# This branch's test against master's verify-module.sh: V8 x2 fail, 6/8.

bash tests/wave2/test-progress-harness-verify.sh project-bin/build-plan-status.sh   (reads the regenerated goldens)
  PASS=30 FAIL=0
bash tests/wave2/test-manifest-clean-checkout.sh
  ok   project-bin/ is fully named by the manifest

bin/render-routing.sh --check          -> in sync, Baseline: 75510 words (base: 75510)
bin/check-pr-discipline.sh             -> clean
bin/check-portability.sh               -> clean
bin/check-no-client-data.sh            -> no client data detected
LEAKGUARD_BASE=origin/master bin/check-no-client-data.sh -> new capitalised words: AssociationId CreateListAction
   EnumerationType OutputVariableName PrimaryCustomerRecord SecondaryCustomerRecord UseReturnVariable
   (BSON property names the script reads, and two synthetic parameter names in the fixture)
bin/check-scripts.sh                   -> 119/120 parse; the one failure is project-bin/script-owners.sh
   on master (line 290, "unexpected EOF"), not touched by this PR

…udio Pro canvas

A flow can build, pass its tests and still be unreadable in Studio Pro:
labels on top of each other, a note line leaving the side that faces away,
a decision whose true branch answers "no". mxbuild, check and lint see none
of it.

- project-bin/mf-canvas-facts.py prints the facts (OVERLAP, LINE, NOTE-SIDE,
  LEFTWARD, TURN, CAPTION, SENSE), read-only, exit 2 when a flow could not
  be read. Calibration is from Studio Pro 10.24, not verified on Studio Pro 11.
- verify-module.sh runs it per module as an info rung (1c, 14-canvas-facts.log).
- install manifest, fixture test on a model mxcli v0.27.0 wrote, V8 in
  test-verify-module-446.sh, CHANGELOG.
@MendixMau

Copy link
Copy Markdown
Owner

Thanks @saingge, this is a strong instrument. The review found one blocking issue: the "never a gate" rung could still turn a module's verdict INCOMPLETE when Python or the .mpr was missing, or when a flow failed to decode. The fix is in #551. That PR carries your commit unchanged, with your authorship, plus the fix on top. We couldn't push to your fork from our side. This PR will close when #551 merges; your CHANGELOG credit stays, and the merge commit will carry a Co-authored-by line for you.


Generated by Claude Code

MendixMau added a commit that referenced this pull request Oct 23, 2026
…udio Pro canvas (#551, from #534)

project-bin/mf-canvas-facts.py reads microflow and nanoflow units through mxpatch.py and prints one line per readability fact (OVERLAP, LINE, NOTE-SIDE, LEFTWARD, TURN, CAPTION, SENSE); facts, not verdicts, read-only. verify-module.sh runs it per module as an informational rung (1c, 14-canvas-facts.log). Golden input is a captured mxcli v0.27.0 model; field run read 1,588 flows on one Mendix 10.24 app. Calibration from Studio Pro 10.24, not verified on 11. Contributed by @saingge in #534.

Review fixes on top: the rung now never gates (kind=note; a missing script, Python or .mpr, an exit 2 or a timeout is an INFO "NOT MEASURED" row and leaves FAULTED alone, pinned by two new V8 cases); citations of the not-yet-existing skills/canvas-readability.md point at the script header; CHANGELOG and the install-manifest comment match. install-manifest keeps both mf-canvas-facts.py and model-scope.py.

Review: MERGE-AFTER-FIX — the one blocking finding (an "info" rung that could flip a module verdict to INCOMPLETE) fixed and independently re-reviewed. Security review: safe.

Co-authored-by: saingge <262679532+saingge@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jQvaonym9V1wKKfAEPmRr
@MendixMau MendixMau closed this Oct 23, 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