Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m

## Unreleased

- fix(graph-sweep, lint): **the orphan list now says a flow used only by a pluggable widget's datasource or action property may have no catalog edge, and prints the one `mxcli search` that finds the page (it needs a `REFRESH CATALOG FULL SOURCE` catalog; this sweep reads a FULL one, so the note says to rebuild).** The caveat named only layout snippet calls, so a live flow read as "strong evidence of deadness" (`graph-sweep.sh` comment, `review-report.js` orphan detail, and the `lint-that-actually-runs.md` QUAL004 row, which only said the catalog "likely misses" the ref). Observed on a Mendix 10.24 app with mxcli v0.27.0: 5 live flows used only as a Gallery's or a third-party widget's microflow datasource had 0 `refs` rows, `show references to` said "no references found", `describe page` printed each, and QUAL004 flagged each. A Gallery with a microflow datasource and no microflow `onClick` had its ref (15 of 15); with both, only the `onClick` ref (2 of 2); the two Data grid 2 microflow datasources had theirs. The QUAL004 row now states that and links [mendixlabs/mxcli#1513](https://github.com/mendixlabs/mxcli/issues/1513) (open; reported for Data grid 2 on v0.26.0); the ledger entry and the pending-issue draft now say they are filed. Pinned by `test-catalog-edge-guard.sh` case 1 (fails on 393d253). — saingge
- fix(bug-lookup): **`bin/bug-lookup.sh` also searches the project's own `bug-logs/**.md` drafts, marked `(project draft: <file>:<line>)`, after the ledger's output.** It searched only the toolkit ledger, so a bug a session had already written down in the project was invisible to the lookup run before the next experiment on the same error; the ledger's output and ranking are unchanged (drafts are ranked in a separate pass), `--full` and `--index` stay ledger-only, and `MXTK_PROJECT_DIR=` turns drafts off. Field: a Mendix 10.24 app with mxcli v0.27.0, 43 files in `bug-logs/`; the query "cannot be spliced" listed 0 project drafts at 393d253 and lists 3 (3 distinct files) now, each pointing at a `## ` line; the project was not written. Pinned by group P of `tests/wave2/test-bug-lookup.sh` (3 of its checks fail on 393d253) on synthetic drafts; the run under /bin/bash 3.2.57 passes, other awks not run. — saingge
- fix(harvest-learnings): **section 1 drafted only the first `## ` section of each bug-log file.** The awk splitter's `print buf "\x01"` put a newline after each delimiter, so every later section began with an empty line, read an empty heading and was skipped. It is `printf "%s\x01", buf` now. Field run on a Mendix 10.24 app with mxcli v0.27.0 (43 bug-log files, 54 `## ` sections): `harvest-learnings.sh` at 393d253 drafted 43, the fix drafts 54. Pinned by `tests/wave2/test-harvest-learnings.sh` T5, on a two-file fixture that keeps a captured log's structure with its text replaced (fixed: 7 of 7 sections, 20 of 20 checks; 393d253: 2 of 7, T5 fails). The splitter's delimiter bytes were checked under macOS awk 20200816 only. — saingge
- fix(script-owners): **the restatement guard now parses under macOS's default bash 3.2, so `exec.sh` no longer skips it silently** (guard added in #498). `exec.sh` runs `bash script-owners.sh check … 2>/dev/null || true`; under /bin/bash 3.2.57 the file failed to parse (an apostrophe in a comment inside `$(...)`, then `case` patterns without a leading `(`), so the call (and the ledger `record` call) printed nothing and warned nothing. Fixture `test-restatement-guard.sh` under /bin/bash 3.2.57: 16 of 58 pass before, 58 of 58 after; `bin/check-scripts.sh` now also parses every script with /bin/bash when the bash on PATH is a different one. — saingge
Expand Down
2 changes: 1 addition & 1 deletion bug-logs/mxcli-bugs.md
Original file line number Diff line number Diff line change
Expand Up @@ -7027,7 +7027,7 @@ end;

## BUG-DRAFT-qual004-dg2-datasource: QUAL004 reports a `DS_` microflow as "not called from anywhere" when its only caller is a Data grid 2 datasource, and the lint ratchet fails a correct script (2026-10-14)

