Skip to content

intent: a check's when and a visibleWhen resolve a seeded name on any to-one relation (#8057) - #8059

Merged
iliyan-velichkov merged 1 commit into
masterfrom
issue-8057-relation-names-checks-visiblewhen
Oct 22, 2026
Merged

iliyan-velichkov merged 1 commit into
masterfrom
issue-8057-relation-names-checks-visiblewhen

Conversation

@iliyan-velichkov

Copy link
Copy Markdown
Contributor

Cause

#8015 made a seeded name resolve on any to-one relation in a process trigger.when and a where condition. Two record-scoped sites still resolved a name only on the function: EntityStatus relation: a check's when (requiredWhen, forbidWhen) and a field's or a composition child's visibleWhen. So type == CLOSE was refused with "compares [type], a [integer], with [CLOSE], which is not a value of that type", and a model had to write the positional seed id (type == 2). A seed inserted mid-nomenclature then silently retargets that id.

Change

StatusSymbolResolver runs those conditions through one record-scoped pass (rewriteRecordWhen / rewriteRecordTerm):

  • first the record's own status, as before, then every other to-one relation, each against its own target's nomenclature, through intent: resolve seeded names on any to-one relation in a process trigger's when and a schedule's where #8015's rewriteRelationComparisons;
  • scalar and list forms alike;
  • a forbidWhen / requiredWhen one-hop Relation.Status term keeps its existing hop-aware resolution, and only the record-local terms take the new pass;
  • an entity-level visibleWhen on a composition child resolves against its master's relations, as its status terms already did.

The relation is matched the way the parser's guard validator reads the property (CheckSupport.toOne: case-insensitive, to-one only), so Type == CLOSE resolves too. Decisions and trigger guards keep their exact-name lookup and do not change.

#8015's rules are unchanged:

  • equality only: an ordering operator against a name is refused;
  • an unknown name is refused, naming the site and the nomenclature;
  • a cross-model target is refused with the numeric-id fallback message;
  • numeric ids, fields and null tests are left alone.

The class Javadoc and intent-assistant-guide.md now list the new sites.

Verification

  • RelationSymbolIntentTest: 10 new cases covering both check kinds in both forms, the typed check term (FK compared with 2), case-insensitive naming, a field's and a child's visibleWhen, an unknown or ordered name at each new site, a cross-model target, and numeric ids/fields left alone. Run against the unfixed resolver, all fail except the numeric-ids control.
  • EdmVisibleWhenTest: the .model scalar is Type == 2.
  • Full engine-intent unit suite: 1786 green.
  • New IntentRelationNameConditionsIT, which generates and publishes the issue's model:
    • the generated form's x-show compares String(form.Type)) === '2';
    • the attachment panel registers visibleWhen: [{ property: 'Type', equal: true, value: '2' }];
    • the running controller refuses a CLOSE without a note and a note on an OPEN with the declared messages, and accepts the valid pair.
  • IntentForbidWhenVerbsIT, IntentEmissionCoverageIT, IntentEngineIT: green.
  • mvn -T 1C formatter:validate with the formatter cache wiped: green.

Not run: the release-profile Javadoc build. The Javadoc changes are on a package-private class and private methods only. Also not run: the full IT suite or the PostgreSQL leg.

Out of scope, as the issue says: the other record-scoped when sites (notifications, generates, postings, wait), and the docs-site/spec text.

Fixes #8057

🤖 Generated with Claude Code

… to-one relation (#8057)

#8015 made a seeded name resolve on any to-one relation in a trigger guard
and a where condition, but a check's `when` (requiredWhen, forbidWhen) and a
field's or a composition child's `visibleWhen` still resolved a name only on
the `function: EntityStatus` relation. `type == CLOSE` was refused as "not a
value of that type", so a model had to compare the positional seed id, which
a seed inserted mid-nomenclature silently retargets.

StatusSymbolResolver now rewrites those conditions through one record-scoped
pass: the record's own status first, then every other to-one relation against
its own target's nomenclature. A forbidWhen/requiredWhen one-hop
`Relation.Status` term keeps its hop-aware resolution, and a child's
visibleWhen resolves against its master's relations. The relation is matched
as the guard validator reads the property (CheckSupport.toOne: case-insensitive,
to-one only). #8015's rules are unchanged: equality only, an unknown name or a
cross-model target refused naming the site, numeric ids and fields untouched.
Decisions and trigger guards keep their exact-name lookup.

Verified: RelationSymbolIntentTest (10 new cases, red without the fix) and
EdmVisibleWhenTest; the full engine-intent unit suite (1786); the new
IntentRelationNameConditionsIT (generated form/panel gates compare the CLOSE
seed id, the published controller refuses a CLOSE without a note and a note on
an OPEN with the declared messages); IntentForbidWhenVerbsIT,
IntentEmissionCoverageIT, IntentEngineIT; formatter:validate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@iliyan-velichkov
iliyan-velichkov merged commit ed907f3 into master Oct 22, 2026
16 checks passed
@iliyan-velichkov
iliyan-velichkov deleted the issue-8057-relation-names-checks-visiblewhen branch October 22, 2026 15:16
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.

intent: resolve seeded names on any to-one relation in a check's when and a field's visibleWhen (type == CLOSE)

1 participant