intent: a status NAME in the items rule of a cross-model source is refused, not left unresolved (#7225) - #7300
Merged
Conversation
…fused, not left unresolved (#7225) A create-from's `items: where:` may name the item's status by its seeded name (#7164). When the source is cross-model (`fromUses:`) the item's nomenclature is seeded in the owner model, so the parser's resolver could not rewrite the name - and returned silently, leaving `.eq("Status", "APPROVED")` in the generated query: a rule that matched nothing on every click. Worse, a LOCAL entity sharing the item's name lent its own nomenclature to the rewrite, an id positional in the wrong seed list. The resolver now leaves a cross-model source's items rule alone entirely, and GlueIntentGenerator - the one place the owner .model tells WHICH condition names the status (its DOCUMENT_STATUS property) - refuses a non-numeric value there with the message every other cross-model status site gives: a cross-model status must be referenced by its numeric seed id. The item source is resolved once instead of twice. The refuse:/guard/check literal escaping half of the issue was already shipped by #7241 (#7262) and is not touched here. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Cause
items: where:may name the item's status by its seeded name (#7164). With a cross-model source (fromUses:) the item's nomenclature is seeded in the owner model, soStatusSymbolResolver.rewriteGeneratesItemsWherecould not resolve it and returned silently -{ field: Status, value: APPROVED }rendered as.eq("Status", "APPROVED"), a rule that matched nothing on every click, with no diagnostic. A second defect sat behind it: the resolver looked the item entity up by NAME among the LOCAL entities, so a local entity that merely shares the cross-model item's name lent its own nomenclature to the rewrite - an id positional in the wrong seed list.Change
StatusSymbolResolver: a create-from withfromUses:leaves its items rule alone entirely (no local lookup by a foreign entity's name). Which condition names the status is knowable only from the owner.model, so the refusal lives where that model is read.GlueIntentGenerator: the cross-model item source is resolved once (it was resolved twice for perspective and key), and awherecondition on itsstatusProperty(the owner.model'sDOCUMENT_STATUSproperty) whose value is not a whole number is refused with the message every other cross-model status site gives: a cross-model status must be referenced by its numeric seed id. Mirrors thesourceStatusrefusal a few lines above in the same block. With no owner model (the convention fallback) or an owner entity declaring no status, nothing is checked, as before.IntentParser: javadoc only - the items-rule validation notes that a cross-model source's items are checked at generation time.Not touched: the second half of the issue (
refuse:/ guard / check messages rendered into Java literals unescaped) was already fixed by #7241 via #7262 -itemRefuseJavaLiteral,guard.messageJavaLiteralandcheck.messageJavaLiteralare what the templates render on master.Out of scope: the same silent shape in a cross-model
schedules[].whereis #7288; theTargetInfo.statusProperty()check introduced here is reusable there.Verification
StatusSymbolIntentTest.aCrossModelItemSourceIsNotResolvedAgainstASameNamedLocalEntity(the local same-named entity's seed id is NOT taken);GlueGeneratesItemsWhereTest× 3 against a mocked owner.modelcarrying aDOCUMENT_STATUSproperty - a name is refused naming the relation, the name and the owner model; a seed id renders.eq("Status", 3)with the perspective and key read off the owner model; a string on an ordinary column is not treated as a status.mvn -pl components/engine/engine-intent test: 1204 tests, 0 failures.formatter:validateon the module with the cache wiped: unchanged.Fixes #7225
🤖 Generated with Claude Code