Stable Identity: Why Architecture Models Need IDs That Survive a Rename
Rename an application in most architecture tools and you find out, the hard way, what the tool actually thinks that application is. If every diagram that used to show it now shows nothing, and a new, historyless box shows up wherever you typed the new name, the tool was never tracking the application at all. It was tracking a string.
This is not a hypothetical failure mode. It's the default behavior of any system that uses a name, or a name plus a type, as the effective primary key for an architectural object — which describes an uncomfortable number of spreadsheets, wikis, and even some dedicated modelling tools once you look closely at how they persist data. The fix sounds almost too simple to be worth an article: give every element an identity that has nothing to do with its name. In practice, that one design decision is what separates a tool you can trust with a rename, a merge, a round-trip export, or an AI-proposed change, from one where those operations are quietly dangerous.
What "identity" means, concretely
An architecture model is a graph: elements — applications, services, databases, business capabilities, actors — connected by relationships, organized into views, carrying properties and tags. The question stable identity answers is narrow but foundational: when you look at an element today and the same element tomorrow, how does the system know it's the same one?
There are really only two answers in practice.
The first answer is the name is the identity. "Payment API" is "Payment API" because it's called "Payment API." Change the label, and as far as anything downstream is concerned, "Payment API" ceased to exist and a new, unrelated thing called "Payments Service" came into being. Every relationship that pointed at "Payment API" now points at nothing. Every view that referenced it by name silently drops it. Every rule that checked "Payment API" for compliance stops checking anything. This is exactly how a plain spreadsheet behaves, and it's how a surprising number of diagramming tools behave underneath a friendlier surface, because a label is the only thing they persist.
The second answer is identity is a separate, immutable value the name never touches — a machine ID, typically a UUID or similarly opaque token, assigned once when the element is created and never reassigned, never derived from the name, and never shown to anyone in normal use. The name becomes just another property of the element, editable like its description or its owner tag, and every relationship, view reference, and rule points at the ID, not the label. Rename the element, and nothing else in the model even notices, because nothing else was ever pointing at the name.
Mooodels is built on the second answer, and this article is about why that has to be true for a lot of the other things an architecture tool promises to do — round-trip exchange, semantic diff, AI-proposed changes, merges between two people's edits — to actually work rather than just mostly work.
The failure mode, in a diagram
The left side of that diagram is not a strawman. It's what happens, quietly, in a lot of everyday architecture tooling: a spreadsheet where "application name" is column A, a wiki page keyed by title, a diagramming tool whose file format stores shapes with labels and nothing else. Nobody designed it to break on rename. It breaks on rename because nobody designed identity into it at all — the name was doing double duty as both a human label and a database key, and those two jobs have different requirements.
Why this is a bigger deal than it sounds
An occasional broken diagram after a rename is annoying but survivable — someone notices, redraws the box, moves on. The reason stable identity deserves a whole article is that a growing list of things architects now want from a modelling tool depend entirely on identity being reliable, and none of them fail loudly. They fail by quietly producing a wrong answer that looks plausible.
Round-trip exchange with Archi and Sparx EA
Most architecture practices don't live in a single tool for their whole history. A model gets exported from Sparx Enterprise Architect, worked on somewhere else, and needs to come back — or a team standardizes on Archi for day-to-day editing but needs occasional exchange with a governance repository. Both EA and Archi already understand this problem at a basic level: EA assigns internal GUIDs to elements, Archi does the same with its own identifier scheme. That's stable identity, and it's exactly why round-trip through those tools mostly works today.
Where it breaks is at the boundary. If an intermediate tool re-imports a model and re-keys everything by name because it doesn't preserve the source GUID, every element that got renamed on either side during the round trip comes back as a duplicate rather than an update — same real-world application, two rows in the target repository, no way to reconcile them except by hand. A tool that's serious about interoperating with EA and Archi has to carry the foreign identifier through untouched, alongside its own, precisely so a rename made on one side and exported back to EA lands on the same GUID-keyed object EA already knows about, rather than creating a phantom duplicate next to it.
Semantic diff and Git-friendly serialization
A model with a deterministic, stably ordered serialization — the same model state always writing out byte-for-byte the same way — is only Git-friendly if a rename actually produces a small diff. With a stable ID, renaming "Payment API" to "Payments Service" changes one line: the name field on one object. Every relationship line, every view reference, every rule reference stays byte-for-byte identical, because they're all keyed by the ID, not the name. A pull request reviewer sees exactly what happened: one field, one object, nothing else touched.
Without a stable ID, the same rename can't be expressed as an update at all. It has to be expressed as a deletion of everything under the old name and a creation of everything under the new one — which, serialized to text, touches every line that mentioned the object anywhere: every relationship, every view entry, every rule. A one-word rename produces a diff that looks like the application was ripped out of the architecture and a stranger was dropped in its place. Reviewing that diff for what actually changed becomes a manual reconstruction exercise, which is precisely the kind of thing a version-controlled model with a deterministic serialization is supposed to eliminate.
AI patches
Mooodels never lets an AI assistant edit the model directly — it proposes a structured ModelPatch, a set of add/update/rename/delete/connect/disconnect operations, which goes through validation and a human approval step before anything is committed. That structure only holds together because rename is a distinct, first-class operation from delete plus add. When someone asks the assistant to "rename Payment API to Payments Service across the landscape," the proposed patch is one operation against one stable ID: rename(id: 7f2a-91c…, name: "Payments Service"). The reviewer sees exactly that — a rename, scoped to one object, nothing structural implied — and can approve it with confidence about the blast radius.
Without stable identity, the AI has no honest way to express that request as a patch. It would have to guess: is this actually a rename, or does the user mean "make Payment API's relationships point at a new element called Payments Service and leave the old one alone"? Those are very different operations with very different consequences, and a name-keyed model gives the AI — and the human reviewing its proposal — no reliable way to tell them apart. Every apparent rename becomes a judgment call about intent, which is exactly the kind of ambiguity that structured review is supposed to remove from AI-assisted editing.

