Repository navigation
Sync ako/mxcli: incremental source-catalog rebuilds (re-describe only what changed) - #1681
Merged
Merged
Conversation
…not have The write refuses an action type newer than the project (canon.UndeclaredTypeError, #1774), but nothing at check time did, so `mxcli check -p` passed a script that exec then refused part-way, and --continue-on-error ran on without that microflow (#1787). check -p and exec's pre-flight now report MDL-VERSION01 for each, naming the statement and the version, wherever it sits in the body (bodyContains: branches, loops, error handlers). Each floor is the type's introduction in mendixmodelsdk 4.117.0: call workflow, set task outcome, open user task, open workflow 9.0.2 workflow operation abort / restart 9.2 workflow operation pause / continue 9.3 get workflow data 9.10 workflow operation retry / unpause 9.12 notify workflow 10.0 get workflows, get workflow activity records 10.4 Lock and unlock (9.21) get no gate of their own: every one check and exec accept names its workflow, and that selection is gated at 10.0. The floors stay in sdk/versions, the one place every gate reads and `show features` lists. Each gate now names the storage types it stands for, and TestTypeGates_FloorIsTheTypeIntroduction pins its row to canon.TypeIntroduced of them (the #1774 workflow type gates too), so the check-time floor and the write-time floor cannot drift. Control: with the table's gates left out of microflowBodyGates, all 70 below-floor cases fail with no violation; a row moved off its type's introduction fails the pin test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
statementVersionGates had no case for `alter microflow|nanoflow`, so no version gate reached what an insert or a replace splices in: check -p passed an alter inserting `get workflows` on 9.24.30, and the write then refused it (#1787). The body gates are now shared (microflowBodyGates, nanoflowBodyGates) and applied to every operation's fragment: the workflow actions, send email, a lock or unlock naming its workflow, and synchronize unsynchronized in a nanoflow. A drop writes nothing new and is not gated. execAlterFlow applies them too, before it reads the stored flow, so exec without the pre-flight (the REPL, --no-check) refuses the statement instead of reaching the write. Control: without the AlterFlowStmt case, the 140 alter cases of TestCheckVersionGates_WorkflowMicroflowActions and the three of TestCheckVersionGates_AlterFlowGatesWhatItInserts report nothing; without the handler call, exec fails with "microflow not found" instead of the version refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…0.24 The bug-test writes a microflow per gated workflow action (the 9.0.2 to 9.12 ones together, then notify workflow, get workflows and get workflow activity records, one nested in a decision) and an alter microflow that inserts get workflows into the first. On 9.24.30, before: check -p passed the script without its 10.0 workflow, and exec refused MF_Notify at write time after five statements; with --continue-on-error --no-check it wrote the other five, and mx check reported 0 errors, so the 9.0.2-9.12 actions load there. After: check -p and exec's pre-flight report MDL-VERSION01 for MF_Notify (10.0), MF_GetWorkflows, MF_ActivityRecords and the alter (10.4), and App.mpr is byte-identical. On 10.24.24, before and after: check -p is clean, exec writes everything, and mx check reports 0 errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
The check-time gate and the write-time type floor answer one question twice, and the class has recurred four times (#1434, #1771, #1774, #1787). The page now names the variant, where the sweep starts (the types the converter writes) and the guard (a pin to canon.TypeIntroduced). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
`mxcli debug break` without `--if` left the `condition` property out of
add_breakpoint. Mendix 11.13 and 11.15 (both measured) refuse that request
with {"message":"Missing property: condition","status":2} and register
nothing, so the microflow never paused. The property is now always sent,
as "" for an unconditional breakpoint, which both runtimes accept with
status 0.
The test stub now answers like the runtime: status 0 on success, and the
runtime's "Missing property: <name>" rejection for each property measured
as required. The test that asserted an empty condition is omitted encoded
the defect; it now asserts the empty string is sent.
#1782, mendixlabs#1676
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
`mxcli debug continue` sent `continue` with empty params. The runtime
requires the flow's debug_id and refuses the request with
{"message":"Missing property: debug_id","status":2} (Mendix 11.13 and
11.15, measured), so the flow stayed paused while mxcli printed
"Continued." -- the reporter's "continue after a step reported Continued.,
but the flow stayed paused until continue --all".
Continue now takes the debug_id and `debug continue` resolves it the way
`step` and `inspect` do: the only paused flow, or the one named with the
new --flow. continue_all, which takes no flow, moves to ContinueAll.
#1782, mendixlabs#1676
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
The runtime answers every /debugger/ request with HTTP 200 and says in the
reply envelope whether it took it: {"result":...,"status":0} on success,
{"result":{},"message":...,"status":2} on a refusal (every reply measured
on Mendix 11.13 and 11.15). post read only the HTTP status, so each refusal
came back as success with an empty result: `debug break` printed
"Breakpoint set" over "Missing property: condition", `continue` printed
"Continued." over "Missing property: debug_id", and `inspect` printed {}
for a String variable over "The variable ... is not a Mendix object."
post now returns a *DebuggerError carrying the action, status and the
runtime's message whenever the status is non-zero, for every action. A
reply without a status is still success, so a runtime that omits it keeps
working. A refused session token (the runtime restarted, or another
debugger started a session) adds the `mxcli debug enable` remedy.
#1782, mendixlabs#1676
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
The client test covers the request continue sends; this one covers the
command: with one flow paused, `debug continue` resolves its debug_id
from get_paused_microflows (the 11.15 reply, verbatim) and sends it.
Against the command as it was, the stub records `continue {}` and the
output is "Continued." -- the reported symptom.
#1782, mendixlabs#1676
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
`debug inspect <var>` asks get_object, which takes only an object
variable. For a String (and an enumeration) the runtime refuses it --
"The variable 'Greeting' is not a Mendix object.", status 2, measured on
11.15 -- and the refusal's empty result printed as {}: the reporter's
"inspect <var> printed {} for a String variable".
get_paused_microflows already carries each in-scope variable's type and,
for a primitive, its value ({"type":"string","value":"hello"}). inspect
now prints that entry for any variable whose type is not object or list,
and sends only objects to get_object. A variable the paused state does
not list (a nanoflow's lives in poll_events) still goes to get_object.
#1782, mendixlabs#1676
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
Now that a refusal from the runtime is an error, every `mxcli debug`
subcommand printed it followed by the command's whole usage text --
thirty-odd lines of flags -- and then the error again, so the runtime's
reason ("Failed to parse condition: ...") was the line you had to scroll
for. Once a subcommand's RunE runs its arguments were accepted, so an
error from there on is not a usage mistake: RunE now sets SilenceUsage.
A missing argument or unknown flag fails before RunE and still prints
the usage.
#1782
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
One finding for the debugger fixes: the /debugger/ endpoint reports the outcome in the reply envelope under HTTP 200, a status-code-only client hid three malformed requests behind it, and the stub has to answer the runtime's way for the tests to mean anything. Also records the two poll_events traps measured but not fixed: the ~25 s long poll, and an event lost to an abandoned poll, which rules out a short client timeout as the fix for the wait. #1782, mendixlabs#1676 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
An incremental source rebuild compared an entity through its module's domain model unit, so one new attribute re-described every entity of the module and every document that used any of them. On a 4,753-unit app, adding an attribute to an unreferenced entity in a 154-entity module re-described 346 documents. An entity's describe reads only its own subtree, so that subtree (with its domain model's ID) is now its basis, and the rest of the domain model is a parent whose change still re-describes the module. The same edit now re-describes 1 document; a heavily referenced entity re-describes itself and its 69 users. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82ttaGzay5CwiC2V7cf
A catalog refresh read every .mxunit of an MPR v2 project after every save: 4,753 file opens on a large app, each one scanned on Windows, where users measured the scanner as the bulk of their wait. The reader now keeps a zstd-compressed copy of the units in .mxcli/cache/unit-contents.db and serves a unit from it while the file's size and modification time (stat'ed before the read) and the Unit row's ContentsHash are what they were when it was stored. Misses are recorded and written at the end of a full pass and on Close; units the project no longer has are dropped. The store's directory carries its own .gitignore, because .mxcli/ is not ignored in every project. On the test fixture the next process's refresh reads 0 of 369 unit files (1 after a file changes) and builds a row-identical catalog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82ttaGzay5CwiC2V7cf
Gate workflow microflow actions at check time; debug break, continue and inspect work against the runtime
…-source-reuse # Conflicts: # CHANGELOG.md
fix(catalog): base an entity's source reuse on its own subtree (#1803)
…catalog # Conflicts: # CHANGELOG.md
…g work debug enable said breakpoints and stepping "arrive in a later slice"; debug status and debug break said a paused flow waits for "'continue' (a later slice)". Both have worked since #1782. enable now names debug break, and status/break name debug continue. The package comments and the Timeout comment described slice 1; the Timeout comment now records why it must stay above poll_events' ~25 s long poll (#1812). The proposal's protocol table listed add_breakpoint's condition as optional and continue with {}; 11.13 and 11.15 refuse both. It now records the measured shapes and the status envelope. Closes #1813. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
fix(mpr): serve unchanged v2 units from one store file (#1804, part 1)
`mxcli playwright check http://frontend.local:8180/` (an /etc/hosts name for 127.0.0.1, the app's configured root URL) failed a page that rendered on two console errors: WebSocket connection to 'ws://frontend.local:8180/mxdevtools/' failed: Error during WebSocket handshake: Unexpected response code: 502 while the same check on 127.0.0.1 passed (#1800). Neither the runtime nor run --local returns the 502: the runtime answers the dev channel's handshake 101 on the configured name. It is the environment's HTTPS proxy. Chromium on Linux takes its proxy from the environment and sends ws:// to the HTTPS proxy (RFC 6455 4.1.3), so with only https_proxy set the page loaded directly while the WebSocket went to the proxy, which cannot reach this machine's loopback. no_proxy listed localhost and 127.0.0.1 but not the app's own name. The browser mxcli starts against an app (the page probe, the sign-in and sign-out scripts, the screenshot) now gets every host that resolves only to this machine (loopback, or an address of one of its interfaces) added to no_proxy and NO_PROXY. The proxy settings are untouched, so a remote URL still uses the proxy. No console error is ignored: the channel connects, and a genuine console error still fails the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
Explain in the playwright check reference and in the docker-workflow skill's mxdevtools section why a browser sends ws://<app-host>/mxdevtools/ to the HTTPS proxy when no_proxy lists only the loopback names, what the browser mxcli starts now does about it, and that a browser of one's own needs the name in no_proxy (#1800). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…er list A published entity set whose statement stated no mode was written without ReadMode, InsertMode, UpdateMode and DeleteMode, and an OData action whose microflow takes no parameters without Parameters. Studio Pro writes all five on every element, so on Mendix 11.14.0 `mxcli fix property-sets` reported them as MIXED (#1805): MIXED ODataPublish$EntitySet.ReadMode: on 42 of 60 element(s); without it: … MIXED ODataPublish$PublishedMicroflow.Parameters: on 2 of 5 element(s); only on: … and Mendix's merge engine refuses to compare a revision of such an element with one Studio Pro saved. An unstated mode is now written as the value Mendix gives the absent property, and a parameterless action as the empty marker-3 list. Measured with `mx convert -p -s` on 10.24.24, 11.13.0 and 11.15.0 (ReadSource, ChangeNotSupported, [3]); the 11.14.0 Studio Pro service in testdata/testapp-views carries the same. What the service does is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
… out On a Mendix 11.14.0 project mxcli wrote, `mxcli fix property-sets` reported five names on one domain model and left them (#1805): MIXED DomainModels$DateTimeAttributeType.LocalizeDate: on 15 of 16 element(s); without it: … [DomainModels$DomainModel] MIXED DomainModels$NoGeneralization.HasOwnerAttr: on 81 of 84 element(s); without it: … [DomainModels$DomainModel] (and HasChangedByAttr, HasChangedDateAttr, HasCreatedDateAttr) No writer of today leaves these out: a script through create, create or modify, add and modify attribute, association, alter, rename and move gives no such line on 10.24.24, 11.13.0 or 11.15.0. The elements were stored by an older mxcli, which wrote only the true system-attribute flags and no LocalizeDate, and a domain-model write passes the entities it does not name through as their stored bytes. The table had no row for the keys, since no measurement of today's writers saw one missing, so neither the next write nor the repair could fill them. Published OData services stored before the previous commit are in the same position for the entity-set modes and an action's Parameters. Ten rows, measured by stripping each key from Studio Pro- and mxcli-authored elements of a fresh app and letting `mx convert -p -s` write it back on 10.24.24, 11.13.0 and 11.15.0: the flags false, LocalizeDate true, ReadMode ReadSource, the change modes ChangeNotSupported, Parameters [3] — the same on all three, so since 10.24.24. Each is what Mendix reads the absent key as, so the model says what it said before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
One script through create, create or modify, add and modify attribute, association, an alter that rewrites a sibling, rename and move, and a published OData service whose entity sets state their modes and do not and whose actions take parameters and do not, created and then modified. Measured on fresh 11.13.0 and 11.15.0 apps: before the fix `fix property-sets --dry-run` reports ReadMode, InsertMode, UpdateMode, DeleteMode and Parameters as MIXED (also on 10.24.24); after it, "Every unit already has the property names Studio Pro writes", `mx convert -p -s` on a copy adds no key to any unit mxcli wrote, and `mx check` reports 0 errors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…ind one MIXED report Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…the full build For a Reference from an entity to itself (M.Order_Parent), the full build typed `retrieve $P from $Order/M.Order_Parent` as a list of M.Order unless an object use followed: the start variable is an instance of the TO entity too, so addRetrieveAction read it as a reverse traversal. Mendix follows a self-reference from its FROM end - the stored AssociationRetrieveSource has no direction - so `$n = count $P;` was written and failed the build with CE0013 "Input variable 'P' must be of type 'List'." (#1793, measured on 11.13.0; a change of $P builds). The direction is now one rule, associationRetrieveEnd: a start at both ends of a self-reference is the FROM end, a start at both ends of an association between two different entities is ambiguous, otherwise the end it is. addRetrieveAction and associationRetrieveType (the splice path, #1777) both ask it through associationRetrieveEndFrom, so the two can no longer type a retrieve differently; a test pins that they agree on every unambiguous shape. A self-reference is never a reverse traversal, so it never takes the owner-Both database fallback either. The ambiguous shape keeps the full build's old reading (the TO end), which is not measured. Control: with addRetrieveAction's direction reverted, the self-reference is typed "List of Sample.Node" after a count, a loop, or no use, from the entity and from a specialization, and the owner-Both self-reference becomes a DatabaseRetrieveSource; the agreement test reports the build and the splice disagreeing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…ve binds check --references judged a retrieve over an association in one direction only: a list used as one object (MDL-RETRIEVE03, mendixlabs#1516). The one object a Reference gives from its FROM end, used as a list, passed check and exec and failed the build - and associationRetrieveShape returned "not known" for a self-reference outright, so `retrieve $P from $Order/M.Order_Parent; $n = count $P;` was silent (#1793). associationRetrieveShape now decides the start end by associationRetrieveEnd, the rule the full build takes, so a self-reference is followed from its FROM end and a specialization of both ends of an association between two entities is left alone (it used to take the nearest link of the chain). The chain is read through the script's own entity declarations first, so a specialization the same script creates counts. The pass reports, as MDL-RETRIEVE01, that object taken by any aggregate (CE0013), any list operation but range (CE0097), a loop (CE0100) or a list parameter (CE0117) - each measured on 11.13.0 over a self-reference's object. range (Microflows$ListRange) and add/remove/clear/set (Change list) are not reported: mx check does not type their variable. A one-to-one from its TO end is not judged, because the full build rewrites a list use of it into a database retrieve. A forward Reference is the same rule and the same hole: `count` of it was CE0013 too. validateFlowBody's forwardReferenceTarget takes the same rule, so `set` on a self-reference's object is refused like `set` on any object (CE7247). The Change list Replace mxcli wrote for it passed mx check only because mx check does not type a Change list's variable (`add` to the object is clean too); CE0100's "'P' is of type M.Order" settles what Mendix types it as. Two bug-tests held shapes the rule now refuses: - 1323-set-object-variable.mdl item 2 set a self-reference Reference retrieve "typed as a LIST by Mendix"; it now shows the same over a self reference set, which is a list (11.13.0: 0 errors). - 1100-loop-variable-typing.mdl looped over a Reference retrieved from its FROM entity: exec'd as written it is CE0100 on 11.13.0. It now starts from the TO entity, which is the list the loop meant (0 errors). Control: with the source reverted to main, the 11 refused shapes and the script-declared specialization report nothing, the self reference set's member path is not reported, `set` on the self-reference is accepted, and the ambiguous-start control reports a CE7247 by a direction nobody measured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
The bug-test holds the shapes that build: a self-reference Reference retrieve used as the one object it is (change, a member path), from the entity and from a specialization of it, and a self reference set used as the list it is (loop, count). The refused shape is in the header comment. On a fresh 11.13.0 app, one microflow per shape: Before (main): check -p --references passed every list use of `retrieve $P from $Order/M.Order_Parent` and exec created them all; mx check then reported CE0013 for count, sum, average, minimum, maximum, all, any and reduce, CE0097 for head, tail, find, filter, sort, union, intersect, subtract, contains and equals, CE0100 for a loop, CE0117 for a list parameter, the same from an M.SpecialOrder, and CE0013 for count of a forward Reference. range, add, remove, clear and `set` over the object, the change of it, and the reference set's count and loop: 0 errors. After: check -p and exec's pre-flight refuse the eight list uses in the first measurement script as MDL-RETRIEVE01 (and `set` as CE7247), naming the CE code, with nothing written. The valid shapes (object uses from the entity and a specialization, the reference set's count, loop and set, a one-to-one counted from its TO end), this bug-test, and the rewritten 1323 and 1100 bug-tests pass check -p, exec, and mx check with 0 errors. describe -> exec of four of them (an unused and a changed self-reference retrieve, this bug-test's parent flow, 1323's ReplaceList) reports all four already in sync. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
One finding: four sites answered "which end does this association retrieve start from" (the full build, the splice, check's shape, validateFlowBody), and the full build's answer was wrong for a self-reference. The insight is the measurement: every aggregate is CE0013 and every list operation CE0097 over the object, but range and the Change list activities are not typed by mx check at all - which is how #1323's bug-test came to record a self-reference retrieve as a list - and CE0100's message naming the variable's type is the reading to trust. #1793, #1777, #1323 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
`workflows basic` said 9.0.0 while Workflows$Workflow is a 9.0.2 type (mendixmodelsdk 4.117.0), and only `alter workflow` applied it. On 9.0.0 or 9.0.1 `create workflow` and `create or modify workflow` passed `check -p`, and the write then refused them part-way through exec (canon.UndeclaredTypeError, #1774). The row is now 9.0.2, pinned to the type by TestTypeGates_FloorIsTheTypeIntroduction, and create, create or modify and alter workflow all apply it. `alter workflow`'s hint named 9.12, a version the gate never stood for; it names none now, as the message states the registry's floor. Fixes #1809. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…ir type floor send rest request, range, call external action, transform … with and find/filter by expression had no check-time gate, so `check -p` passed them and the write refused them part-way through exec (canon.UndeclaredTypeError, #1774). flowActionGates names each at its storage types' introduction in mendixmodelsdk 4.117.0, with the sub-shapes that add a later type: a send rest request's arguments (10.2), result variable (10.4) and body (10.5), and a call external action's arguments (10.2). It applies to create and alter of microflows and nanoflows alike. A find whose input the statement declares as a String is a String find(), not a list operation, and is not gated. The pin test now also takes the properties a gate's shape writes a value to, so a row is pinned to the later of a type and its holding property. Part of #1811. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…base queries Listing every $Type the converters construct against the Model SDK's type data found more flow activities the write refuses below their floor with no check-time gate: a loop over a list and a while loop (9.0.4, Microflows$IterableList / WhileLoopCondition), show page with arguments (9.7, Forms$PageParameterMapping), a call in a task queue (9.10, Queues$QueueSettings), execute database query (9.24) and its connection arguments (11.1). They join flowActionGates, the loops last so that an action inside one is the refusal named. The database query rows of sdk/versions said 10.6 and 11.0, floors nothing measured; they now hold the type floors, and mx 9.24.30 loads the action. The #1787 test's at-floor check now allows the loop's own refusal for a loop placement below 9.0.4. Part of #1811. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…floor Past the workflow document's own 9.0.2 (#1809), what a workflow states has later floors the write enforced and no gate named. Measured on 9.x projects whose recorded version was set below each floor, a workflow with a parameter is refused below 9.18 (Workflows$Parameter.Name) and a user task below 9.19 (Workflows$UserTaskOutcome.Value); a jump needs 9.0.5, a call workflow activity 9.6 (its parameter mappings 9.18), an overview page 9.11, an annotation 9.15 and an interrupting notification event sub-process 11.10. workflowShapeGates names each, pinned to the latest of the types and properties the shape writes, and create and alter workflow apply them. statementTypeGate carries a typeGate for a whole statement. The user task row said 9.0.0; it is 9.19.0. Part of #1811. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
… floor The sweep of converter types found document shapes written in a type or property newer than the project with no check-time gate: snippet parameters, alter page add parameters, page variables, the workflow button actions, menu item icons, progressive web app settings, a native profile's home page, a not-found page, JAR dependencies and their exclusions, scheduled event schedules, database connections and their queries, business event services, and a consumed REST service's basic authentication, operations, query parameters and OpenAPI document. documentTypeGates names each, pinned to the latest of the types and properties the shape writes; statementVersionGates adds them after the per-statement cases. A database connection is 10.0, and one with a query 10.12: measured on stamped projects, every query's QueryType is refused below that. create view entity was gated at 10.18, but the source document mxcli writes for the query is a 10.21 type, so on 10.18 to 10.20 check -p passed it and the write refused it. viewEntityGate is pinned at 10.21. The sdk/versions rows that disagreed with the write (database connector 10.6, business events 10.0, view entities 10.18) now hold its floor. The OpenAPI import tests ran on a 10.6 mock project, where the write refuses the stored OpenAPI document (measured on a stamped 10.6 and 10.20); they now run at its 10.21 floor. Part of #1811. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…wer type TestTypeGates_CoverEveryWrittenType lists every storage $Type the write paths construct (a "Module$Type" literal, or a modelsdk/gen constructor resolved to the type it stamps) and, for each introduced after 9.0.0, requires a type gate that names it, a broader gate whose floor is at or above it, or an entry in typeCoverageExceptions saying why no project below its floor reaches it (lowered, unreachable, or a RESIDUAL the statement cannot tell). A converter that starts writing a newer type fails here instead of passing check -p and being refused by the write. Entries that are no longer written fail too. allTypeGates is now the one list both this test and the floor pin read. Part of #1811. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
1811-actions-below-their-version.mdl holds the 9.x and 10.x shapes and 1811-mendix-11-shapes-below-their-version.mdl the 11.x ones. On 9.24.30, before, check -p passed the script (without the two statements main already gated) and exec refused the database connection at write time, and with --continue-on-error each 10.x statement; after, check -p and the pre-flight report MDL-VERSION01 for each and App.mpr is unchanged, while the 9.x-floor statements write and mx check reports 0 errors. On 10.24.24 the 10.x script writes everything with 0 errors, and the 11.x script is refused by check -p where before the write refused it. The finding records how the floors were measured without an old mxbuild: a newer app with its recorded version stamped down. Part of #1811. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
…cate-resolver-drift The version-floor variant came back twice more (#1809, #1811). Record that the sweep is now a test over the written types, that a shape's floor is the latest of its types and the properties it fills, how to measure it with a stamped project, and that mx check is no witness for a newer property. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011oK82sUVQEB3K5W5vh85wM
Check-time gates for every write floor; self-reference retrieves; OData property sets; playwright behind a proxy; debug text
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs
ako/mxcli:maininto upstream: 1 commit from fork PR ako#1802.Refs #1081 and #1329.
Incremental source-catalog rebuilds
Problem: once a project had a source index (
refresh catalog full source), every later rebuild described every document again. That included the implicit rebuilds thatsearchandshow referencesstart after every save. On a 4,753-unit app that took 38 s each time.This follows from #1081's never-narrow guard: the cheapest rebuild that can still be saved is the most expensive one.
Fix: a source build now records what it described from:
source_units: every unit's content hash and container;source_elements: which document came from which unit;The next build carries a document's row over only when all of these hold:
FORCEstill describes everything. Anything the plan can't vouch for is described again, so reuse can make a build faster but can't change its result.Other details:
Reader.UnitContentHashesreads v2 hashes from the Unit table, and computes v1 hashes from the blob, because older v1 writes left them stale.Evidence
TestSourceCatalog_IncrementalBuildEqualsFullBuildcompares the incremental build with a forced full build, row for row, after each of these:alter entity … add attribute, a plainrefresh catalogtakes 11.2 s instead of 38.2 s, reusing 3,525 of 3,718 rows. The result is byte-identical to a forced full rebuild.docs-site/src/tools/refresh-catalog.mdexplains the incremental rebuild and whatFORCEdoes