Architecture state¶
A repository holds the same architecture several times over: how it is today, how it is meant to end up, and the stable plateaus in between. Architecture state is how a model, a diagram or an individual element says which of those it describes.
Without it the graph merges them. A target-state component and its baseline counterpart become one resource making contradictory claims, and a query for "what runs today" returns things nobody has built yet.
The vocabulary is three individuals from the core ontology, and the property is
arch:architectureState:
| Value | arch:architectureState |
Meaning |
|---|---|---|
baseline |
arch:Baseline |
how the architecture exists today — implemented, operational |
target |
arch:Target |
how it should exist once planned changes are realised |
transitional |
arch:Transitional |
a stable plateau on the way from one to the other |
The spelling variants the ontology records as skos:altLabel are accepted too: as-is, current
and current-state for baseline; to-be, future and future-state for target; transition,
intermediate and intermediate-state for transitional. Case and the choice of -, _ or a space
are ignored, so As Is and as-is are one value.
Not the same thing as status:
The two are easy to confuse and answer different questions.
| Field | Question | Subject |
|---|---|---|
status: |
has this diagram been released? | the diagram, as a document |
architectureState: |
which reality does it describe? | the architecture |
A target-state diagram can be perfectly published — finished, reviewed, and describing a future
that does not exist yet. Neither field implies anything about the other, which is why they are
separate fields rather than one vocabulary. Writing draft under architectureState: fails the
run and says where it belongs.
status: is ADR 0004 and reaches the graph as
adms:status in the provenance graph. Architecture state lands in the semantic graph.
Which route each notation and level has¶
There are two ways to state it, and the difference matters more than where you write it:
- The checked route — the
architectureState:field, or'!la-architecture-statein a.puml. You supply a token, its value must be one of three, a typo fails the run, and no flag is needed. - The generic route — writing the triple yourself as an annotation:
links:,'!la-link, BPMNextensionElements, or an ArchiMate property. You supply the predicate IRI and the object IRI, any IRI is accepted without complaint, and it requires--emit-extension-data.
The checked route reaches only the model and the view, and only where a diagram index exists. Every other cell below is the generic route.
| Notation | Model | View | Element |
|---|---|---|---|
| PlantUML | index — checked | index, or in-file '!la-architecture-state — checked |
generic: index elements:, or in-file '!la-link |
| BPMN | index — checked | index — checked | generic: index elements:, or in-file extensionElements |
| Backstage | index — checked | index — checked | generic: index elements: |
| LeanIX | index — checked | index — checked | generic: index elements: |
| ArchiMate | ✗ no route | generic: property + object-properties: |
generic: property + object-properties:also relationships |
| Structurizr | ✗ | ✗ | ✗ |
What each route costs is set out under the two routes below.
Two gaps are worth stating plainly rather than leaving to be discovered:
- ArchiMate has no model-level route. It has no diagram index, and the converter promotes properties on elements, relationships and views but not on the model. A model-wide claim has to be made in the aggregation repository instead.
- Structurizr has no route at all, in-file or index.
The two routes¶
The checked route: architectureState:¶
A first-class field whose values are a closed set. Not gated behind --emit-extension-data:
which reality a diagram describes is a property of the diagram, like its status, not data borrowed
from a modelling tool's extension point.
In the diagram index, at model level and per view:
model:
id: order-domain
architectureState: baseline # the model IS the baseline architecture
views:
- id: order-flow-as-built
file: order-flow.bpmn
status: publish
- id: order-flow-planned
file: order-flow-v2.bpmn
status: publish
architectureState: target # this diagram describes the target
PlantUML sources can also declare it in the file, which BPMN cannot — a .bpmn has nowhere to put a
statement about the diagram as a whole, because extensionElements nests inside the element it
annotates:
An unrecognised value fails the run, naming the entry:
[ERROR] Conversion failed: Unknown architectureState 'Targt' for 'planned.puml' in
/repo/models/diagram-index.yaml. Accepted: baseline, target, transitional. A state says which
reality the diagram describes, so an unrecognised one is refused rather than published as a link to
a term nothing defines. Note this is not the publication status: 'draft' and 'publish' belong under
'status:'.
Failing closed is the whole point of the field existing, and the contrast with the generic route below is the reason it is a field rather than one more link.
If a PlantUML file and the index both declare one, they must agree. Baseline and target are opposite claims about one diagram, so a disagreement is refused rather than settled by precedence — which is where this differs from a prefix declared twice. Preferring either silently would publish a future architecture as current, or the reverse.
The generic route: arch:architectureState as a link¶
The same predicate written through the extension-data mechanism. This is the only route that reaches an element, and for ArchiMate it is the only route at all.
Index, any of the three levels. Requires --emit-extension-data:
prefixes:
arch: https://meta.linked.archi/core#
model:
id: order-domain
links:
arch:architectureState: arch:Baseline # the model
views:
- id: planned
file: planned.bpmn
links:
arch:architectureState: arch:Target # the view
elements:
Process_Order:
links:
arch:architectureState: arch:Target # one element
PlantUML, in the file:
'!la-prefix arch: https://meta.linked.archi/core#
'!la-view-link arch:architectureState arch:Target # the view
'!la-link OrderService arch:architectureState arch:Target # one element
BPMN, in the file. The subject is always the element that owns the extensionElements, so this
reaches the process and its tasks but never the arch:View:
<definitions xmlns:arch="https://meta.linked.archi/core#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" …>
<process id="Process_Order" name="Order Fulfilment">
<extensionElements>
<arch:architectureState rdf:resource="arch:Target"/>
</extensionElements>
ArchiMate, as an element, relationship or view property, with the key declared under
object-properties: in --type-mapping so the value resolves to an IRI rather than a string:
Without that declaration the property is emitted as the literal "arch:Target", which violates
arch:architectureState's rdfs:range and loses the IRI join, so no query can follow it into the
state vocabulary. See type mapping and
ArchiMate.
What the generic route costs¶
It is gated. Without --emit-extension-data the entries are read and ignored. Nothing warns
that a statement was dropped.
It is not validated. A generic predicate has no closed set to check against, so a misspelling resolves to a perfectly valid IRI that nothing defines, and nothing complains:
# authored as arch:architectureState: arch:Targt
<…/element/Process_Order> arch:architectureState <https://meta.linked.archi/core#Targt> .
A query filtering on arch:Target then silently skips that element — no error at conversion, no
error at query time, just a row that is not there. The only case that does warn is an undeclared
prefix, where the value cannot resolve at all and is kept as a literal.
So the discipline is on the author wherever the checked field does not reach: element scope in every notation, and every level in ArchiMate.
Two rules that govern how it is read¶
Nothing is inherited. This is where architecture state differs from status:, where a
model-level value is only a default and the model is never the subject. arch:architectureState is
defined on a Model as readily as on a view — the core ontology's own example uses a Model — so a
model saying baseline is a claim about the model, not a default for its views:
model:
id: order-domain
architectureState: baseline # the model is the baseline architecture
views:
- id: as-built
file: as-built.puml # says nothing of its own, and inherits nothing
- id: planned
file: planned.puml
architectureState: target # this diagram describes the target
A view-level statement does not reach the elements in the view either. A diagram marked arch:Target
has elements carrying nothing, so "which applications are in the target architecture" is answered by
walking from the view into its contents, not by filtering elements directly.
Saying nothing asserts nothing. There is no default. A repository that has never distinguished baseline from target is not thereby claiming everything is baseline, which means an unstated resource is genuinely unstated and must not be read as baseline by a consumer.
What reaches the graph¶
One triple per subject, in the model's semantic graph:
<https://example.org/la/bpmn/order-domain/graph/semantic> {
<…/bpmn/order-domain> arch:architectureState arch:Baseline .
<…/bpmn/order-domain/view/order-flow-planned> arch:architectureState arch:Target .
<…/bpmn/order-domain/element/Process_Order> arch:architectureState arch:Target .
}
Semantic rather than provenance, for two reasons that point the same way. It says which reality the diagram describes rather than how the file came to be, so it is not provenance in the sense the rest of the index metadata is. And the same predicate can arrive through the generic route, which lands in the semantic graph — one predicate appearing in two named graphs depending on which route wrote it would silently halve the results of any query scoped to a single graph.
See also¶
- ADR 0011 — Which reality a diagram describes — why it works this way: no inheritance, no default, a refused disagreement, and the semantic graph
- Diagram index files — the index schema, and
status:beside this - Extension data — the generic route in full
- ADR 0004 — Lifecycle states — the other state vocabulary
- Type mapping —
object-properties:, the ArchiMate route