Merges between two people's edits
Put two architects on the same model at once — one dragging boxes on the canvas, one approving a patch the AI assistant proposed, both saving independently — and identity is the only thing that makes a three-way merge possible at all. If both edits are expressed as operations against the same stable ID, the merge logic can reason about them: two updates to different properties of the same object combine cleanly, two updates to the same property conflict and need a human decision, a delete on one side and an update on the other is a real, meaningful conflict worth surfacing. None of that reasoning is available if the two edits are keyed by name and one of them happened to include a rename — the merge tool can't tell "these are the same object, edited twice" from "these are two different objects that happen to share a label," which is the exact ambiguity stable identity exists to remove.
A worked example: renaming under load
Take a concrete case. "Payment API" exists in a model with:
- An outgoing relationship to "Fraud Detection Service" (uses)
- An incoming relationship from "Checkout Web App" (uses)
- Membership in three views: the executive landscape, the domain view for Payments, and a security boundary view
- Two tags:
tier: 1andowner: payments-team - A rule check: "Tier-1 applications must have an assigned owner" — currently passing
- A linting note flagged earlier: missing description — still open
The Payments domain lead decides the name undersells what the service now does and renames it to "Payments Service" on the canvas, by selecting the element and typing the new label. With a stable ID underneath, here's the full list of side effects: the name property changes. That's it. Both relationships still resolve, because they were never pointing at a string called "Payment API" — they were pointing at an ID. All three views still show the object, now with its new label. Both tags are untouched. The Tier-1 owner rule still passes, because it was evaluating the object's owner tag, not its name. The missing-description lint flag is still open, correctly, because renaming an element doesn't add a description to it — and it should still be flagged, because a rename doesn't retroactively fix a real documentation gap.
Compare that to a name-keyed system attempting the same rename. "Payment API" is deleted. A new object called "Payments Service" is created with no relationships, no view membership, no tags, no rule history, and no lint history. The rename has, in effect, quietly deleted two relationships, removed the element from three views, dropped both tags, and reset a compliance check that used to pass to a state where it's simply never been evaluated. Nobody asked for any of that. It happened because the system's only way to represent "this is now called something else" was "the old thing is gone and a new thing showed up."
Harder cases: splits, merges, and profile changes
Rename is the easy case for stable identity to handle, which is exactly why it's a good test — a tool that gets rename wrong will get everything harder than rename wrong too. Three cases worth thinking through separately:
Splitting one element into two
Sometimes "Payment API" genuinely stops being one thing — it's being decomposed into a "Payment Authorization Service" and a "Payment Settlement Service." This is not a rename, even though it might start by renaming the original element to one of the two new names. The honest model of what happened is: the original ID becomes "Payment Authorization Service," keeping its history and most of its existing relationships, and a genuinely new element, "Payment Settlement Service," is created with its own new ID, taking over whichever relationships now belong to it. A stable-identity system lets you express this precisely, operation by operation — one rename plus one add plus some relationship reassignment — instead of forcing the whole decomposition through the same blunt delete-and-recreate mechanism that a name-keyed system would use even for a plain rename.
Merging two elements into one
The reverse happens too — two applications turn out to be duplicate entries for the same real system, entered independently by two teams before anyone noticed. Merging them is explicitly an identity operation: one ID is chosen to survive, every relationship and view reference pointing at the other ID gets repointed to the survivor, and the losing ID is retired rather than silently vanishing. Done well, this is auditable — the model can record that ID B was merged into ID A, so anything that still has ID B cached somewhere (an external system, an old export) can be resolved forward instead of just breaking.
Changing profile or element type
Mooodels supports pluggable profiles — Generic, ArchiMate, C4 — and a model can outgrow its starting profile, or an element can be reclassified as understanding of the system improves (a "component" that turns out to be better modelled as a full "application"). That's a change to the element's type property, not a new identity. The relationships, views, and tags accumulated under the old classification should survive a reclassification exactly the way they survive a rename, for the same underlying reason: the ID never encoded the type any more than it encoded the name.
A side effect: names don't have to be unique
Once identity stops living in the name, a constraint that name-keyed systems have to enforce somewhere — usually badly — simply disappears: the requirement that no two elements share a label. A spreadsheet keyed by application name has to either forbid two rows called "Gateway API" or silently let the second one overwrite the first when someone filters or looks it up. Neither option is good, and large organizations run into this constantly, because "Gateway API" is exactly the kind of generic, descriptive name that two unrelated teams in two unrelated domains independently arrive at.
With identity separated from naming, two elements can legitimately both be called "Gateway API" — one in the Payments domain, one in Logistics — because nothing about the model depends on the name being a lookup key. Each has its own ID, its own relationships, its own place in its own views, and the fact that they share a label is, correctly, just a naming coincidence rather than a data integrity problem. This matters more than it sounds like it should, because it's precisely the situation architecture linting is built to catch and flag as worth a human look — "these two elements have identical names, are you sure they're not duplicates of the same thing" — without the tool being forced to treat the collision as an error it can't represent. A name-keyed system can't even ask that question cleanly, because by the time two elements share a name, one of them has usually already silently overwritten the other.
The same separation is what makes a sensible default naming convention — "use the business-friendly name people actually recognize" — compatible with large, federated modelling efforts where no single person controls every name being typed in. Uniqueness becomes something linting checks for and flags, not something the storage layer has to physically prevent by rejecting a save.
Objections worth taking seriously
"Isn't a UUID just more complexity for no visible benefit?"
It's genuinely invisible in normal use — nobody types a UUID, nobody sees one on the canvas, and nobody encounters one in an export unless they go looking for it. The complexity is real but it lives entirely in the tool's internals, in exchange for removing a much worse kind of complexity from the user's actual workflow: the manual bookkeeping of "did I remember to update every diagram and every rule that mentioned the old name." That bookkeeping doesn't go away just because the tool doesn't have a UUID scheme — it gets pushed onto the architect, silently, and shows up months later as documentation that no longer matches reality.
"What about systems downstream that only know the name — a CMDB, a spreadsheet export, a ticketing system?"
This is real and worth being honest about: stable identity inside the model doesn't automatically propagate to every external system that only ever tracked a name. A CMDB entry keyed by application name will not know, on its own, that "Payment API" and "Payments Service" are the same configuration item. What stable identity does give you is a reliable, queryable record — inside the model — of exactly which objects were renamed and when, which is the input a reconciliation step against those external systems actually needs. Without it, you'd be trying to reconstruct the rename history from diffs of old exports, which is strictly harder than reading it off the object directly.
"Doesn't this assume everyone edits inside the tool? What about a spreadsheet-driven bulk import?"
Bulk import is exactly the scenario where identity discipline matters most, not least. A well-behaved import matches incoming rows against existing elements by a stable external key when one exists — a source system ID, an EA GUID, an Archi identifier carried through the exchange format — and falls back to name-based matching only as a last resort, flagged as uncertain rather than treated as ground truth. A bulk import that matches purely on name will happily read a rename in the spreadsheet as "delete one application, create another," reproducing the exact failure this article opened with, just at import time instead of edit time.
What to check before you trust a tool with this
Rename is a cheap, fast test that exposes whether identity is real or cosmetic in any architecture tool, not just this one. A few checks that take under five minutes:
- Rename an element that appears in at least two views and has at least one relationship. Confirm both views still show it and the relationship survives, without manually re-adding anything.
- Check whether any tags, properties, or passed/failed rule state on the element survive the rename unchanged.
- Export the model, rename an element, re-import. Confirm it updates the existing object rather than producing a duplicate.
- If the tool offers more than one way to make a change — a visual canvas and an AI assistant, say — rename through one and confirm the other is looking at the same object afterwards, not a new one.
- If the tool offers AI-assisted editing, ask it to rename something and look at what the proposed change actually says before approving — is it a single update to one object, or does it read like a delete and an add.
The bigger pattern
Stable identity is not a feature you'd put on a slide by itself — nobody evaluates a tool by asking specifically "does it have immutable machine IDs." But it's the load-bearing assumption underneath almost every other claim a model-native tool makes: that round-trip exchange with EA and Archi won't duplicate your portfolio, that a Git diff on the model will actually be readable, that an AI-proposed patch can be reviewed with confidence about its actual scope, that two people editing the same model at once can be merged rather than forced to pick a winner. Pull the thread on any of those and you land back on the same question: does this object have an identity independent of what it's currently called?
In Mooodels, the answer is yes by construction — every element gets its ID on creation and keeps it for the life of the model, through renames, reclassifications, splits, merges, and round trips through Archi or Sparx EA. It's a small, mostly invisible design decision. It's also the reason a rename can be just a rename, instead of a small act of quiet data loss dressed up as a labeling change.
See the model this article describes, working in a real editor.
Try the live demo