Skip to content
Closed
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(progress-report, build-plan-status): **HARNESS rows are no longer counted as built rows, and a module's `verify-module.sh` row shows once, as that module's sign-off status on its phase card, instead of as a row.** A HARNESS step is a module's sign-off, not a build, so it is out of every "x of y built" count: the phase cards, the plan rollup and the Stage 5 card in `progress-report.html`, and the lede of `build-plan-status.sh --html` ("N build rows", plus a "Not counted: N HARNESS rows" note). The verify row's evidence is read exactly as #501 reads it (`harness_verify`'s rule, now `verify_evidence` + `module_status` in `progress-report.py`; nothing new measured, no extra script run, no mxcli or mxbuild call) and shown as one line per module: `Verified ✓ <date> (LOOK n/n)`, `Verify owed - LOOK + CONFIRM`, `Verify stale (N builds since)` (or `(a script was marked done- after it)`), `Verify not run`, `built? no verify summary`, `Verify not clean <date> (<why>)` for a summary with a FAULT, FINDING or SKIPPED row, or `Verify clean <date>, LOOK n/n - held: State says <State>` when State is blocked or pending a person (held is not signed off, as #501 never promoted it); a State cell that disagrees is flagged under it, the rollup says how many modules are verified, and the Stage 5 card, KPI and owed text add ", k of n modules signed off". The Phase state badge is read from the build rows only (a phase of HARNESS rows alone says "sign-off only" and its card "Sign-off phase: no build rows"). A module with no verify row shows no status. Other HARNESS rows (a coherence pass, a harness run) stay in the row list, marked "(not counted)". `build-plan.md`, `build-plan.json` and the text output are unchanged, so agents still see every HARNESS step. **Behaviour change to check in your project:** the progress report's built counts drop the HARNESS rows (a plan of 10 rows with 2 HARNESS reads "x of 8"), and the verify rows leave the row tables. Fixture: `test-progress-harness-verify.sh` (H1-H10, N1-N6, both layouts). — MendixMau (decision 2026-10-21)
- fix(exec): **a script restated from a stale DESCRIBE now WARNs instead of silently reverting an earlier exec** (#261). A script drafted from a DESCRIBE taken before an earlier script of the batch ran put four old messages back, with check, mxbuild and lint green. New `project-bin/describe-baseline.sh stamp` writes `-- baseline: <Doc> sha256=<hash>` (plus `-- baseline-mxcli: <version>`) from a DESCRIBE at draft time; `exec.sh` runs `verify` only for a script that carries the header, so other scripts cost one grep and no mxcli call. It reports DRIFT with the first lines of the diff, STALEHEADER, and RESTAMP after an mxcli upgrade (DESCRIBE text may change, so that is not called drift). A re-run by the script's own last recorded write (the #269 ledger) and a fresh model are not drift. Nothing is refused and the exit codes do not change. Preflight STOP 21 gains one clause (`-- supersedes:`, `stamp`, exec.sh only warns) and its trigger names `create or modify` (+24 words). Not-found DESCRIBE and `--version` output are captured from mxcli v0.26.0. Lands after the #269 PR; with it, supersedes draft #311. **Behaviour change to check in your project:** `exec.sh` output can carry `WARN: stale draft: …` lines, and the BUILD-LOG detail cell `WARN stale baseline: <docs>`; `MXTK_RESTATE_GUARD=off` skips the check. — AlvinnYeo (#261)
- fix(exec): **re-running an older `mdlsource/` script over a newer owner's live work now WARNs instead of passing silently** (#269). Three field apps had 99/579, 130/357 and 38/159 documents created by more than one script, and a replay of an older one reverted the newer with exit 0 and every gate green. New `project-bin/script-owners.sh` maps each microflow, nanoflow, page and snippet to the scripts that create or restate it, in run order (digit runs compared as numbers, so `2-core/` runs before `11-fixes/`; `done-` ignored), and reads `-- supersedes:` / `-- superseded-by:` headers. `exec.sh` records every kept write in a machine-local last-writer ledger (`.claude/loop/script-owners/`, self-gitignored, compacted per write); `restore-mpr.sh` marks it on a manual restore. A replay WARNs only when the newer owner's write is live: ledger first, else one DESCRIBE per document, at most 5 per exec (the rest print `CONFLICT (not checked)`). A new owner without a supersedes header gets one `NOTE:` line on its first run, kept out of BUILD-LOG. Nothing is refused and the exit codes do not change. With no co-owner, `exec.sh` runs one grep over `mdlsource/` and no mxcli call. `gate-check.sh` prints the co-owned count when it is above 0. Part of the rebuilt draft #311 (with the #261 PR). **Behaviour change to check in your project:** `exec.sh` output can carry `WARN: restatement: …` and `NOTE: new owner of …` lines; the BUILD-LOG detail cell can carry `WARN reverts: <docs>`. Set `MXTK_RESTATE_GUARD=off` to skip the check. — MendixMau (#269)
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