> **NOT YET FILED.** Upstream draft: `bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md`.
> **Filed:** [mendixlabs/mxcli#1513](https://github.com/mendixlabs/mxcli/issues/1513) (2026-10-16, open). Upstream draft: `bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md`.

**Discovered:** 2026-10-14, on an existing-app change project (a connector app). A build row created a page whose Data grid 2 is driven by a new `DS_<Entity>_<Verb>` microflow, in one script; the navigation entry came in a later script.
**Reproducible:** seen twice on one model, not yet reduced to a blank app. **mxcli version:** v0.26.0. **Mendix:** 11.15.0. macOS.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Repo: mendixlabs/mxcli
Source: toolkit issue #360; `bug-logs/mxcli-bugs.md` BUG-DRAFT-qual004-dg2-datasource
Status: **NOT FILED.** Reduce to a blank app first: one page, one Data grid 2 on a `DS_` microflow, `mxcli lint`, then the same with a classic list view.
Status: **FILED — https://github.com/mendixlabs/mxcli/issues/1513 (2026-10-16)**. Not reduced to a blank app, and not retested on v0.27.0 when filed.

--- everything above this line is stripped before filing ---

Expand Down
12 changes: 10 additions & 2 deletions project-bin/graph-sweep.sh
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,12 @@ ORDER BY COALESCE(i.n,0) ASC, e.n DESC;

# --- finding 2: orphaned microflows -----------------------------------------------------------
# No inbound call / page action / nav item. Entry-point prefixes are excluded: they are
# legitimately unreferenced. Note SHOW REFERENCES TO misses layout snippetcalls, so this is
# strong evidence of deadness, not proof.
# legitimately unreferenced. The catalog also records no edge for some pluggable-widget
# properties (observed on mxcli v0.27.0: a Gallery's microflow `DataSource` when the Gallery also
# has a microflow `onClick`, and a third-party widget's datasource and action properties), and
# SHOW REFERENCES TO misses layout snippetcalls. So this is evidence of deadness, not proof:
# check the page source before deleting a flow (the report prints the command; see also
# skills/lint-that-actually-runs.md).
ORPHANS="$(q "
SELECT m.QualifiedName, m.ActivityCount
FROM microflows_data m
Expand Down Expand Up @@ -228,6 +232,10 @@ echo " orphaned microflows (no call / action / nav inbound, entry-point prefixe
if [ "$N_ORPH" -gt 0 ]; then
printf '%s\n' "$ORPHANS" | awk -F'|' 'NF {printf " %-56s %s activities\n", $1, $2}' | head -40
[ "$N_ORPH" -gt 40 ] && echo " ... and $((N_ORPH-40)) more"
echo " NOTE: a flow used only as a pluggable widget's datasource or action property may have no edge, so it can"
echo " be listed here. Before deleting one, find the page that holds it: rebuild with 'REFRESH CATALOG FULL SOURCE'"
echo " (a plain FULL catalog has no page source), then look for a PAGE row under 'Source Matches':"
echo " ./mxcli -p \"$MPR\" search \"<Module.Flow>\""
fi

echo
Expand Down
6 changes: 4 additions & 2 deletions project-tests/e2e/review-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,10 @@ if (graphParsed) {
verdict: 'manual', provenance: 'judged',
detail: (f[2] || '?') + ' activities, and no inbound call / action / menu_item / ' +
'show_page / datasource edge. Entry-point prefixes are already excluded. ' +
'SHOW REFERENCES TO misses layout snippetcalls, so this is strong evidence of ' +
'deadness, not proof.',
'The catalog records no edge for some pluggable-widget properties (a datasource or ' +
'action set there) and SHOW REFERENCES TO misses layout snippetcalls, so this is ' +
'evidence of deadness, not proof: find the page that holds the flow (a source-catalog search) ' +
'before deleting it.',
measuredAt: STARTED,
nonVacuity: { controlRan: false, note: 'graph sweep has no positive control' },
evidence: [{ type: 'query', sql: 'microflows_data LEFT JOIN refs (catalog.db)',
Expand Down
2 changes: 1 addition & 1 deletion skills/lint-that-actually-runs.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ onto the wrong document. Each answer is the user's decision, recorded in `PROJEC

| Finding | Why it is not a defect | What to do today |
|---|---|---|
| **QUAL004** on a `DS_` flow whose only caller is a Data grid 2 datasource (#360) | The stock rule already counts `datasource` refs (v0.24.0+), yet v0.26.0 flagged two working Data grid 2 datasources. The catalog likely misses the pluggable widget's ref. | Confirm with `describe page`, then accept the rise: `--update-baseline --reason "QUAL004 DS_ datasource false positive"`. Never rename or add a caller. Upstream: `pending-github-issues/qual004-dg2-datasource-ref.md` |
| **QUAL004** on a `DS_` flow whose only reference is a pluggable widget's datasource (#360) | The stock rule counts `datasource` refs (v0.24.0+), but the catalog drops some pluggable-widget refs: v0.26.0 flagged two working Data grid 2 datasources. On v0.27.0 (Mendix 10.24, one app) a Gallery with a microflow `DataSource` and a microflow `onClick` keeps only the `onClick` ref (2 of 2); one without `onClick` keeps its ref (15 of 15); a third-party widget's datasources have none (3 of 3). `show references to` then says "no references found", while `describe page` shows the flow. | Find the page with `mxcli search "<Module.Flow>"` on a `REFRESH CATALOG FULL SOURCE` catalog (a PAGE row under "Source Matches"). Then accept the rise: `--update-baseline --reason "QUAL004 DS_ datasource false positive"`. Never rename or add a caller. Upstream: [mendixlabs/mxcli#1513](https://github.com/mendixlabs/mxcli/issues/1513) (open; Data grid 2, v0.26.0); draft `bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md` |
| **QUAL004** on a `TEST_` helper (#241) | It is called from `tests/*.test.mdl`, which lint cannot see. `ENTRY_POINT_PREFIXES` is a constant, not an option. | Baseline with a reason. Keep QUAL004 on: it is the orphan check `process-coherence-pass.md` runs. Upstream: `pending-github-issues/lint-naming-prefixes-as-options.md` |
| **CUSTOM002** on `TEST_`, `GET_`, `PRS_`, `STUB_` (#241) | `example_microflow.star` is an *example* rule from `mxcli init` ("customize the prefixes"). Its `VALID_PREFIXES` is a constant. | `rules: CUSTOM002: enabled: false`, recorded in `PROJECT.md`, or baseline with a reason. Never edit the `.star` file. Upstream: `pending-github-issues/lint-naming-prefixes-as-options.md` |
| **QUAL002** on import mappings, published REST services and Marketplace Java actions (#246) | MDL cannot store documentation on the first two (MDL089); a doc comment above them moves to the next microflow. | The rule has per-kind options (mxcli >= 0.24.0): `rules: QUAL002: options: check_import_mappings: false`, `check_published_rest_services: false`, `check_java_actions: false`, `check_java_action_params: false`. Or document them in Studio Pro. Upstream: `pending-github-issues/qual002-skip-mdl089-types.md` |
Expand Down
10 changes: 10 additions & 0 deletions tests/wave2/test-catalog-edge-guard.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
# 4. build_mode 'fast' + empty refs -> FAULT, as before
# 4b. refs typed, but none of the orphan-read kinds -> sweeps, with the orphan-list WARNING
# 5. app-facts: 'source' + calls and action-only both pass the guard; kind-less FAULTs
# (case 1 also asserts the orphan list's note on pluggable-widget datasource/action properties)
#
# The catalog databases are SYNTHETIC: no real catalog.db is captured in this repo, and the
# report quotes only the FAULT line and the counts. Tables and columns are exactly the ones the
Expand Down Expand Up @@ -120,6 +121,15 @@ for layout in single two; do
else
bad "[$layout] orphan finding wrong on a 'source' catalog" "$(out)"
fi
# The orphan list must say that a flow used only by a pluggable widget's datasource/action
# property has no edge, and print the one search that finds the page holding it (it needs
# a SOURCE catalog, which this sweep's FULL catalog is not).
if grep -q "NOTE: a flow used only as a pluggable widget's datasource or action property may have no edge" "$WORK/out" \
&& grep -q "REFRESH CATALOG FULL SOURCE" "$WORK/out" && grep -q 'search ".*<Module.Flow>"' "$WORK/out"; then
ok "[$layout] orphan list carries the pluggable-widget note and the source-search command"
else
bad "[$layout] orphan list lacks the pluggable-widget note" "$(out)"
fi

# --- 2. no microflow-to-microflow calls at all: still sweeps (the review-caught regression) ----
P="$(proj $layout)"; mkdb "$(mdir "$P")/.mxcli/catalog.db" full actions
Expand Down
Loading