ADR007 RelatesEndpointDimensionPairs
Title: Relates endpoint dimension pairs
- Status: Accepted
- Decided: D2026-08-27
- Revises: ADR003
EndpointDimensionPairs - Revised by: ADR024
RelatesTargetsInPair - Affects:
Dimension,Parser,Relates,Relationship - Pairings:
Context
ADR 003 taught the compiler to look an authored edge up on both endpoint
dimensions. That is how ApplicationName can write isRepresentedBy { App }
when abbreviation declared the pair and application did not.
A relates body can name the same edges, but ADR 003 left relates unchanged.
A pairing has no dimension of its own, and its two endpoints may belong to
different ones, so that release had no subject to resolve from. The lookup
walked the target concept, then ancestors, then the relates' parent chain. It
never asked either endpoint's dimension.
This failed with SP015 whenever the pair lived only on a dimension:
dimension example {
relationship shouldWork { }
}
example ExampleName { }
concept ConceptName { }
relates ConceptName and ExampleName {
relationships {
shouldWork { ExampleName }
}
}
The same sentence written on ConceptName already compiled. The relates form
is the one that can carry a pair describe, so authors who needed that sentence
could not use the vocabulary the dimension had already declared.
Decision
A relates relationship name uses the same pair lookup as a concept assertion.
The endpoint that is not to is the subject. to is the target. Look the edge
up on both of those resolved dimensions, then the existing ancestor fallback.
relates A and BwithshouldWork { B }is A asserting toward B.relates B and AwithshouldWork { B }is still A asserting toward B. Clause order does not pick the subject.- A
tothat names neither endpoint treats left as subject so the target dimension is still consulted. - Conflicting inverses on the two endpoint dimensions are SP023, as in ADR 003.
to still resolves from the relates declaration's parent. Nested target names
do not start resolving from the subject's parents.
Consequences
Authoring. A relates may use a pair declared on either endpoint's
dimension. The example above compiles. The inverse shouldWork { ConceptName }
compiles too, because the subject is then ExampleName.
Cost. A relates that used to bind an ancestor definition will now SP023 if the two endpoint dimensions define that edge with different inverses. That is the same cost ADR 003 accepted for concepts.
What this does not do. It does not give a relates a dimension of its own.
It does not search ancestor dimensions beyond each endpoint's resolved
dimension. It does not change how to is resolved.
Alternatives considered
Keep the relates-only walk. Rejected. The dimension already declared the
vocabulary; failing SP015 on the form that can carry describe is the wrong
error.
Left endpoint is always the subject. Rejected. relates A and B is an
unordered pairing. Making left win would make clause order load-bearing.
Always consult both pairing dimensions, even when to is a third name.
Rejected as more than the concept rule. When to is one of the two endpoints,
both pairing dimensions are already the subject and target. When it is not,
the concept analog is left plus to.
Evidence
The universe in examples/relates-uses-dimension compiled as a concept
assertion and failed SP015 as a relates. ADR 003 skipped this case to keep
that release small, and because a subject had not been chosen. The subject is
now the other endpoint.