ADR 0006 — How a view says what kind of diagram it is, and a model says what language it is in¶
Status: Accepted, implemented
Scope: how every converter records the kind of a view and the modelling language of a model.
Replaces the PlantUML-only uml:diagramType "SEQUENCE" string, and fills the equivalent gap in the
other four converters.
Depends on: ADR 0002 for the model/view split this attaches facts to. Related to ADR 0004, which settled the analogous question for a different enumerated vocabulary — lifecycle status — and reached the same answer: an IRI from a published vocabulary, not a string.
Context¶
A .puml file declares what kind of diagram it is by its own syntax: participant and -> make a
sequence diagram, class and <|-- make a class diagram. PlantUmlParser.detectEntityDiagramType
resolves this into a DiagramType enum, and the emitter published it as a string:
Three things are wrong with that triple, in increasing order of seriousness.
The predicate does not exist. grep -rn diagramType across linked-archi-meta returns nothing —
not in uml-onto.ttl, not in any shapes file, not in any document. The converter mints
uml:diagramType into the published UML namespace, where it looks like part of UML 2.5.1 and is not.
Nothing declares its meaning and no shape can constrain it, because SHACL cannot constrain a property
it has never heard of.
The value is a Kotlin identifier. "SEQUENCE" is DiagramType.SEQUENCE.name — an untagged
xsd:string naming an internal enum constant. It carries no label, no definition, no translation, and
no link to anything. A typo in it is indistinguishable from a new kind of diagram. This is the pattern
DD-23 lists under alternatives
considered and not adopted, for exactly these reasons.
The vocabulary already exists upstream, and the converter ignores it.
modelingLanguages/uml/uml-viewpoints.ttl declares all fourteen UML diagram types as arch:Viewpoint
instances — umlvp:SequenceDiagram, umlvp:ClassDiagram, umlvp:StateMachineDiagram and the rest —
each with arch:includesConcept naming the metaclasses it may draw, arch:viewpointHasPurpose,
arch:viewpointFramesConcern, and arch:viewType arch:Diagram. Its own dcterms:description reads
"UML 2.5.1 diagram types formalized as Linked.Archi viewpoints". core-onto.ttl has carried
arch:viewConformsToViewpoint (domain arch:View, range arch:Viewpoint) the whole time. So the
converter invented a private string for a fact the ontology was already waiting to receive.
The same gap runs through the other converters, in three different shapes:
| Converter | What it does with the diagram kind |
|---|---|
| PlantUML | resolves it, publishes it as an undeclared string |
| Structurizr | resolves it into C4ViewType, then drops it — the view gets only arch:Diagram |
| BPMN | never asks; every view is arch:View, arch:Diagram |
| ArchiMate | never parses viewpoint=, although the source files carry it |
| Backstage | emits no views at all |
And at the model level, none of the five records which language the model is written in.
arch:modelConformsToMetamodel (domain arch:Model, range arch:Metamodel) is declared upstream and
every notation publishes an arch:Metamodel instance — umlmm:UML2, c4mm:C4Model, bpmnmm:BPMN2,
ammm:ArchiMate3.2 — and no converter emits the link. A merged graph therefore cannot answer "which
of these models are C4 models" except by inspecting the types of the elements inside them.
Options¶
A. Declare uml:diagramType upstream and constrain it with sh:in¶
The smallest change: keep the string, add the property to uml-onto.ttl, add a shape listing the
eight legal values. Costs one upstream property and closes the "undeclared predicate" objection.
It does not close the other two. The value stays a bare string with no label and no definition, and the fourteen published viewpoints remain unused — so the graph now has two vocabularies for one fact, one of them a lossy copy of the other. DD-23 rejected exactly this shape.
B. Mint diagram classes subclassing arch:Diagram¶
uml:SequenceDiagram rdfs:subClassOf arch:Diagram, and type the view with it:
a arch:View, arch:Diagram, uml:SequenceDiagram.
This is genuinely attractive, and the repo anticipates it — archimate3.2-viewpoint-shapes.ttl
comments that a conforming view "must be typed as arch:Diagram (or a subclass)". It gives
rdf:type queries with subclass entailment for free, and it is the only option that allows a SHACL
shape to target one diagram kind, so that a rule like "a sequence diagram's participants must be
lifelines" becomes expressible.
Three objections, of which the second is decisive:
Namespace. uml: is reserved for UML 2.5.1 metaclasses (UML-DD-2, UML-DD-10). "Sequence Diagram" is
Annex A notation guidance, not a metaclass. uml:SequenceDiagram would look like one and not be one —
the same mistake UML-DD-12 avoided when it declined to type enumeration literals as
uml:EnumerationLiteral.
Duplication. umlvp:SequenceDiagram already exists. Adding uml:SequenceDiagram gives one
distinction two IRIs in two files with no link between them. Not punning under DD-6, but precisely the
"second, competing home for the same vocabulary" UML-DD-12 warns against.
Fan-out. If UML gets a diagram subclass tree, C4 needs one, BPMN needs one, ArchiMate needs twenty-odd more. Viewpoints are already the cross-notation mechanism and are already populated for all of them.
C. Named individuals plus a uml:diagramKind object property¶
Follows DD-7's closed-enumeration pattern
literally: an owl:Class closed with owl:oneOf, values as owl:NamedIndividual + skos:Concept, a
property to carry them.
Mechanically correct and still wrong here, for option B's second reason alone: it is a third home for a vocabulary that has one. The pattern is for value sets a source specification fixes and no document yet publishes. This one is published.
D. Use the conformance properties that already exist¶
arch:viewConformsToViewpoint umlvp:SequenceDiagram on the view,
arch:modelConformsToMetamodel umlmm:UML2 on the model.
Adds no ontology terms in any namespace. Uses two properties and two vocabularies that are published, versioned and documented upstream. Uniform across all five converters, because every notation has a viewpoint catalogue and a metamodel manifest.
Decision¶
D, for both levels.
<…/plantuml/checkout/view/checkout-sequence>
a arch:View, arch:Diagram ;
arch:viewConformsToViewpoint umlvp:SequenceDiagram .
<…/plantuml/checkout>
a arch:Model ;
arch:modelConformsToMetamodel <https://meta.linked.archi/uml/metamodel#UML2> .
uml:diagramType is removed rather than kept alongside. Nothing consumed it — no SPARQL query, no
feature file, no document, and the only tests that mentioned it asserted on the Kotlin enum rather than
on RDF — so there is no migration to stage, and leaving two predicates for one fact guarantees they
drift.
The mapping is total except for one value:
DiagramType |
Viewpoint |
|---|---|
CLASS |
umlvp:ClassDiagram |
COMPONENT |
umlvp:ComponentDiagram |
SEQUENCE |
umlvp:SequenceDiagram |
USECASE |
umlvp:UseCaseDiagram |
ACTIVITY |
umlvp:ActivityDiagram |
STATE |
umlvp:StateMachineDiagram |
DEPLOYMENT |
umlvp:DeploymentDiagram |
UNKNOWN |
nothing emitted |
UNKNOWN emits no triple, and that is the point of moving to an IRI. "UNKNOWN" was a value that
looked like a value and meant "the detector did not recognise this file"; absence says the same thing
without inviting a consumer to match on it.
Four choices inside the decision, each of which had a plausible alternative:
A detected viewpoint is a claim, and an author's overrides it. A viewpoint is prescriptive — it
specifies conventions a view is meant to follow — while the diagram kind is descriptive. Asserting
conformance from a syntax guess is a mild overreach, so where an author has declared
arch:viewConformsToViewpoint through the index or an in-file annotation, that wins and the detected
value is suppressed. This is the precedence DeclaredTitle.forView already applies to titles: the
index declares, the notation fills the gap. It is deliberately not ArchitectureState.reconcile's
rule, which refuses a disagreement rather than resolving it — baseline and target are contradictory
claims about one diagram, whereas "the author says this is a communication diagram and the parser
guessed sequence" has an obvious winner.
The viewpoint namespace is a separate option from the ontology namespace. --ns-puml points at
uml/onto# and viewpoints live in uml/viewpoints#. Deriving one from the other by string surgery
would break the moment someone repoints the namespace, so --ns-uml-viewpoints is its own knob with
its own default.
The metamodel link is emitted per notation, not per converter. BPMN emits bpmnmm:BPMN2 normally
and bpmnlmm:BPMNLite when the lite type-mapping is in play, because that is a different metamodel and
the converter already knows which one it is using. PlantUML emits umlmm:UML2 — PlantUML is a syntax,
not a metamodel, which is the same reasoning PublishedAssets already records for why its shapes are
UML's.
Structurizr's model is now typed arch:Model. It was not before: the converter minted a model IRI
for provenance and never declared what it was, so the metamodel link would have hung off an untyped
subject. Its views also gain arch:View alongside arch:Diagram, matching every other converter.
Consequences¶
- A merged graph answers "every C4 model", "every UML model", "every sequence diagram across all notations" with a one-hop query and no reasoning.
- Views reach their metamodel in two hops, because they already carry
dcterms:isPartOfto the model. uml:diagramTypedisappears from converter output. Any consumer matching on it — none known — breaks loudly rather than silently, since the predicate simply stops appearing.- The detection now has consequences it did not have before.
detectEntityDiagramTypematches substrings against PlantUML's own diagram class simple names and falls back toDiagramType.CLASS, so a rename in the PlantUML library reclassifies diagrams silently, and a misfire previously produced a string nobody read. It now produces a false conformance claim that SHACL will act on. Every diagram kind is therefore pinned by a test, whichtodo/ANALYSIS-converter-gaps.mdhad already asked for on weaker grounds. - ArchiMate now reads
viewpoint=from the Exchange XML, which it parsed nowhere before despite every source file carrying it. ArchiMate viewpoint names map toamvp:individuals by the specification's own naming. - The emitted viewpoint and metamodel IRIs are defined in documents no converter previously loaded, so
uml/viewpoints,c4/viewpoints,bpmn/viewpoints,core-viewpointsand the seven metamodel manifests are now registered inPublishedAssets. They are not in the default shape sets: a validation run that does not care about viewpoint conformance should not pay two fetches for it. - Because the viewpoint documents are registrable,
archimate3/viewpoint-shapesbecomes worth registering too — itsViewConformsToViewpointShaperequires exactly one viewpoint perarch:View, which every converter's output previously violated and now satisfies. Registered, opt-in, and noted in Open questions because a shapes document in the ArchiMate namespace targetingarch:Viewapplies one notation's policy to every notation in a merged graph.
The version problem, which this does not solve¶
arch:modelConformsToMetamodel names a version: ammm:ArchiMate3.2 and am4mm:ArchiMate4 are two
metamodels, as are bpmnmm:BPMN2 and bpmnlmm:BPMNLite. So "every ArchiMate model regardless of
version" needs a grouping, and the hop that should provide it does not:
# archimate3.2-metamodel.ttl → https://meta.linked.archi/archimate3/metamodel#ArchiMateFramework
# archimate4-metamodel.ttl → https://meta.linked.archi/archimate4/metamodel#ArchiMateFramework
Each version's manifest declares arch:basedOnFramework pointing at a Framework individual minted in
its own namespace, so one framework has as many IRIs as there are versions, and there are no
prov:wasRevisionOf or owl:priorVersion links between the metamodels either.
Nothing on the converter side can fix that; a consumer needs
VALUES ?mm { ammm:ArchiMate3.2 am4mm:ArchiMate4 } until it is fixed upstream. Filed as issue 6 in
todo/UPSTREAM-ISSUES-meta.md.
Example¶
@startuml
' checkout-sequence.puml
participant ClientApp
participant OrderService
ClientApp -> OrderService: create order
@enduml
<…/plantuml/checkout>
a arch:Model ;
arch:modelConformsToMetamodel <https://meta.linked.archi/uml/metamodel#UML2> .
<…/plantuml/checkout/view/checkout-sequence>
a arch:View, arch:Diagram ;
dct:isPartOf <…/plantuml/checkout> ;
skos:prefLabel "Checkout sequence"@en ;
arch:viewConformsToViewpoint umlvp:SequenceDiagram .
Author override — the parser sees participant and -> and would guess umlvp:SequenceDiagram, but
the author says otherwise and is believed. Both existing annotation routes already write this
predicate, and neither needed changing:
# diagrams-index.yaml
prefixes:
arch: https://meta.linked.archi/core#
archvp: https://meta.linked.archi/core-viewpoints#
views:
- id: checkout-sequence
file: checkout-sequence.puml
links:
arch:viewConformsToViewpoint: archvp:Roadmap
'!la-prefix arch: https://meta.linked.archi/core#
'!la-prefix archvp: https://meta.linked.archi/core-viewpoints#
'!la-view-link arch:viewConformsToViewpoint archvp:Roadmap
That both routes already existed is what makes the precedence rule load-bearing rather than tidy: the
detected value and the declared one land on the same predicate, and
archimate3.2-viewpoint-shapes.ttl allows sh:maxCount 1. Emitting both would produce a view with two
viewpoints and turn an author's annotation into a validation failure.
Cross-notation query, which is what the whole change is for:
PREFIX arch: <https://meta.linked.archi/core#>
PREFIX umlvp: <https://meta.linked.archi/uml/viewpoints#>
PREFIX c4mm: <https://meta.linked.archi/c4/metamodel#>
# every sequence diagram, whatever produced it
SELECT ?view WHERE { ?view arch:viewConformsToViewpoint umlvp:SequenceDiagram }
# every C4 model, and its diagrams
SELECT ?model ?view WHERE {
?model arch:modelConformsToMetamodel c4mm:C4Model .
?view dct:isPartOf ?model ; a arch:Diagram .
}
Open questions¶
- Should a detected viewpoint be distinguishable from a declared one? Both land on the same predicate, so a consumer cannot tell "the author asserts this conforms to the Sequence Diagram viewpoint" from "the converter inferred it from syntax". Recording the difference would need either a second predicate or a provenance-graph qualification, and neither has been asked for. The current answer is that the author's value silently wins, which is right for the graph and invisible in it.
- Should conformance be checked rather than asserted?
umlvp:SequenceDiagramcarriesarch:includesConceptnaming exactly the metaclasses a sequence diagram may contain, so a converter could verify its own claim against the element types it emitted, and warn when a diagram declares one viewpoint and draws another's concepts. That is a validation feature, deliberately out of scope here. - Does
archimate3/viewpoint-shapesbelong in the default ArchiMate shape set? It is the only published shape that enforces this ADR, and it lives in a notation namespace while targetingarch:View— so loading it applies ArchiMate's viewpoint policy to PlantUML and BPMN views in a merged graph. P-10 argues against exactly that shape of dependency for label rules. Registered but opt-in until upstream decides whether the shape should move to core. - Should ArchiMate 2.x viewpoint names be mapped to their 3.2 successors? They are dropped today.
The published local names are irregular — eleven of the twenty-three carry a
VPsuffix and twelve do not, so"Information Structure"isamvp:InformationStructureVPwhile"Application Cooperation"isamvp:ApplicationCooperation— which is why the mapping is a table rather than a derived slug. Only the shape of the authored name is normalised: lower-cased, non-alphanumerics dropped, a trailing "viewpoint" word removed, so"Business Process Co-operation"matchesamvp:BusinessProcessCooperation.
What it will not do is translate across specification versions. Measured on two real Exchange files:
Archimetal resolved 18 of 83 views and Archisurance 9 of 16, and every failure was an ArchiMate 2.1
name — Introductory, Business Function, Actor Co-operation, Infrastructure,
Application Behavior, Principles. Some have a plausible 3.2 successor and Introductory has none
at all, so a mapping would be our editorial judgement presented as the author's statement. Dropped and
reported instead, aggregated to one line per run. If a corpus needs the translation, it wants an
explicit, reviewable table and probably an --archimate-2-viewpoints switch to opt into it.
- Backstage emits no views, so it gets the metamodel link and nothing else. The vocabulary is not
the obstacle — backstage-viewpoints.ttl publishes five viewpoints and the manifest points at them
with arch:architectureViewpoints — the converter simply produces a catalog, not a diagram. If a
rendered form is ever added, the viewpoints are waiting.