diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f8e7cb7..0409331c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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: :)`, 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 diff --git a/bug-logs/mxcli-bugs.md b/bug-logs/mxcli-bugs.md index 141be2bd..5edc85bc 100644 --- a/bug-logs/mxcli-bugs.md +++ b/bug-logs/mxcli-bugs.md @@ -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__` 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. diff --git a/bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md b/bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md index 0b5d9b22..9a182617 100644 --- a/bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md +++ b/bug-logs/pending-github-issues/qual004-dg2-datasource-ref.md @@ -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 --- diff --git a/project-bin/graph-sweep.sh b/project-bin/graph-sweep.sh index 35e4647e..5ecd124e 100755 --- a/project-bin/graph-sweep.sh +++ b/project-bin/graph-sweep.sh @@ -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 @@ -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 \"\"" fi echo diff --git a/project-tests/e2e/review-report.js b/project-tests/e2e/review-report.js index 7cf79982..9e295d8f 100644 --- a/project-tests/e2e/review-report.js +++ b/project-tests/e2e/review-report.js @@ -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)', diff --git a/skills/lint-that-actually-runs.md b/skills/lint-that-actually-runs.md index dd3329c0..de86a8db 100644 --- a/skills/lint-that-actually-runs.md +++ b/skills/lint-that-actually-runs.md @@ -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 ""` 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` | diff --git a/tests/wave2/test-catalog-edge-guard.sh b/tests/wave2/test-catalog-edge-guard.sh index 2206710a..95d3d554 100755 --- a/tests/wave2/test-catalog-edge-guard.sh +++ b/tests/wave2/test-catalog-edge-guard.sh @@ -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 @@ -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 ".*"' "$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