From cd187a4a83938e850ec5856d6adcbe97845715bb Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 13:13:25 +0000 Subject: [PATCH 1/6] feat(doctor, sync-project): wire mxcli fix property-sets into the upgrade path, report first; name a pre-fix model-stamp.sh #295. mxcli up to v0.25 wrote units without Studio Pro's full property set. mx check, the build and the runtime stay green, and Studio Pro's merge/diff throws once it has saved such a document. No gate saw it. - bin/doctor.sh --property-sets : read-only `mxcli fix property-sets --dry-run`, result plus mxcli version in .claude/.property-sets-receipt (gitignored). Exit 0 clean / 1 needs or unclassified / 2 not run / 3 mxcli < v0.26.0. --if-stale skips when already run for this mxcli. - bin/doctor.sh --fix-property-sets : the repair, only through bin/exec.sh --patch (snapshot, mxbuild gate, restore); refused on an exec.sh without --patch. doctor.sh is its own patch script. - doctor --quick (run by exec.sh when the mxcli version changes) warns while the check is owed; a full doctor runs it. - sync-project.sh runs the check with --if-stale (never the repair). - Support is read from `mxcli fix --help`: `fix property-sets --help` exits 0 on v0.24/v0.25 too (cobra prints the parent's help). - learned-detection-gaps.md row; platform-link.md "Before a Team Server merge" (fix property-sets, fix hashes, git note). #236 remainder: known_fix_note gains the model-stamp.sh arm keyed on GIT_WORK_TREE (patch 0004); test-model-stamp.sh T9 adds the unstaged worktree `commit -a` and `commit -- app` cases. Golden input: `--version`, `fix --help`, `fix property-sets --help` and a not-found dry-run, captured from the official v0.24.0/v0.25.0/v0.26.0 linux-amd64 release binaries (never run against a model). The clean / NEEDS / FAILED reports follow mxcli v0.26.0's source format strings. tests/wave2/test-property-sets.sh: 43 passed here, 26 fail on master's doctor.sh/sync-project.sh. Field run on a real model still owed. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VJgWP5vEoAsNsJYqCDMGNw --- CHANGELOG.md | 2 + bin/doctor.sh | 200 ++++++++++++++++ bin/sync-project.sh | 29 +++ skills/learned-detection-gaps.md | 1 + skills/platform-link.md | 27 +++ .../dry-run-not-found-v0.26.0.exit | 1 + .../dry-run-not-found-v0.26.0.txt | 2 + .../property-sets/fix-help-v0.24.0.txt | 21 ++ .../property-sets/fix-help-v0.25.0.txt | 22 ++ .../property-sets/fix-help-v0.26.0.txt | 23 ++ .../fix-property-sets-help-v0.25.0.txt | 22 ++ .../property-sets/version-v0.24.0.txt | 1 + .../property-sets/version-v0.25.0.txt | 1 + .../property-sets/version-v0.26.0.txt | 1 + tests/wave2/test-model-stamp.sh | 6 + tests/wave2/test-property-sets.sh | 219 ++++++++++++++++++ 16 files changed, 578 insertions(+) create mode 100644 tests/wave2/fixtures/property-sets/dry-run-not-found-v0.26.0.exit create mode 100644 tests/wave2/fixtures/property-sets/dry-run-not-found-v0.26.0.txt create mode 100644 tests/wave2/fixtures/property-sets/fix-help-v0.24.0.txt create mode 100644 tests/wave2/fixtures/property-sets/fix-help-v0.25.0.txt create mode 100644 tests/wave2/fixtures/property-sets/fix-help-v0.26.0.txt create mode 100644 tests/wave2/fixtures/property-sets/fix-property-sets-help-v0.25.0.txt create mode 100644 tests/wave2/fixtures/property-sets/version-v0.24.0.txt create mode 100644 tests/wave2/fixtures/property-sets/version-v0.25.0.txt create mode 100644 tests/wave2/fixtures/property-sets/version-v0.26.0.txt create mode 100755 tests/wave2/test-property-sets.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index b46921d3..3390a0ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. ## Unreleased +- feat(doctor, sync-project): **`mxcli fix property-sets` is wired into the upgrade path, report first: the Studio Pro merge break no gate could see.** mxcli up to v0.25 wrote units without Studio Pro's full property set. `mx check`, the build and the runtime stay green, and Studio Pro's merge/diff throws ("Objects with ID … do not have the same properties") once it has saved such a document. New `bin/doctor.sh --property-sets ` runs the read-only `--dry-run` and records the result with the mxcli version in `.claude/.property-sets-receipt` (machine-local, gitignored). It exits 0 clean, 1 needs repair or could not classify (never green by absence), 2 not run, 3 for an mxcli before v0.26.0. `sync-project.sh` runs it with `--if-stale`, once per installed mxcli version, and `doctor --quick` (which exec.sh runs when the mxcli version changes) warns while it is owed. The repair is `bin/doctor.sh --fix-property-sets `, which runs `mxcli fix property-sets` only through `exec.sh --patch` (snapshot, mxbuild gate, restore). It refuses on an exec.sh without `--patch`. Support is probed from `mxcli fix --help`, because `mxcli fix property-sets --help` exits 0 on v0.24/v0.25 too, printing the parent's help. New row in `learned-detection-gaps.md`; `platform-link.md` gains "Before a Team Server merge", covering `fix property-sets`, `fix hashes` and `git note`. Golden input is captured from the v0.24.0/v0.25.0/v0.26.0 release binaries. The clean/NEEDS/FAILED reports follow mxcli's source format strings, because no model was run. `tests/wave2/test-property-sets.sh` (43 cases, 26 fail on master). Field run still owed. `fix hashes` as an `exec.sh --patch` post-step is pending (Refs #295) — jopterhorst +- fix(sync-project): **sync names a `bin/model-stamp.sh` that predates the worktree hook blind-spot fix.** `known_fix_note` gains the `model-stamp.sh` arm from the #236 patch, keyed on `GIT_WORK_TREE`, which the fixed script pins. The arm says to upgrade `model-stamp.sh` and `_common.sh` together. `tests/wave2/test-model-stamp.sh` T9 adds the unstaged worktree `commit -a` and `commit -- app` cases. The silent rc 1 half of #236 landed earlier. The new note is asserted by `test-property-sets.sh` P10, which fails on master. — MendixMau (card-disbursement requirements-driven build, field task 21) - feat(lint): **Lint Batch 3 — TXT001 build-process words in user-visible text, TXT002 non-ISO dates in user-visible text, UI001 Data grid 2 / Atlas input layout traps.** From the 2026-10-12 UX-fix retros ([#280](https://github.com/MendixMau/mxcli-project-toolkit/issues/280), [#282](https://github.com/MendixMau/mxcli-project-toolkit/issues/282), [#276](https://github.com/MendixMau/mxcli-project-toolkit/issues/276)): leaked words reached 3 of 3 apps and non-ISO dates 2 of 3, each past a one-off glossary grep; a list view in a grid column and a width on an Atlas input each cost fix rounds. Warning severity, `_rule` finding on a missing field, an empty `strings()` under a FULL-catalog rule, or vocabulary that matches nothing; 23 cases in `tests/lint-rules/test-batch3-rules.sh` (harness gained a `strings()` mock). Field run (mxcli 0.26.0, 21-module Mendix 11.12 model): 0/0/0 over 478 user-visible strings and 271 widgets, with loosened positive controls returning 27/50/17 through the same accessors. TXT002 cannot see format strings inside expressions — that half is a blocked row. `process/lint-backlog.md` Batch 5 lists all 17 candidates from the three issues (rows 32–48) — MendixMau - new(process): **feedback typed mid-build gets a change log in `PROJECT.md`, written before any edit, and the BRD/decision/architecture/wireframe is edited before the MDL.** Across 12 mid-build changes on real projects, 12 went straight into MDL and 0 updated a BRD, build plan or wireframe; the drift-sync `UNSYNCED` marker was never written once, and its absence is invisible, so every gate passed on silence. At the other extreme, one already-settled entity change cost ~270k tokens through two helper agents, and one screenshot-driven fix took 4 rounds because it regressed twice. New `skills/change-intake.md` (baseline, lead+ba, Stages 2–7; routing trigger "the user gives feedback or asks for a change mid-project"): one `## Change log` row per ask (`CR | Date | Source | Verbatim ask | Class | Size | Entry artifact | Status | Closed-by`), six classes, each mapped to its entry artifact (a decision is superseded by a new row, never edited; a built page's visual change is recorded as a before/after screenshot pair instead of wireframe upkeep; impl/bug need only a regression journey). Ceremony is proportional: a small change the user typed gets a one-line receipt and no question, a medium one gets one batched question at the next module gate, a large one or one that contradicts a CONFIRMED decision is asked and stopped on, and stakeholder asks wait for the user. Statuses run open → refined → agreed → applied → proven, or rejected. `bin/lib/change-log.sh` holds the one template and the parser: `init-project.sh` writes the section, `sync-project.sh` appends it once to older projects, and `gate-check.sh` prints a **warn-only** `Change log:` line plus a dashboard row (rows not yet applied, N of M; applied/proven rows with no Closed-by; unrecognised statuses). It becomes blocking only after two projects' counts match a hand count. `project-bin/exec.sh --cr CR-NN` tags the BUILD-LOG detail cell (metrics-ledger columns unchanged). Ownership contradiction fixed: the lead marks; ba-agent flushes BRDs and briefs; architect-agent flushes wireframes and `architecture/` (runbook §3b, `iterative-build-loop.md`, `agent-roles.md`, both stubs, `close-the-loop.md`). Inbox TD-04's change-loop half is promoted here, and its row is narrowed to the two unpromoted items. Fixture `tests/wave2/test-change-log.sh` (39 cases, PROJECT.md built by the real init) — MendixMau - feat(exec): **per-project exec lock with stale takeover, opt-in `--commit-first`, a post-exec "restart needed / watch can apply this" verdict, a scoped `bin/app-restart.sh`, and `bin/test-scratch.sh` for `mxcli test` on a locked copy** ([#287](https://github.com/MendixMau/mxcli-project-toolkit/issues/287) items 3-4, [#284](https://github.com/MendixMau/mxcli-project-toolkit/issues/284), [#275](https://github.com/MendixMau/mxcli-project-toolkit/issues/275), [#289](https://github.com/MendixMau/mxcli-project-toolkit/issues/289) items 1-2, [#285](https://github.com/MendixMau/mxcli-project-toolkit/issues/285), [#278](https://github.com/MendixMau/mxcli-project-toolkit/issues/278) recipe half). In a 20-task UX-fix field run over three apps (2026-10-12), 57 of 148 `exec.sh` runs applied nothing (26 refused on uncommitted model changes, 15 gate failures, 16 mxbuild exit 1), a machine-wide `pgrep "mxcli exec"` guard blocked an exec because another project was writing, watch mode silently missed recreated microflows, grants, attributes, pages, page URLs and theme SCSS/JS (~26 restarts), and 24 implementer restart-resumes cost 41.6M tokens because only the lead could restart apps. `exec.sh` now locks per project (atomic, `