Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e148e6e
feat(describe): draw a module's domain model as SVG
ako Oct 11, 2026
76581aa
feat(companion): show the domain model diagram on surfaces that draw SVG
ako Oct 11, 2026
ec1b54a
feat(companion): show diagrams at actual size, with pan, fit and a fu…
ako Oct 11, 2026
06d50e9
fix(companion): give the diagram Svg its size, so it is not a thumbnail
ako Oct 11, 2026
2c8b998
docs(skills): regenerate the create-page section index
claude Oct 11, 2026
bdd6105
fix(describe): fit full names in the domain model SVG without overlap
ako Oct 11, 2026
dc2b276
fix(test): carry the raised error message into the FAIL verdict
claude Oct 11, 2026
c531677
feat(test): --app-port/--admin-port/--serve-port for test --local
claude Oct 11, 2026
d152835
fix: unnamed DataGrid 2 column with no caption writes an empty header…
claude Oct 11, 2026
7e8e5b1
fix(init): title generated docs after the app, not the repo folder
claude Oct 11, 2026
4eb1a08
fix(init): default the bootstrap script's MXCLI_TAG to the generating…
claude Oct 11, 2026
a4b7a4f
docs(skills): drop the dated Mendix version claim from bootstrap-app
claude Oct 11, 2026
2ca94b8
fix(docker): resolve the project's JDK major on macOS, never the /usr…
claude Oct 11, 2026
0f71b80
fix(init): make a failed database provisioning loud in the bootstrap …
claude Oct 11, 2026
9ad158c
Merge pull request #1116 from ako/claude/peaceful-clarke-0emnau-skill…
ako Oct 11, 2026
0ddc417
fix(syntax): stop teaching spellings check flags as deprecated
claude Oct 11, 2026
14d09a4
test(syntax): hold Example and Syntax to the deprecation registry
claude Oct 11, 2026
75acb27
feat(syntax): add microflow.workflow-actions topic
claude Oct 11, 2026
af4617a
fix(docker): bound one-shot mxbuild runs with a timeout and stall wat…
claude Oct 11, 2026
f4bef02
fix(docker): raise the mxbuild watchdog defaults to 30m / 10m stall
claude Oct 11, 2026
1f279c0
fix: unbound DataGrid 2 attribute column gets an empty tooltip template
claude Oct 11, 2026
05a05aa
fix(grammar): accept a module-qualified association hop in an attribu…
claude Oct 11, 2026
6a5994f
meta: measured read access for System module entities
claude Oct 11, 2026
516ca85
lint: SEC010 flags page data widgets their roles cannot read
claude Oct 11, 2026
cc69904
fix(check): predict flow verdicts for calls to flows the script creates
claude Oct 11, 2026
8f0b0eb
Merge pull request #1118 from ako/claude/peaceful-clarke-0emnau-test-…
ako Oct 11, 2026
07bc890
Merge pull request #1119 from ako/claude/peaceful-clarke-0emnau-init-…
ako Oct 11, 2026
dda7435
Merge remote-tracking branch 'origin/main' into claude/peaceful-clark…
claude Oct 11, 2026
fd1ed9a
Merge pull request #1120 from ako/claude/peaceful-clarke-0emnau-synta…
ako Oct 11, 2026
ca1cfc7
Merge pull request #1122 from ako/claude/peaceful-clarke-0emnau-dg2-q…
ako Oct 11, 2026
a2db41b
Merge pull request #1123 from ako/claude/peaceful-clarke-0emnau-flow-…
ako Oct 11, 2026
b602a33
Merge pull request #1124 from ako/claude/peaceful-clarke-0emnau-lint-…
ako Oct 11, 2026
d5b5949
Merge pull request #1121 from ako/claude/peaceful-clarke-0emnau-macos…
ako Oct 11, 2026
bf7bdca
Merge pull request #1125 from ako/claude/peaceful-clarke-0emnau-dg2-h…
ako Oct 11, 2026
249c03b
Merge pull request #1117 from ako/claude/peaceful-clarke-0emnau-test-…
ako Oct 11, 2026
ee5a747
Merge pull request #1115 from ako/feature/companion-domain-model-svg
ako Oct 12, 2026
bb5d38c
Merge branch 'mendixlabs:main' into main
ako Oct 12, 2026
1c8326f
fix(lint): SEC010 counts a specialization's rule only for the members…
claude Oct 12, 2026
c9c0f34
Merge pull request #1126 from ako/claude/peaceful-clarke-0emnau-sec01…
ako Oct 12, 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 .claude/commands/mendix/lint.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ mxcli lint -p app.mpr --exclude System --exclude Administration
| SEC001 | security | NoEntityAccessRules - Persistent entities need access rules |
| SEC002 | security | WeakPasswordPolicy - Password minimum length should be 8+ |
| SEC003 | security | DemoUsersActive - Demo users should be off at Production security |
| SEC010 | security | PageEntityNotReadable - A page data widget lists an entity the user roles that open the page cannot read; at Production it renders empty, silently (info when only row-scoped) |
| CONV011 | performance | NoCommitInLoop - Commits inside loops (commit actions, or create/change with commit) cause N+1 issues |
| CONV012 | quality | ExclusiveSplitCaption - Exclusive splits need meaningful captions |
| CONV013 | quality | ErrorHandlingOnCalls - External calls (REST/WS/Java) need custom error handling |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "symptom": "A session whose SessionStart hook failed to provision the app database (\"no local PostgreSQL superuser available\") looked like a healthy one: the hook runs `sh .claude/bootstrap-mxcli.sh || true` and the script ended in `exec ./mxcli run --local --setup --ensure-db`, so the failure was one line in hook output nobody reads and exit 0 (ChipCoV8/V9 bootstrap findings)", "cause": "`exec` handed the script's last word to mxcli, leaving the script no chance to react to the failure; `|| true` (correct — a hook must not block the session) then hid the status", "file": "`cmd/mxcli/init_hook.go` (`bootstrapScriptTemplate` tail); tests `cmd/mxcli/init_hook_failure_test.go`; `docs-site/src/tools/bootstrap-prompt.md`", "insight": "Keep `|| true` and move the loudness into the script: run without exec, tee the output to a log, keep the status in a file (a POSIX sh pipeline's status is tee's, and `cmd || echo $? >file` is the set -e-safe capture), then print an ERROR banner naming the last error line, the retry and `--db-type hsqldb`, and exit with that status. Test it by running the generated script under sh (dash here) with a stand-in mxcli whose `run` fails — the control (`run` succeeds) asserts no banner. Before the fix the failing case exited with the right status but printed no banner"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "symptom": "The generated `.claude/bootstrap-mxcli.sh` defaulted `MXCLI_TAG` to `nightly` whatever mxcli wrote it, so a project initialised by a pinned release re-fetched the current nightly after every idle reap — a different mxcli from the one its tooling was written by (ChipCoV8/V9 bootstrap findings)", "cause": "`TAG=\"${MXCLI_TAG:-nightly}\"` was a literal in `bootstrapScriptTemplate`", "file": "`cmd/mxcli/init_hook.go` (`bootstrapDefaultTag`, `renderBootstrapScript`); tests `TestBootstrapDefaultTag`, `TestBootstrapScript_DefaultTagIsGeneratingRelease` in `cmd/mxcli/init_hook_test.go`; `docs-site/src/ide/syncing.md`", "insight": "Only a plain `vX.Y.Z` is a downloadable tag: `devcontainerReleaseTag`/`mxcliReleaseTag` strip a `-N-gHASH` suffix, which would map a dev build onto a release it is not — the bootstrap default must not do that, so it uses its own strict match and keeps nightly otherwise. The script is regenerated by `mxcli init` (not by `--sync-skills`), so the default is the release that last ran init"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "symptom": "`mxcli init` titled the generated CLAUDE.md `# Mendix Project: <repo folder>` (and named the devcontainer after it): a cloud session clones into a folder named after the repository, so a seed repo produced `Mendix Project: seed` for an app called ChipCoV8 (ChipCoV8/V9 bootstrap findings)", "cause": "`projectName := filepath.Base(absDir)` in init, add-tool and the `init --sync-skills` doc refresh — the folder stood in for the app name although the .mpr file name was already in hand", "file": "`cmd/mxcli/init_claudemd.go` (`projectDisplayName`), `cmd/mxcli/init.go`, `cmd/mxcli/cmd_add_tool.go`, `cmd/mxcli/init_tooling_sync.go`; test `cmd/mxcli/init_appname_test.go`", "insight": "Every consumer of projectName is a display name (doc headings, devcontainer `name`, comments) — paths use absDir/mprFile — so one helper covers them all. The sync path matters as much as init: fixing init alone would have the session hook's `init --sync-skills` retitle the doc after the folder again. The `project.mpr` placeholder (no .mpr found) keeps the folder name. Control: with the call sites reverted to filepath.Base the init and sync tests fail"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "symptom": "On macOS, `mxcli new` for an 11.14+ (Java 25) project hung 10+ minutes in its final build step, running mxbuild with `--java-home=/usr --java-exe-path=/usr/bin/java`, Gradle at 100% CPU. `docker build`, `run --local` and `test --local` resolve the JDK the same way", "cause": "`resolveMacOSJavaHome` hard-coded `/usr/libexec/java_home -v 21`, so for a Java 25 project its answer always failed the major check and resolution fell through to `LookPath(\"java\")`. On macOS /usr/bin/java is a launcher stub, not a symlink: EvalSymlinks leaves it, the derived home is /usr, and `isJDK(\"/usr\", 25)` passes because the stub forwards `-version` to the default JDK", "file": "`cmd/mxcli/docker/detect.go` (`resolveJDKWith`, injectable `jdkEnv`, `isMacOSJavaStub`, `resolveMacOSJavaHome(major)`)", "insight": "A version probe through a forwarding launcher validates the launcher's target, not the path you derived from it — `isJDK` answered a question about a different directory than the one returned. The machine that exhibits this is one CI never runs, so the fix had to make the OS, java_home, LookPath and isJDK injectable; the fake models the stub's worst case (isJDK('/usr', n) true for every n). Revert proof: java_home -v 21 plus no /usr rejection returns /usr for a Java 25 project. Off macOS /usr is left alone — a Linux PATH java resolves through symlinks to /usr/lib/jvm/...", "refs": ["ChipCoV8 #3"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "symptom": "`mxcli new`'s final settle build (and `mxcli docker build`) could hang indefinitely — observed 10+ minutes on macOS with Gradle at 100% CPU and no output, and nothing ever reported or gave up", "cause": "`SettleGeneratedSources` and `mxbuildCmd` called `cmd.Run()` bare: no deadline, no detection of a build that had stopped printing, and killing only the direct child would not have helped since mxbuild is a wrapper whose JVM/Gradle grandchildren hold the output pipe", "file": "`cmd/mxcli/docker/mxbuild_watchdog.go` (`runWithWatchdog`, `WatchdogError`, `MXCLI_MXBUILD_TIMEOUT` default 15m, `MXCLI_MXBUILD_STALL_TIMEOUT` default 5m), wired in `settle.go` and `build.go` (`mxbuildCmd`)", "insight": "Bound the process TREE, not the child: the fake mxbuild in the test is `echo; sleep 60 & wait`, because a grandchild holding the pipe is exactly what makes `Wait` block after a plain Kill — reuse `setProcessGroup`/`killProcessGroup` and set `cmd.WaitDelay` as a backstop. The error carries the last output lines and the java home used, since a wrong --java-home was the cause the one time this was seen. Revert proof: `mxbuildCmd` with bare `cmd.Run()` leaves the hung fake running past the test's 20s guard. The trigger here was the /usr/bin/java stub (sibling finding); the watchdog is what turns the next unknown cause into an error instead of a hang", "refs": ["ChipCoV8 #6"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "symptom": "`mxcli syntax` teaches spellings `check` warns on as deprecated, so an agent copying the reference gets MDL-DEPRnnn: `NOT NULL [ERROR 'msg']` (MDL-DEPR021, write `error message`), a named data grid `COLUMN name (` (MDL-DEPR005), `CREATE [OR REPLACE]` for microflow/nanoflow/layout/navigation (MDL-DEPR001), `MODEL accepts these keys` for `alter settings runtime` (MDL-DEPR555), the MOVE doctype list's QUEUE / REST CLIENT / ODATA CLIENT / ODATA SERVICE / MODEL, and `Date` as an attribute type (MDL-DEPR160, refused under mdl 1); the microflow workflow actions (`$Wf = call workflow M.WF ($Obj);`, get workflow data, workflow operation, lock/unlock …) had no topic at all", "cause": "TestExamplesParse proved each Example parses but never ran the validator, and the Syntax field (metasyntax) was checked only against hand lists of retired spellings — every deprecation added to the registry after a topic was written left that topic stale", "file": "`cmd/mxcli/syntax/features_{domain_model,misc,page,microflow,workflow}.go`; guards in `cmd/mxcli/syntax/example_parses_test.go` (deprecationErrors, container wrappers) and `cmd/mxcli/syntax/syntax_deprecations_test.go` (registry-driven fingerprints)", "insight": "Drive the guard from `mdl/deprecation`, not a hand list. Examples: run `executor.ValidateProgram` + `ApplyDeprecationPolicy(Error)` in EVERY context a block parses in, and host fragments in their containers (datagrid, dataview) because MDL-DEPR005 only fires on a column inside a grid. Syntax: diff each entry's Example against its CanonicalExample to get the changed tokens, then widen with context until the pattern holds a keyword, does not end on a name (`Ready comment` matched the prose \"a comment\"), and matches none of the known-clean corpus (all CanonicalExamples + every validated Example) — that corpus is what keeps `image collection` or `type:` from flagging canonical text. Drop `[`/`]` when lexing or `NOT NULL [ERROR 'msg']` escapes the pattern. Prose in `--` comments is not matched, so the MOVE doctype list and the RUNTIME prose had to be found by hand with `check`. Revert-proofed: restoring `ERROR 'msg'`, `COLUMN name (` or `head($L)` each fails with the code.", "refs": ["ChipCoV8 #9", "ChipCoV8 #12", "ChipCoV9 #4"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-11", "raw": "| A `mxcli test` case whose body does `retrieve … where [id = '[%CurrentUser%]']` fails with only **FAIL:exception during execution** — nothing says what was raised | Two things at once. Runtime: tests run in `Core.createSystemContext()` (`endpoint.go`), a system session with no user, so the `[%CurrentUser%]` token cannot resolve and the retrieve throws; `[id = $currentUser]` only *seems* to work because `$currentUser` is empty there and matches nothing. mxcli: `rewriteBodyForVerdict` wrapped every CALL in an `ON ERROR` handler that set a **fixed** verdict text and discarded the error | `cmd/mxcli/testrunner/generator_endpoint.go` (`rewriteBodyForVerdict`), `.claude/skills/mendix/test-microflows/SKILL.md` | Concatenate the error: `'FAIL:exception during execution: ' + $latestError/Message`. No new measurement needed — `throwsHandler` already uses the same expression, measured at 0 errors on mxbuild 11.6.0 and 11.13.0. A generic catch-all verdict is the same defect class as a decorative assertion: it hides the one fact that diagnoses the failure. The skill now says plainly that tests have no current user and that user-scoped logic is tested by passing the user/account as a parameter. Not changed: the legacy after-startup runner's log-line `Exception during execution` (its runtime log already carries the stack trace). ChipCoV9 #5 |", "refs": ["ChipCoV9#5"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend", "date": "2026-10-11", "symptom": "A Data grid 2 column with no attribute, no content widgets and no ShowContentAs (`column (Caption: '')`) still reports **CE0463** under `mx check --no-update-widgets` after its header is fixed; `fix widgets` changes only its `tooltip`, null -> empty Forms$ClientTemplate", "cause": "`detectObjectListItemKind` classifies a column as attribute-kind only when an attribute is BOUND, so an unbound column fell to `itemKindDefault`, which has no rule in `emptyClientTemplateRules` — its tooltip stayed null. update-widgets keys the convention on showContentAs, whose widget default is `attribute`", "file": "`mdl/backend/widgetobj/builder.go` (`buildObjectListItemBSON`, `effectiveShowContentAs`)", "insight": "Classify by the EFFECTIVE showContentAs (authored, else the widget's DefaultValue), not by whether an attribute is bound. Found only by diffing every column property against `fix widgets` output after the header fix (ChipCoV8 #11) — the header was the first of two differences on the same column, and checking only the reported property would have stopped there. Measured on 11.15.0: CE0463 gone; what remains is Mendix's own legitimate \"An attribute is required when 'Show' is set to 'Attribute'\", which the CE0463 had been masking", "refs": ["ChipCoV8 #11"], "ce": ["CE0463"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-10-11", "symptom": "A Data grid 2 column with no caption (empty or absent), no attribute and **no name** — `column (Caption: '', ShowContentAs: customContent) { actionbutton … }`, `column (Caption: '')`, bare `column { … }` — passes `mxcli check`, but `mx check --no-update-widgets` reports **CE0463** on the grid. `fix widgets` clears it; re-exec rewrites the page and CE0463 returns", "cause": "`applyColumnHeaderFallback` returned early when there was no fallback text (no attribute, no column name), leaving the header an empty texttemplate, which `overlayItemValue` serializes as `TextTemplate: null`. `mx update-widgets` writes an empty `Forms$ClientTemplate` there (Fallback Items[3], Parameters[2], Template Items[3])", "file": "`mdl/executor/widget_engine.go` (`applyColumnHeaderFallback`)", "insight": "**The 2026-08-31 finding's \"verified, 0 errors for custom-content columns (empty + absent caption)\" was incomplete:** its tests and examples always passed a column NAME, so the name fallback hid the unnamed case. Fix: with no fallback, flag the header `EmptyTemplate` (in place, or appended) — scoped by the `hasHeaderSlot` gate, never all texttemplates (null vs empty differs per widget). Measured on 11.15.0 with update-widgets output as the reference: header shapes now byte-match it. A blind spot worth naming: a test fixture that always supplies the optional field (here the name) cannot see the branch where it is absent", "refs": ["ChipCoV8 #11", "ChipCoV9 #2"], "ce": ["CE0463"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-10-11", "symptom": "`check -p` printed \"no flow change exec would refuse\" (and exec's preflight said nothing) for a script whose `create or modify microflow` exec then refused with MDL-V1-REBUILD (\"replace $X: $X is still used by\") — after writing the statements before it. The trigger: the new body calls a flow an earlier statement of the same script creates", "cause": "CheckFlowVerdicts builds the declared flow against the stored project and skips any flow whose build fails as \"not predictable\"; a CALL MICROFLOW to a flow the script creates earlier fails microflowExists (\"not found in the project\"), so the verdict was silently skipped and the check line claimed full coverage", "file": "mdl/executor/validate_flow_verdicts.go (checkFlowVerdicts, flowModifyViolations), mdl/executor/cmd_microflows_builder.go (declaredFlow/scriptFlows overlay), cmd/mxcli/cmd_check.go, cmd/mxcli/exec_preflight.go", "insight": "A check-time prediction that skips what it cannot build must say so: a silent skip reads as a pass, and the skip set is exactly the multi-statement scripts where a half-applied exec hurts. Fix is an overlay of the script's own CREATE [OR MODIFY] MICROFLOW|NANOFLOW signatures in the builder (generalising the self-call `selfFlow` of #843), plus an Unpredicted list (FormatUnpredictedFlows) for whatever still does not build. Revert proof: stub the overlay lookup and the multi-statement case reports no violation, only the unpredicted note"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"date": "2026-10-11", "area": "mdl/grammar", "symptom": "`column (attribute: FieldService.ServiceRequest_LithoSystem/SerialNumber)` in a Data grid 2 failed `mxcli check` with MDL-WIDGET34 (printing the value as `&{…}`, the column as \"column ``\", and advising to wrap it in a data view although it sat in a grid) plus MDL-WIDGET42 \"cannot hold the expression\"; the bare `ServiceRequest_LithoSystem/SerialNumber` passed. XPath and data view sources name the same association module-qualified, so the qualified spelling is the natural one.", "cause": "`attributePathV3` (MDLPage.g4) took only plain identifiers between slashes, so `Module.Assoc/Attr` missed `ATTRIBUTE COLON attributePathV3` and fell through to the generic `keyword COLON expression` alternative, parsing as the division `Module.Assoc / Attr` -> ast.WidgetExpressionV3. The executor already accepted qualified hops (resolveAssociationPathIn keeps a dotted name). The WIDGET34 message formatted the non-string value with %v and assumed a named widget outside any data container.", "fix": "Grammar: `attributePathV3 : (attributePathHopV3 SLASH)* attributePathSegmentV3`, a hop optionally `Module.Assoc`; the final segment stays bare so `M.E.A` (no slash) is not a path. buildAttributePathV3 unquotes each dotted part. Message: nonStringAttributeText returns WidgetExpressionV3.Text; nonPathBindingProblem names an unnamed widget by caption, suggests `Assoc/Attr or Module.Assoc/Attr` for a value with `/`, and drops the wrap-in-a-data-view advice inside a data container.", "insight": "When a value reaches a checker as an expression where a path was meant, look at the grammar alternative it fell out of before the checker: the generic `keyword: expression` fallback silently absorbs every near-miss of a specific property rule, and the checker then reports the symptom (\"cannot hold the expression\"), not the cause. The builder side needed no change — a builder test pinning qualified == bare AttributeRef guards it. Describe still prints the short form.", "issue": "ChipCoV8 #10", "file": "mdl/grammar/domains/MDLPage.g4 (attributePathV3), mdl/visitor/visitor_page_v3.go (buildAttributePathV3), mdl/executor/cmd_pages_input_binding_context.go (nonPathBindingProblem, nonStringAttributeText)", "test": "mdl/visitor/visitor_page_qualified_attribute_path_test.go, mdl/executor/cmd_pages_builder_qualified_assoc_path_test.go, mdl/executor/cmd_pages_input_binding_context_test.go TestValidateInputBindingNonPathValueMessage"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/linter", "date": "2026-10-12", "symptom": "SEC010 stayed silent on a list over `System.User` for a ServiceManager, whose browser showed every row with `Name` blank except their own (`[\"\", \"\", \"demo_manager\", \"\"]`) — the very case the rule was written for (ChipCoV9 FINDINGS, re-check on main)", "cause": "The rule counted any entity-level read on a specialization as reading the generalization. The real Mendix 11.15 Administration module grants Administration.User `read (FullName, Email)` on Account UNCONSTRAINED: the rows come through, but no `System.User` member is in that rule, so the fields are blank. The unit fixture had modelled that rule as row-scoped, so the tests agreed with the code and not with the platform", "file": "`mdl/linter/rules/page_entity_read_access.go` (`entityAccessModel.level`, `memberOwners`); tests `TestPageEntityReadAccess_SystemUserMembersNotGrantedBySpecialization`, `..._SystemUserManageAllRolesReadsMembers`", "insight": "A specialization's rule fills ROWS of a list over the generalization, and FIELDS only for members the rule grants — MEMBER_READ rows are qualified by the declaring entity, so the owner prefix tells. Measured on a scratch copy (run --local, HSQLDB, playwright): an Administrator's Account rule grants no System.User member either, yet every name showed — System.User's own rule also opens users whose roles the user role may manage (ManageableRoles FieldEngineer → demo_engineer's name appeared). Build a lint fixture from `show access` / the catalog of a real project, never from the rule as you remember it"}
Loading
Loading