Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
05fefc8
fix(page-shell): read `create page if not exists` declarations; repor…
claude Oct 26, 2026
cff3154
fix(doctor): gate self-test leaves Studio Pro's .mpr.lock out of the …
claude Oct 26, 2026
a5173d7
fix(preflight, exec): mxcli v0.27+ exec is all or nothing; stop calli…
claude Oct 26, 2026
7cdbd9c
fix(platform-link): Deploy API v1 creates the first Free App environment
claude Oct 26, 2026
d87e629
fix(monkey): cut a typed payload to the input's maxLength (#544)
claude Oct 26, 2026
271759c
learn(brd-to-build-plan): widget-only packages never appear in SHOW M…
claude Oct 26, 2026
5fa2277
fix(monkey): a long spinner is a slow finding, not crash-class (#562)
claude Oct 26, 2026
90bcbb9
fix(monkey): a target navTo cannot find is not reached, never fuzzed …
claude Oct 26, 2026
36a1839
learn(mendix-agent-ui): stock ConversationalUI popup traps
claude Oct 26, 2026
7780bf3
learn(microflow-patterns): separate-transaction commit leaves the req…
claude Oct 26, 2026
566b847
fix(doctor): say why mxbuild stopped; warn on a JDK that does not mat…
claude Oct 26, 2026
2c36b12
learn(page-patterns, file-upload-widget): last unpromoted 2026-10-12 …
claude Oct 26, 2026
db8c06e
fix(lint): CONV010 allows NanoflowCallAction in ACT_ nanoflows
claude Oct 26, 2026
d002efe
fix(design-audit): a11y findings name the failing element (#561)
claude Oct 26, 2026
7d9742c
fix(gate-check): warn on multi-line placeholders left in agent stubs
claude Oct 26, 2026
0229c5f
fix(journeys): outcome.label reaches the outcome check name (#538)
claude Oct 26, 2026
2dbbed8
fix(verify-module): page-scope budget override; kill the timed-out tree
claude Oct 26, 2026
700e227
fix(journeys): a mutant that never ran reads INVALID, not "went green…
claude Oct 26, 2026
d71d7b0
fix(verify-module): walk journeys/<Module>/*.journey.json when no sin…
claude Oct 26, 2026
a90b552
fix(e2e): actions wait for visibility instead of isVisible({timeout})…
claude Oct 26, 2026
9926b91
fix(status): WATCH when the lint baseline, acceptances or local rules…
claude Oct 26, 2026
7f5cf8d
fix(coverage-preflight): scope a per-module ledger file to the BRDs i…
claude Oct 26, 2026
cd2e85e
new(journeys): browser Back action and opt-in ui.no5xx row (#564)
claude Oct 26, 2026
c0616d0
fix(doctor): look-hook check catches one-line settings and says when …
claude Oct 26, 2026
dafdd2b
fix(conformance): accept BRD-prefixed pointers and not built/blocked …
claude Oct 26, 2026
081d65a
fix(exec): prune mxbuild logs by time-stamped name, not mtime
claude Oct 26, 2026
e604a46
fix(facts-lock): read name-keyed identifiers, WARN-only
claude Oct 26, 2026
c1dba09
fix(validate-journeys): back.timeout must be a positive number (#522)
claude Oct 26, 2026
b93a968
test(monkey): write the CJK payload in the oracle fixture as \u escapes
claude Oct 26, 2026
2059e68
fix(restatement-guard, hooks): mark the last-writer ledger on a model…
claude Oct 26, 2026
fe2b143
Merge branch 'fix/docs' into claude/loving-gates-hauc1n
claude Oct 26, 2026
984f274
Merge branch 'fix/doctor' into claude/loving-gates-hauc1n
claude Oct 26, 2026
10f9d04
Merge branch 'fix/gates' into claude/loving-gates-hauc1n
claude Oct 26, 2026
fbe92f8
Merge branch 'fix/runners' into claude/loving-gates-hauc1n
claude Oct 26, 2026
5041738
new(fixture-seeding, e2e): state-fixture template — set and revert on…
claude Oct 26, 2026
30abfed
new(harness-scan): flag test scripts that sign in without the toolkit…
claude Oct 26, 2026
a376f9b
fix(validate-journeys): accept offline/online, check device/viewport/…
claude Oct 26, 2026
22be37f
new(journeys): phone device per run, offline/online steps, GPS fix pe…
claude Oct 26, 2026
273c93f
learn(iterative-build-loop): measure mx check vs the deploy gate (#44…
claude Oct 26, 2026
c5c51cc
fix(lint-gate): a project-edited bundled rule lost to mxcli's session…
claude Oct 26, 2026
08af415
new(journeys): --rerun-failed and --only for fix-loop reruns (#492)
claude Oct 26, 2026
2cb753b
new(journeys): ui.pseudoText asserts CSS-authored ::before/::after te…
claude Oct 26, 2026
ff227eb
new(journeys): row-scoped click — `row` and `in` on click (#148, one …
claude Oct 26, 2026
4eaab08
fix(e2e): the remaining isVisible({timeout}) sites that mean "wait" u…
claude Oct 26, 2026
7f9c146
fix(design-audit): read the a11y widget name from the full tag, not t…
claude Oct 26, 2026
b5a409f
test(journeys): drive back and no5xx in a real Chromium (#564)
claude Oct 26, 2026
379289a
fix(doctor, exec): name the env file JAVA_HOME came from; failed-exec…
claude Oct 26, 2026
4b94318
Merge branch 'fix/runner-features' into claude/loving-gates-hauc1n
claude Oct 26, 2026
69899df
Merge branch 'fix/lint-receipt' into claude/loving-gates-hauc1n
claude Oct 26, 2026
da132fa
Merge branch 'fix/acceptance' into claude/loving-gates-hauc1n
claude Oct 26, 2026
87e3d5c
learn(detection-gaps): separate-transaction commit + browser Back reg…
claude Oct 26, 2026
a7f59c7
learn(testing-shape): returned-defect-string false-green register row…
claude Oct 26, 2026
f7c59d4
fix(verify-module, tests): portability markers on the guarded pgrep; …
claude Oct 26, 2026
c5a6a82
Merge branch 'fix/restatement' into claude/loving-gates-hauc1n
claude Oct 26, 2026
9546745
Merge branch 'fix/fixtures' into claude/loving-gates-hauc1n
claude Oct 26, 2026
0a66f9b
Merge branch 'ab/baseline-adds' into claude/loving-gates-hauc1n
claude Oct 26, 2026
8f40c98
chore(mdl-rules): re-render skills/generated after merging the sweep …
claude Oct 26, 2026
d583780
Merge remote-tracking branch 'origin/master' into claude/loving-gates…
claude Oct 26, 2026
75c38f1
fix(journeys): --rerun-failed reads only never-walked row shapes as j…
claude Oct 26, 2026
94ae58d
fix(journeys): a row-scoped click matches whole words and refuses an …
claude Oct 26, 2026
038011a
fix(validate-journeys): the typo rule allows one edit for short keys;…
claude Oct 26, 2026
ef204de
fix(lint-gate): #524 project rows ignore CRs, cover seeded rules only…
claude Oct 26, 2026
d377ec3
fix(state-fixture): refuse PGHOSTADDR/remote server and a NULL curren…
claude Oct 26, 2026
99900f7
fix(hooks): core.hooksPath advice covers post-merge and post-checkout…
claude Oct 26, 2026
38c8b15
fix(doctor): name the env file JAVA_HOME came from only when it did
claude Oct 26, 2026
abfcd79
test(behaviour): commit the baseline-adds A/B tasks and scorer so the…
claude Oct 26, 2026
5dc2f8a
Merge branch 'fix/p2-runners' into claude/loving-gates-hauc1n
claude Oct 26, 2026
1c2c783
Merge branch 'fix/p2-lint' into claude/loving-gates-hauc1n
claude Oct 26, 2026
821d814
test: leak-guard-clean fixture values (git email, test password default)
claude Oct 26, 2026
1ebfedf
Merge remote-tracking branch 'origin/master' into claude/loving-gates…
claude Oct 26, 2026
b288594
fix(page-shell): here-string instead of printf | grep -q under pipefail
claude Oct 26, 2026
1332b90
fix(row-groups, exec): remind when Row groups is on but a script name…
claude Oct 28, 2026
a49640f
Merge the already-squashed #578 branch history (content is in master …
claude Oct 28, 2026
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(row-groups, exec): **with `Row groups: on`, a script that names no build-plan row now gets a visible reminder instead of a silent "not checked"**: `row-groups.sh check` exits 4 and exec.sh prints "start the script with `-- rows: N`" and notes it in the BUILD-LOG row; it never refuses. In the #581 A/B (purchase-requests app, Sonnet) all 31 scripts were numbered on their own sequence with no header, so row grouping never ran once while the project had it switched on. Fixture: `test-row-groups.sh` G4 (2 of 3 cases fail on the previous row-groups.sh) — A/B 2026-10-27 of #581
- new(exec, row-groups): **row-group gate**: `bin/row-groups.sh` plans scripts from the build plan (consecutive low-risk BUILD rows of one module, at most 4, in one script; security, workflow, agents, REST, Java, Marketplace and changes to built documents stay one row per script), and `exec.sh` refuses a split low-risk group, a mixed high-risk script, or the first script past a module with no `docs/progress/module-close/<Module>.md`. The gate checks a script that names its rows in a `-- rows:` header, or, when PROJECT.md says `Row groups: on`, its file name; otherwise it is skipped, because `brd-to-build-plan.md` numbers scripts on their own sequence (on the real SampleDashboards plan `16-cutover.mdl` is row 26 and was refused as row 16; `tests/wave2/test-row-groups.sh`). A row counts as built only when its State says built / done / complete / verified / proven / passed / applied (`planned`, `partial`, `**blocked**` and an empty State do not), or when an applied script's `-- rows:` header names it. Override: `MXTK_ROWS_OVERRIDE="<why>"` (ProcureFlow run 3 arm D: 0.93 → 0.48 scripts per row, 0 overrides; build to Test 2 12/12 in 322 min vs arm C stopped at row 121 after 650) — cook-off ProcureFlow run 2/3
- fix(exec, lint): **lint prints and counts only the findings THIS script added, plus any earlier one still unfixed**, diffed against the previous exec (`.claude/loop/lint-prev-exec.json`); a finding that was reported and is neither fixed nor accepted into the baseline is carried (`.claude/loop/lint-unacked.json`) and stays "lint rose" on every later exec, and a diff that cannot run or cannot read `lint-last.json` (missing, unparseable, no `new_findings`), or itemises nothing with no previous exec to explain the rise, keeps the rise as lint-gate returned it (and does not advance `lint-prev-exec.json`, so the next exec still reads it as a rise), never "0 new" (`tests/wave2/test-exec-lint-diff.sh`); the baseline cannot be refreshed unattended, so "rose vs baseline" stayed true for every later exec (run 2 arm C: ROSE on 123 of 147 rows, ~60 lines each, 6 real SEC010 unread) — cook-off ProcureFlow run 2
- new(reload): **`bin/reload.sh` hot-reloads instead of restarting** and finds the app URL from `APP_URL`, then `.docker/.env` `APP_PORT`, then CLAUDE.md (run 2 arm C: 176 app starts; run 3 arm D: 33, 1 failed); it and `bin/module-close.sh` find the `.mpr` and mxcli through `_common.sh`, so a two-tree checkout (`.mpr` under `app/`) works, and `reload.sh` reads the `.docker/` folder beside the `.mpr`, where mxcli writes it (`test-module-close.sh` C2, R1); `bin/module-close.sh` runs the module-close checks and lists pages still owed a LOOK; its report carries `<!-- mxtk-module-close: lint=N vm=RC -->`, and the row-group gate counts a module as closed only at `lint=0` or with a filled row in the report's Page | Role LOOK table, so a report with findings and no page looked at does not open the next module (`tests/wave2/test-row-groups.sh` M1, `test-module-close.sh` with a captured mxcli v0.28.0 lint) — cook-off ProcureFlow run 2/3
Expand Down
4 changes: 4 additions & 0 deletions project-bin/exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,10 @@ if [ "$PATCH_MODE" != "1" ] && [ -x "$PROJECT_ROOT/bin/row-groups.sh" ]; then
fi
echo "⚠ Row-group gate OVERRIDDEN: ${MXTK_ROWS_OVERRIDE}" >&2
ROWS_NOTE="rows override: $(printf '%s' "$MXTK_ROWS_OVERRIDE" | tr '|' '/')"
elif [ "$_rg_rc" = 4 ]; then
# Opted in, but the script names no plan row: a reminder, never a refusal.
echo "⚠ $_rg_out"
ROWS_NOTE="rows: no -- rows: header (not grouped)"
fi
fi

Expand Down
14 changes: 12 additions & 2 deletions project-bin/row-groups.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
# The remedy is never blocked: run bin/module-close.sh <Module>, fix and re-run, or fill the table.
# Override, with a reason that lands in the BUILD-LOG row: MXTK_ROWS_OVERRIDE="<why>".
# exit 0 pass, 1 refused, 3 nothing to check (no plan, no rows header and no opt-in, or no BUILD row).
# exit 4: `Row groups: on` but the script names no BUILD row; exec.sh prints the hint, never refuses.
#
# WHY (run 2, 2026-10-26, arm C). 147 build-plan rows ran as ~137 scripts and ~185 execs; each exec
# paid check, snapshot, baseline mxbuild, apply, mxbuild gate (~2 min of instruments). A prompt rule
Expand Down Expand Up @@ -155,13 +156,22 @@ except OSError:
if mine is None and not optin:
print("row-groups: script has no `-- rows:` header and PROJECT.md does not say `Row groups: on` — not checked")
sys.exit(3)
# Opted in, but the script names no BUILD row of the plan: exit 4, a reminder exec.sh prints and
# lets through. WHY (A/B 2026-10-27, purchase-requests app): with `Row groups: on` every script was
# numbered on its own sequence (052-…, 076-…) and none carried a header, so all 31 read "not
# checked" and the run never grouped a row; exit 3 said nothing anyone saw.
OPTIN_HINT = ("row-groups: `Row groups: on`, but this script names no build-plan BUILD row, so it was not "
"checked or grouped. Start the script with `-- rows: N` (or `-- rows: N,M,…` for a group); "
"bin/row-groups.sh lists the groups.")
if mine is None:
m = re.match(r"(\d+)(?:-(\d+)(?=-))?-", os.path.basename(script))
if not m: print("row-groups: script names no row — not checked"); sys.exit(3)
if not m: print(OPTIN_HINT); sys.exit(4)
a, b = int(m.group(1)), int(m.group(2) or m.group(1))
mine = set(range(a, b + 1)) if b >= a else {a}
mine &= {n for n, k, *_ in rows if k == "BUILD"}
if not mine: print("row-groups: script names no BUILD row — not checked"); sys.exit(3)
if not mine:
if optin: print(OPTIN_HINT); sys.exit(4)
print("row-groups: script names no BUILD row — not checked"); sys.exit(3)

problems = []
for risk, ns in groups:
Expand Down
10 changes: 10 additions & 0 deletions tests/wave2/test-row-groups.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# G1 real plan, no opt-in: no script name in it is refused (16-cutover.mdl was, as row 16)
# G2 `-- rows:` header: the split-group refusal still works on the real plan
# G3 `Row groups: on`: a file-name number is read as the row again
# G4 `Row groups: on` but the script names no BUILD row: exit 4, the `-- rows:` hint exec.sh prints
# S1 built = an explicit built/done/applied State; planned, **blocked**, partial, empty are not
# M1 module close: the report must record 0 lint findings for the module, or a filled LOOK row
set -uo pipefail
Expand Down Expand Up @@ -60,6 +61,15 @@ chk "$P3" "14-snippets.mdl" "create snippet ..."
printf '# Project\n\n- Row groups: off\n' > "$P3/PROJECT.md"
chk "$P3" "14-snippets.mdl" "create snippet ..."
[ "$rc" = 3 ] && ok "G3: Row groups: off → not checked" || bad "G3 off: rc=$rc" "$out"
printf '# Project\n\n- Row groups: on — CONFIRMED\n' > "$P3/PROJECT.md"
chk "$P3" "999-cleanup.mdl" "create microflow ..."
{ [ "$rc" = 4 ] && printf '%s' "$out" | grep -q -- '-- rows: N'; } \
&& ok "G4: Row groups: on, a script numbered past the plan → exit 4 with the -- rows: hint" || bad "G4 numbered: rc=$rc" "$out"
chk "$P3" "cleanup.mdl" "create microflow ..."
[ "$rc" = 4 ] && ok "G4: Row groups: on, an unnumbered script → exit 4 hint" || bad "G4 unnumbered: rc=$rc" "$out"
printf '# Project\n\n- Row groups: off\n' > "$P3/PROJECT.md"
chk "$P3" "999-cleanup.mdl" "create microflow ..."
[ "$rc" = 3 ] && ok "G4: Row groups: off, same script → still exit 3, no hint" || bad "G4 off: rc=$rc" "$out"

echo "== S1 what counts as built"
plan_states() { # $1 $2 $3 = states of rows 1..3 (one low group)
Expand Down
Loading