/** * A typed relationship as the registry reports it. * * Derived from the ontology's `connection def` declarations. The YAML * `relationshipTypes:` block that used to declare these is gone. */ export interface RelationshipType { /** Relationship identifier, e.g. "mitigates" */ name: string; /** Human-readable label, e.g. "Mitigates" */ label: string; /** Architecture layer this relationship belongs to */ layer: string; /** Hex colour for relationship visualization */ color: string; } import type { ParsedDocument } from './parser-utils.js'; import type { MultiplicityDTO, RelationshipDefinitionDTO } from './relationship-legality.js'; /** One `end` declaration on a connection definition */ export interface RelationshipEnd { name: string; type?: string; /** Declared multiplicity, e.g. `end owner : Requirement [0..1];` */ multiplicity?: MultiplicityDTO; } /** Entry in the RelationshipRegistry */ export interface RelationshipRegistryEntry { /** Relationship name in PascalCase as defined in SysML (e.g. "Mitigates") */ sysmlName: string; /** Normalized camelCase name for matching (e.g. "mitigates") */ name: string; /** Human-readable label */ label: string; /** Architecture layer derived from directory path */ layer: string; /** Doc comment on the connection definition */ description?: string; /** Abstract definitions (e.g. MemoRelationship) are not instantiable */ isAbstract?: boolean; /** * Whether an element may be related to itself by this relation, from the * `isReflexive` attribute. Undefined when the ontology does not say. */ isReflexive?: boolean; /** * Whether the same ordered pair may be linked more than once, from the * `isUnique` attribute. Undefined when the ontology does not say. */ isUnique?: boolean; /** Supertype connection definition, when the relationship specializes one */ superType?: string; /** * The construct the relation is declared with — `connection def` or * `allocation def`. Both produce links and both live in this registry, but * they are not interchangeable to a reader: an allocation def carries the * standard's allocation semantics and serializes with `allocate`. The * keyword-collision lint also needs it, since a name that agrees with its * own construct is not a reinvention of the keyword. */ sysmlConstruct?: string; /** * The SysML v2 keyword that writes this relation natively, when the language * already provides one — `satisfy`, `verify`, `allocate`. A relation with a * keyword is a *usage*, not a `connection def` instance: it must never be * serialized as `connection : X connect a to b`, whatever the ontology * happens to still declare alongside it. */ nativeKeyword?: string; /** End names from the connection definition */ ends: RelationshipEnd[]; /** * Attribute names declared on the connection definition, e.g. * `sectionReference` on `TracesToDocument`. Inherited attributes are not * folded in — walk `superType` for those. Absent on a manually registered * entry, which is not the same as "declares none". */ attributes?: string[]; } /** * The relations SysML v2 already writes with a keyword, and the MEMO trace edge * each one produces. * * The end names and types mirror `memo_core_relationships`' `SatisfiedBy`, * `VerifiedBy`, and `AllocatedTo`, because both spellings must produce the same * graph — a model that says `satisfy r by p;` and one that says * `connection : SatisfiedBy connect requiredElement ::> r to satisfyingElement * ::> p;` are the same statement, and nothing downstream should be able to tell * them apart. * * The ends that the ontology relaxed are relaxed here too, and for the same * reason (ARCADIA plan Track A0): a part-typed end cannot admit a port, a * behaviour, or an actor, and MEMO needs all three. The strictness did not move * into this table — it moved to CR-ONT-060..073 in the ontology's own rules, * where it can be stated across metaclasses. Re-tightening these ends would * silently re-impose the constraint A0 removed, on the day the connection defs * are retired and this table stops being a fallback. */ export declare const LANGUAGE_NATIVE_RELATIONS: Record; /** * The metadata that makes a `dependency` a refinement, and the keyword that * introduces it (`Domain Libraries/Metadata/ModelingMetadata.sysml:132`). * * A bare `dependency a to b;` is an unclassified dependency and means less than * `Realizes` does; only the annotated form carries realization. Naming it once * here keeps the builder, the serializer, and the tests reading the same word. */ export declare const REFINEMENT_METADATA = "refinement"; /** * Convert PascalCase to camelCase. * "Mitigates" → "mitigates", "TraceTo" → "traceTo", "HasSubProcedure" → "hasSubProcedure" */ export declare function pascalToCamelCase(name: string): string; /** * Registry that discovers relationship types from SysML AST ConnectionDefinition nodes. * Replaces config.relationshipTypes lookups in the builder. */ export declare class RelationshipRegistry { private readonly relTypes; /** Number of registered relationship types */ get size(): number; /** * Look up a relationship type by camelCase name. * Returns undefined if not registered. */ getRelType(name: string): RelationshipRegistryEntry | undefined; /** * Convert a registry entry to a RelationshipType (for backward compat). * Uses empty string for color since SysML doesn't define colors — * colors come from memo.rendering.yaml. */ toRelationshipType(name: string): RelationshipType | undefined; /** * Get all registered relationship types as RelationshipType[], * matching the shape of config.relationshipTypes for backward compatibility. */ toRelationshipTypesArray(): RelationshipType[]; /** Check if a relationship type is registered */ has(name: string): boolean; /** Get all relationship type names (camelCase) */ relTypeNames(): string[]; /** Get all entries */ entries(): RelationshipRegistryEntry[]; /** * Project the registry into serializable definitions for the web client. * The first declared end becomes the source, the second the target; a * definition with fewer than two ends still yields a definition with the * missing end untyped, so it accepts any kind rather than disappearing. */ toDefinitionDTOs(): RelationshipDefinitionDTO[]; /** * Resolve a structural property up the specialization chain: a connection * def that says nothing inherits whatever its supertype declared, so a * value set once on MemoRelationship reaches every relation. */ private inherited; /** Register a relationship type manually (for testing or config fallback) */ register(entry: RelationshipRegistryEntry): void; /** * Populate the registry from parsed SysML documents. * Walks all ConnectionDefinition nodes in each document's AST. */ populateFromDocuments(documents: ParsedDocument[]): void; /** * Record the three relations SysML v2 spells with a keyword. * * The registry otherwise derives everything from `connection def`s, and * `satisfy` / `verify` / `allocate` are usages — there is no definition to * walk, so nothing would report them. That is not a cosmetic gap: the * writer decides how to serialize a relation from its registry entry, and * an entry that looks like every other connection def gets written as * `connection : SatisfiedBy connect …` even when the source said `satisfy`. * * While the ontology still declares `SatisfiedBy` / `VerifiedBy` / * `AllocatedTo` the derived entry is kept and only stamped with its * keyword — the ends, layer, and doc comment it carries are real ontology * facts and are better than anything invented here. When those definitions * are deleted the synthetic entry stands on its own, so the relation does * not vanish from the registry along with its retired spelling. */ private registerLanguageNatives; /** Walk a package declaration and register all ConnectionDefinition nodes */ private walkPackage; } //# sourceMappingURL=relationship-registry.d.ts.map