memo_core_relationships¶
| Public namespace | memo::core::relationships |
| Declared package | memo_core_relationships |
| Source | src/core/relationships/memo_relationships.sysml |
Namespace hierarchy¶
memo → memo::core → memo::core::relationships
Packages¶
| Package |
|---|
memo_core_relationships |
Imports¶
| Visibility | Target |
|---|---|
| private | Metaobjects::SemanticMetadata |
| private | ScalarValues::* |
| private | Connections::BinaryConnection |
| private | memo_core_common::* |
| private | memo_core_enumerations::* |
| private | Allocations::Allocation |
Declarations¶
| Name | SysML kind | Description | Specializes |
|---|---|---|---|
MemoRelationship |
connection def |
Typed relationship for memo relationship. | Connections::BinaryConnection |
MemoTypedDependency |
metadata def |
A link whose ends are not both usages cannot be a connection def: a connection joins features, and a ref cannot point at a definition.… |
— |
ScopedTo |
connection def |
Typed relationship from any element to MemoPart. |
MemoRelationship |
DerivesFrom |
connection def |
Typed relationship from any element to MemoRequirementElement. |
MemoRelationship |
ProducesEvidence |
connection def |
Typed relationship from MemoVerificationCase to MemoEvidence. |
MemoRelationship |
DerivesCyberRequirement |
connection def |
Typed relationship from RequirementDriver to MemoRequirementElement. |
MemoRelationship |
CrossesTrustBoundary |
connection def |
Typed relationship from any element to any element. |
MemoRelationship |
Validates |
connection def |
Typed relationship from any element to MemoVerificationCase. |
MemoRelationship |
HostedBy |
allocation def |
A processing node hosted by an assembly is allocated to it. The end NAMES were already right; two of the three usages wrote them in reverse order, and the builder binds by position, so those two edges pointed the wrong way. See the reversed-end-name lint in memo-tools. | MemoRelationship |
BindsToInterface |
connection def |
Typed relationship from any element to any element. |
MemoRelationship |
MemoRelationship¶
abstract connection def MemoRelationship :> Connections::BinaryConnection| Property | Value |
|---|---|
| Description | Typed relationship for memo relationship. |
| Kind | connection def |
| Abstract | Yes |
| Specializes | Connections::BinaryConnection |
| Owning package | memo_core_relationships |
MemoTypedDependency¶
abstract metadata def MemoTypedDependency| Property | Value |
|---|---|
| Description | A link whose ends are not both usages cannot be a connection def: a connection joins features, and a ref cannot point at a definition.… |
| Kind | metadata def |
| Abstract | Yes |
| Specializes | — |
| Owning package | memo_core_relationships |
ScopedTo¶
connection def ScopedTo :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from any element to MemoPart. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
DerivesFrom¶
connection def DerivesFrom :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from any element to MemoRequirementElement. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
ProducesEvidence¶
connection def ProducesEvidence :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from MemoVerificationCase to MemoEvidence. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
DerivesCyberRequirement¶
connection def DerivesCyberRequirement :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from RequirementDriver to MemoRequirementElement. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
CrossesTrustBoundary¶
connection def CrossesTrustBoundary :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from any element to any element. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
Validates¶
connection def Validates :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from any element to MemoVerificationCase. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
HostedBy¶
allocation def HostedBy :> MemoRelationship, Allocations::Allocation| Property | Value |
|---|---|
| Description | A processing node hosted by an assembly is allocated to it. The end NAMES were already right; two of the three usages wrote them in reverse order, and the builder binds by position, so those two edges pointed the wrong way. See the reversed-end-name lint in memo-tools. |
| Kind | allocation def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
BindsToInterface¶
connection def BindsToInterface :> MemoRelationship| Property | Value |
|---|---|
| Description | Typed relationship from any element to any element. |
| Kind | connection def |
| Abstract | No |
| Specializes | MemoRelationship |
| Owning package | memo_core_relationships |
Source¶
core/relationships/memo_relationships.sysml
package memo_core_relationships {
private import Metaobjects::SemanticMetadata;
private import ScalarValues::*;
private import Connections::BinaryConnection;
private import memo_core_common::*;
private import memo_core_enumerations::*;
private import Allocations::Allocation;
// All MEMO relations are native SysML v2 `connection def`s (each is a
// Connection/Association), specializing the MemoRelationship base. The
// relationship name is the verb; the RelationshipRegistry derives the
// navigable type as camelCase(name) and navigation is bidirectional.
//
// MemoRelationship roots on the SysML v2 standard library's
// Connections::BinaryConnection rather than floating free. Every two-ended
// `connection def` implicitly specializes it anyway; saying so explicitly
// is what lets MEMO relations be read as ordinary SysML connections by any
// conforming tool instead of as a MEMO-private construct.
//
// A relation is a MEMO element like any other, so it carries the same
// identification core as the part/action/item/requirement bases in
// memo_core_common — with four exceptions, R10-S5 (2026-08-13). `name`,
// `description`, `rationale` and `status` were declared here too, and a
// tree measurement found them dead weight: across every connection usage
// in src/ and examples/ (876 of them, 77 with a body at all), exactly one
// ever set `rationale` and none ever set `name`, `description` or
// `status`. The former `linkStatus` (planned/active/verified/obsolete) is
// already gone for the same reason: a link being "verified" was never an
// editorial state.
//
// The replacement is native, not a MEMO-authored substitute:
// - `name` → the connection usage's own declared name
// (`connection linkFoo : Bar …`), which every usage already has.
// - `description` → `doc /* … */` on the usage.
// - `rationale` → standard `Rationale` metadata: `@Rationale { :>> text
// = "…"; }` (ModelingMetadata.sysml:95). `text` is exported into
// `rel.attributes.rationale` by the builder, same key as before.
// - `status` → standard `StatusInfo` metadata: `@StatusInfo { :>>
// status = StatusKind::…; }` (ModelingMetadata.sysml:60). StatusKind
// (open/tbd/tbr/tbc/done/closed) is NOT ElementStatusKind
// (proposed/draft/inReview/approved/released/deprecated/retired) — the
// mapping between them, and why no MEMO-side conversion code exists, is
// recorded in docs/reference/naming-and-native-constructs.md. Exported
// into `rel.attributes.status`.
// Both metadata defs live in the standard `ModelingMetadata` package;
// `private import ModelingMetadata::*;` wherever they are applied.
//
// isReflexive/isUnique are structural properties of the relation itself,
// declared here so authoring and validation read them from the ontology
// instead of assuming them. Both are unset on the base and carry the
// conservative reading: a relation forbids self-links and forbids repeats
// unless it says otherwise. A subtype opts out by redefining, e.g.
// `attribute :>> isReflexive = true;`.
abstract connection def MemoRelationship :> Connections::BinaryConnection {
attribute id : String;
attribute uuid : String;
attribute shortDescription : String;
attribute sourceReference : String;
doc /* True when an element may be related to itself by this relation.
* Unset is read as false. */
attribute isReflexive : Boolean;
doc /* True when at most one link of this type may join the same ordered
* pair of elements — KerML Feature::isUnique over the relation.
* Unset is read as true. */
attribute isUnique : Boolean;
doc /* True when this relation is a connector between two parts, the kind of link that makes a part
* count as wired in an internal block diagram (rule AR-IBD-001). Trace, allocation, deployment and
* satisfaction links are not. Unset is read as false. Interface and flow usages are connectors by
* their language construct and need no value. */
attribute isConnector : Boolean;
}
// ─── Typed dependencies ─────────────────────────────────────────────
//
// A link whose ends are not both usages cannot be a `connection def`: a
// connection joins features, and a `ref` cannot point at a definition. SysML
// already has the construct for a client and a supplier that are any element,
// the Dependency (SysML-textual-bnf.kebnf:51-59), and a metadata prefix
// names what kind of dependency it is (`#RealizesFeature dependency from a to
// b;`, PrefixMetadataAnnotation, kebnf:52). A `metadata def` that specializes
// this marker declares such a link as a MEMO relation: it joins the
// relationship registry under camelCase(name), is navigated like any other
// relation, and needs a row in the workspace-membership table. A metadata
// def that does not specialize it (`EnforcesClause`) is plain metadata on a
// dependency and builds no relation. Source is the client, target the
// supplier. Ends are untyped: what a relation may join is a rule's to say
// (see the note above on metaclass-neutral ends).
abstract metadata def MemoTypedDependency;
// ─── Metaclass-neutral ends (Track A0) ──────────────────────────────
//
// An end is left UNTYPED (`:>> source` / `:>> target`) wherever its
// legitimate endpoints do not share a MEMO base, and a rule in
// memo_rules_ontology states the constraint the type used to state.
//
// The reason is structural, not stylistic. KerML will not let a port or a
// behaviour specialize a part-based type, so a `MemoPart`-typed end forces
// everything it accepts to be a part. That is what made PhysicalPort and
// SoftwarePort part defs (so they could terminate exchanges), what made
// SystemFunction a part def with its behaviour stapled on through a
// separate action def, and what makes `allocate <function> to <actor>` —
// ARCADIA's own System Analysis mechanism — illegal, since Actor is a
// MemoPart but not a narrower part subtype.
//
// Several of the relaxed ends were ALREADY being violated by real content
// before they were relaxed: `composes` links parts to OperativeAction
// (an action def) and to SoftwarePort/PhysicalPort;
// `precedes` links OperativeAction to OperativeAction; `allocatedTo`
// has ActionUsage sources; `bindsToInterface` targets an `interface def`,
// which an InterfaceElement-typed end cannot hold. The types were not
// buying the strictness they appeared to buy.
//
// What is NOT relaxed stays typed on purpose: `verificationCase` and
// `validationCase` are verification defs, `performed` and `enabled` are
// MemoActions, `targetRequirement` is a MemoRequirementElement. Those ends
// name one metaclass and mean it.
//
// The strictness did not evaporate — see CR-ONT-060..CR-ONT-071 in
// src/rules/ontology/ontology_invariants.sysml. Relaxing the ends without
// those rules would have been a silent loss of every constraint the ends
// were carrying.
//
// The general relation that can join any two model elements, whatever
// their metaclass. MemoLink leaves both ends untyped and adds no
// domain-specific semantics, which is what makes it universal.
//
// It is deliberately the weakest relation in the ontology. Reach for it
// only when no specific relation carries the meaning, and say why in the
// inherited `rationale` — an untyped link with no stated reason is an
// audit gap, not a model fact.
// An item belongs to the scope of one system or system of systems: a need,
// requirement, risk or verification case that describes, constrains or
// assesses that system and is its to deliver or verify. Imported records
// arrive with no design element to anchor them (a requirement is not
// allocated to anything yet), so this is how an import says whose they are;
// without it they are Unassigned in every workspace. The target is the
// system, typed as a part (a System and a SystemOfSystems both are). The
// source stays untyped: the items span metaclasses (a need is a requirement
// def, a risk an item, a verification case an action), as for DerivesFrom.
connection def ScopedTo :> MemoRelationship {
end scopedItem :>> source;
end scopeSystem : MemoPart :>> target;
}
abstract connection scopedToLinks : ScopedTo[*];
metadata def <scopedTo> ScopedToMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = scopedToLinks meta SysML::Usage;
}
connection def DerivesFrom :> MemoRelationship {
// Drivers span metaclasses — a need is a requirement def, a hazard an
// item, a threat an item — so the source end stays untyped. The target
// is now typed: since Requirement re-rooted onto MemoRequirement, one
// type name covers the whole requirement family.
end sourceDriver :>> source;
end targetRequirement : MemoRequirementElement :>> target;
}
abstract connection derivesFromLinks : DerivesFrom[*];
metadata def <derivesFrom> DerivesFromMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = derivesFromLinks meta SysML::Usage;
}
// `Realizes` (realizing/concrete element → realized/abstract element) is
// native `#refinement dependency` (R10-S6): write
// `#refinement dependency <realizing> to <realized>;` instead. It used to
// unify RealizesInterface, RealizesComponentExchange,
// RealizedByArchitecture, RealizesScenario, ModuleRealizesLogical,
// ComponentRealizesModule, PhysicalModuleRealizesLogical,
// Implements{Component,Procedure}, UIRealizesFunctional,
// FunctionalRealizesOper{ative,ational} and ScenarioRealizesUseCase; the
// native form keeps that reach, since `#refinement` places no metaclass
// restriction on either end.
connection def ProducesEvidence :> MemoRelationship {
end producer : MemoVerificationCase :>> source;
end producedEvidence : MemoEvidence :>> target;
}
abstract connection producesEvidenceLinks : ProducesEvidence[*];
metadata def <producesEvidence> ProducesEvidenceMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = producesEvidenceLinks meta SysML::Usage;
}
// `Precedes` is native `succession` (`first a then b;`), R10-S6.
// `sameStepRequired`/`precedenceRationale` had zero usages anywhere in
// the tree (same free-deletion shape R10-S5 found for `rationale`), so
// there was no content to carry forward.
connection def DerivesCyberRequirement :> MemoRelationship {
end sourceThreatOrRisk : RequirementDriver :>> source;
end targetRequirement : MemoRequirementElement :>> target;
}
abstract connection derivesCyberRequirementLinks : DerivesCyberRequirement[*];
metadata def <derivesCyberRequirement> DerivesCyberRequirementMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = derivesCyberRequirementLinks meta SysML::Usage;
}
connection def CrossesTrustBoundary :> MemoRelationship {
attribute crossingKind : InterfaceKind;
end boundary :>> source;
end crossingItem :>> target;
}
abstract connection crossesTrustBoundaryLinks : CrossesTrustBoundary[*];
metadata def <crossesTrustBoundary> CrossesTrustBoundaryMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = crossesTrustBoundaryLinks meta SysML::Usage;
}
connection def Validates :> MemoRelationship {
// Validation targets include use cases and other behavioural elements,
// so the target remains untyped across SysML metaclass families.
end validationTarget :>> source;
end validationCase : MemoVerificationCase :>> target;
}
abstract connection validatesLinks : Validates[*];
metadata def <validates> ValidatesMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = validatesLinks meta SysML::Usage;
}
// Enables unifies the former EnablesWorkflow / EnablesActivity synonyms
// (an enabling system/function enables a workflow/activity).
// `Enables` is native `dependency` (2026-08-18): write
// `dependency from <enabling> to <enabled>;`. Same call as `Supports`,
// which was deleted as a duplicate of both `dependency` and `Enables`.
// A processing node hosted by an assembly is allocated to it. The end
// NAMES were already right; two of the three usages wrote them in reverse
// order, and the builder binds by position, so those two edges pointed the
// wrong way. See the reversed-end-name lint in memo-tools.
allocation def HostedBy :> MemoRelationship, Allocations::Allocation {
end processingNode : MemoPart :>> source;
end hostAssembly : MemoPart :>> target;
}
abstract connection hostedByLinks : HostedBy[*];
metadata def <hostedBy> HostedByMetadata :> SemanticMetadata {
:> annotatedElement : SysML::AllocationDefinition;
:> annotatedElement : SysML::AllocationUsage;
:>> baseType = hostedByLinks meta SysML::Usage;
}
// `Composes` is deleted (R10-S7). Containment is NESTING — the child is
// declared inside the parent — which is how SysML v2 models composition:
// composite feature ownership, not a link. The relation specialized
// `Connections::BinaryConnection`, "a link between two things WITHIN some
// containing structure", so it was the wrong category for the containment
// itself, and the corpus has no composition connection to specialize.
//
// Nothing is lost: the builder synthesizes a `composes` edge from every
// nested part and item, so rules, the DSM and traceability read exactly the
// graph they read before. The edge type is registered natively in
// memo-tools' relationship registry.
connection def BindsToInterface :> MemoRelationship {
end portElement :>> source;
end boundInterface :>> target;
}
abstract connection bindsToInterfaceLinks : BindsToInterface[*];
metadata def <bindsToInterface> BindsToInterfaceMetadata :> SemanticMetadata {
:> annotatedElement : SysML::ConnectionDefinition;
:> annotatedElement : SysML::ConnectionUsage;
:>> baseType = bindsToInterfaceLinks meta SysML::Usage;
}
}