Skip to content

Fix eight defects from the rest/ledger/sudoku/ChipCoV6 test-project findings - #1083

Merged
ako merged 9 commits into
mainfrom
claude/peaceful-clarke-0emnau
Oct 9, 2026
Merged

ako merged 9 commits into
mainfrom
claude/peaceful-clarke-0emnau

Conversation

@ako

@ako ako commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Eight independent fixes from the 2026-10-09 FINDINGS.md rounds of the test projects (ako/mxcli-ledger, ako/mxcli-sudoku, ako/ChipCoV6). One commit each, each with a failing-first test, a revert proof, and a new finding record; most also checked end to end on a copy of the reporting project.

1. fix(pages): layout-grid row/column appearance lost on describe → exec (ledger #167) — data loss

A describe → exec round trip dropped every design property, class and style on layout-grid rows and columns, and reset row/column alignment. On ledger MyFirstModule.Home_Web: Forms$DesignPropertyValue 46 → 33 ('Flex container' ×7, 'Column gap' ×3, 'Cards style' ×3 — real values, not None as the finding thought), and VerticalAlignment: Center ×6 → None. check, exec and mx check were all green.

Cause: no layer carried it — parseLayoutGridRows read only columns/weights/widgets, the v3 builder ignored row/column properties (validator classed them slotDropped), and the writer hardcoded an empty appearance and alignment None.
Fix: sdk/pages rows/columns gain Class, Style, DynamicClasses, DesignProperties and alignment; describe prints them only when set (a plain grid still describes as row {); the builder types design properties against the theme's LayoutGridRow/LayoutGridColumn groups; both writers (modelsdk, mcp) write them, defaults unchanged.
End to end: 46 entries kept, alignment kept, second exec reports Unchanged page. Not run: docker check (no mxbuild in this container).

A follow-up commit strikes two TestApp snippets (WorkflowCommons.Snip_UserTask_NameColumnWithIcon, Snip_WorkflowJumpToDetails) from the round-trip knownFailures: this fix repaired them (they still fail at its parent commit), and the ratchet requires the allowlist to shrink.

2. fix(check): no MDL-WIDGET07 for an explicit pluggable widget id without a project (ledger #165)

Without -p, a pluggablewidget '<id>' has no definition and fell through to the built-in widgets' allow-list, so every property was reported "silently dropped on write" (58 false hits on the ledger's Vega chart). Now skipped for explicit-id widgets, as MDL-WIDGET25 already does; with a project an unknown id is still MDL-WIDGET25. Control: a built-in container with a bogus key still warns. Ledger, no project: 58 → 0.

3. fix(navigation): report Unchanged when a navigation rewrite was elided (ChipCoV6)

create or modify navigation printed "updated" on every run though the write was elided (unit files byte-identical). Now reported through ctx.reportWrite like security/settings (#890); the kept-menu-actions note prints only when written. ChipCoV6 re-run: 22 → 23 documents in sync, no navigation line.

4. fix(security): echo the rule a GRANT wrote, not a shared one (ChipCoV6)

The Result: line picked the first rule naming any granted role; the backend upserts by the exact role set + XPath. GRANT now selects by that key (REVOKE keeps the overlap match). ChipCoV6: Result: read * → Result: read (Country), write (Country), matching show access.

5. fix(deprecation): MDL-DEPR081 names the $currentObject form it means (sudoku #63)

The warning said to write Visible: <expression> — "same meaning" — but inside the brackets a bare attribute is rooted in $currentObject, so dropping the brackets alone rebinds it. fmt --upgrade was already right. The entry's Canonical now names the binding; it is the text shown by the warning, the mdl-2 refusal, the LSP, fmt notes, help and the generated migration table (regenerated).

6. fix(visitor): hint the if exists order, and no false missing-; after recovery (ledger #166)

drop microflow M.F if exists; gave only extraneous input 'if', plus — under mdl 1; — a second error claiming a missing ;, because recovery truncated the statement. The parse error now names the order (drop microflow if exists M.F;), and the mdl-1 terminator check stands down on a line that already has a syntax error. Control: a genuinely missing ; on a clean line is still refused.

7. fix(visitor): hint the quoted last segment for a hyphenated icon name (ChipCoV6)

Icon: Atlas_Core.Atlas.add-circle (error pointing at a dot) and Icon: 'Atlas_Core.Atlas.add-circle' (stray string) now carry a hint naming Atlas_Core.Atlas."add-circle", for menu items and widget icons. The grammar is unchanged — an icon stays a qualified name. Control: the quoted segment parses; unrelated errors on an icon line get no hint.

8. fix(lint): MPR007 flags a user role that cannot open its home page (ChipCoV6)

A user role whose module roles have no access to its effective home page (role-based entry, else the profile default; page or microflow) built to 10× CE2729 in docker check, with nothing from lint or check --references. MPR007 now reports it per profile and user role, naming the page and the fix (grant view, or a role-based home page). Skipped under security level Off; a page with no allowed roles at all stays CE0557's report. End to end on ChipCoV6: an added TmpUser (mxbuild: 10× CE2729) is flagged; the unmodified project and the ledger report no new MPR007.

Validation

make build, make test, make lint-go and make check-findings pass; TestTestAppRoundTrip passes locally with the struck allowlist.

🤖 Generated with Claude Code

https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT

claude added 7 commits October 9, 2026 20:25
After `grant write (Country) on entity FieldService.Customer to
FieldService.Coordinator`, the Result line printed `read *` - the rights of
the shared FabUser/Coordinator/Engineer rule - while the grant had written a
separate rule for Coordinator alone.

formatAccessRuleResult picked the first rule naming ANY granted role with the
same XPath, but AddEntityAccessRule upserts by the exact role set plus XPath.
On the GRANT path the echo now selects by that same key (sameRoleSet mirrors
the backend's order-insensitive sameStringSet). REVOKE keeps the any-overlap
match, which it wants.

Finding: .claude/skills/fix-issue/findings/mdl-executor/2026-10-09-grant-result-line-describes-shared-rule.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
…ut a project

`mxcli check` with no project reported every property of a project's own
pluggable widget (`pluggablewidget '<id>' w (…)`) as "not recognized and
will be silently dropped on write", although exec writes them all and the
same check with -p is clean. 58 false warnings across the mxcli-ledger
scripts.

Cause: with no project the widget registry holds only the embedded
definitions, so the explicit id resolves to no definition. TypeIsGeneric is
set only for a bare-identifier type, so this form fell through to the
built-in static allow-list. MDL-WIDGET25 already returns early for an
explicit id with no project.

Fix: skip the built-in checks for any widget carrying an explicit widget id,
detected by a new explicitWidgetID helper now shared with MDL-WIDGET25. With
a project an unknown id is still MDL-WIDGET25. Control test: a built-in
`container c (bogus: 1)` still raises MDL-WIDGET07.

Finding: .claude/skills/fix-issue/findings/mdl-executor/2026-10-09-check-no-project-widget07-explicit-widget-id.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
Re-running `create or modify navigation Responsive ...` printed
"Navigation profile 'Responsive' updated." on every run, although
canon.Reconcile elided the write and no .mxunit changed. The handler
printed its sentence with fmt.Fprintf after UpdateNavigationProfile
returned, so it claimed a write it had no evidence for; the #890 sweep
moved security and settings onto ctx.reportWrite but missed navigation.

The update branch now reports through ctx.reportWrite, which says
"Unchanged navigation profile '<name>'" (via the run tally) when the
write was offered and elided. The kept-menu-action note follows the
write, as reportWrite's follow-up lines do elsewhere. Creating a profile
always writes and is unchanged.

Finding: .claude/skills/fix-issue/findings/mdl-executor/2026-10-09-create-or-modify-navigation-reports-updated-when-write-elided.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
…ough describe -> exec

A describe -> exec round trip of a Studio Pro page lost every design
property, class and style on its layout-grid rows and columns, and reset
row/column alignment. Measured on ledger MyFirstModule.Home_Web:
Forms$DesignPropertyValue entries 46 -> 33 ('Flex container' x7 on
columns, 'Column gap' x3 and 'Cards style' x3 on rows), and
LayoutGridRow.VerticalAlignment Center x6 came back None. check, exec
and mx check were all green.

Cause: none of the three layers carried it. parseLayoutGridRows read
only columns/weights/widgets; buildLayoutGridRowV3/ColumnV3 ignored all
properties but widths (the validator classified row/column as
slotDropped); layoutGridRowToGen/ColumnToGen hardcoded an empty
Forms$Appearance, alignment "None" and SpacingBetweenColumns true.

Fix: sdk/pages LayoutGridRow/Column gain Class, Style, DynamicClasses,
DesignProperties and alignment (row: Vertical/HorizontalAlignment,
NoSpacingBetweenColumns; column: VerticalAlignment). Describe reads the
row's and column's Appearance and alignments and prints them only when
set (`row (VerticalAlignment: Center, DesignProperties: (...)) {`), so a
plain grid describes as before. The builder types design properties
against the theme's LayoutGridRow / LayoutGridColumn groups (shared
designPropertyValuesV3, split out of applyWidgetAppearance), and the
validator checks them there instead of reporting them dropped. A
top-level `row`/`column` keeps its appearance on the wrapping container
only. Writers (modelsdk and mcp) write the carried values, defaults
unchanged when unset.

Finding: .claude/skills/fix-issue/findings/mdl-executor/2026-10-09-layout-grid-row-column-appearance-lost-on-describe-exec.json
(follows 2026-09-29-re-running-describe-page-output-resets-every-layout-grid).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
MDL-DEPR081 told the author to write `Visible: <expression> / Editable:
<expression>` — "same meaning". It is not: inside the brackets a bare
attribute is rooted in $currentObject, so dropping the brackets alone
rebinds it (`Visible: ["N1"]` stores $currentObject/N1, `Visible: "N1"`
does not). A hand migration from the message changed every notes-mode
cell in sudoku with check, exec, mx check and tests all green (sudoku
FINDINGS #63). fmt --upgrade and the Structural rewrite were already
right; the one-line message contradicted its own suggestion.

The entry's Canonical now names the binding. It is the text shown by the
check/exec warning, the mdl-2 refusal, the LSP, fmt notes, help and the
generated migration table (versions.md regenerated).

Finding: .claude/skills/fix-issue/findings/mdl-other/2026-10-09-depr081-message-canonical-drops-currentobject.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
…ter recovery

`drop microflow M.F if exists;` (SQL order) gave only `extraneous input
'if'`, and under `mdl 1;` a second error claimed the statement "has no
terminating `;`" — ANTLR's recovery ended the drop at the name and
discarded `if exists;`, and the mdl-1 terminator check read that
truncated statement (ledger FINDINGS #166).

enhanceErrorMessage now names the order (`drop microflow if exists
M.F;`). The error listener records the lines it reported on, and
ExitStatement does not add a terminator error on such a line: the
statement there is what recovery left, not what was written. A missing
`;` on a clean line is still refused.

Finding: .claude/skills/fix-issue/findings/mdl-visitor/2026-10-09-drop-if-exists-after-name-blames-missing-semicolon.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
…epaired

integration (roundtrip) failed with "no longer breaks getput — strike it
from knownFailures" for WorkflowCommons.Snip_UserTask_NameColumnWithIcon
and Snip_WorkflowJumpToDetails. Both pass getput at a1f0463 and still
fail at its parent 4b1cfde: carrying layout-grid row/column appearance
and alignment through describe -> exec is what repaired them. The
allowlist may only shrink.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
@ako ako changed the title Fix four defects from the rest/ledger/sudoku/ChipCoV6 test-project findings Fix six defects from the rest/ledger/sudoku/ChipCoV6 test-project findings Oct 9, 2026
claude added 2 commits October 9, 2026 21:24
`Icon: Atlas_Core.Atlas.add-circle` failed with an error pointing at a
dot (or `no viable alternative` on a widget), and quoting the whole name
read as a stray string; neither said what to write, and it cost the
ChipCoV6 build two retries. The grammar is right — an icon is a
qualified name and `add-circle` is not an identifier — so the fix is a
source-line hint naming `Atlas_Core.Atlas."add-circle"`, for menu items
and widget icons, unquoted or quoted whole.

Finding: .claude/skills/fix-issue/findings/mdl-visitor/2026-10-09-hyphenated-icon-name-no-hint.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
A user role none of whose module roles is allowed on the home page it lands
on passes `mxcli lint` and `check --references`, then fails mxbuild with one
CE2729 per widget on that page ("No read access to attribute ... for user
role 'X' (with no roles defined in module 'M')") — none of which names the
cause. ChipCoV6 hit it with the template's generic `User` role left in place
after the Responsive home page moved to a new module (FINDINGS.md: 10x
CE2729 in docker check).

MPR007 only checked that a navigation page has some allowed role (CE0557).
It now also resolves, per navigation profile and user role, the effective
home page (the role-based entry for that role, else the profile default)
and warns when none of the role's module roles is allowed. A microflow home
page is checked against the microflow's allowed module roles. Skipped at
security level Off; a page with no allowed roles at all is left to the
existing CE0557 report. The guest role is an ordinary user role in the
list, so it is covered without special-casing; nothing is exempted by name.

Verified on a copy of ChipCoV6 with `create user role TmpUser (ModuleRoles:
(System.User, Administration.User))`: mxbuild 11.15.0 reports 10x CE2729,
lint now reports one MPR007 warning naming TmpUser, Responsive and
FieldService.Home_Dashboard; the unmodified project (Administrator, FabUser,
ServiceCoordinator, FieldEngineer) and Ledger report no new MPR007.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012PkPkaYM12u8yqMKNmzBgT
@ako ako changed the title Fix six defects from the rest/ledger/sudoku/ChipCoV6 test-project findings Fix eight defects from the rest/ledger/sudoku/ChipCoV6 test-project findings Oct 9, 2026
@ako
ako merged commit 6b3f0b1 into main Oct 9, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants