CelinQ Insights · No. 44
Why an Element-Level Conflict Is Usually Too Large
If the unit of conflict detection is the whole element, two people can never touch the same one without an argument being manufactured that neither of them was actually having.
Picture an application component in a mid-sized Enterprise Architect model, the kind of element that ends up touched by half the team over the course of a project because it sits at the centre of several concerns. One architect updates its lifecycle status from "In Development" to "In Test." A second, entirely independently, corrects a typo in its notes field. A third adds a tagged value recording which team owns it in production. None of the three knows about the other two changes. None of the three would, if you asked them directly, say they were doing anything that conflicted with a colleague's work — because they were not. And yet, in a tool that decides whether a conflict exists by asking the blunt question "did more than one person touch this element," all three of these edits collide, and someone is now asked to resolve a dispute between three people who never actually disagreed about anything.
This is the trap of element-level conflict detection, and it is worth understanding precisely why it happens, because the failure is not a bug in some particular implementation. It is the predictable consequence of choosing too coarse a boundary for what counts as "the same thing," and it gets worse, not better, exactly where a shared model earns its value most: on the elements that matter enough for several people to legitimately need to touch them.
Object-level conflict detection, and where it breaks down
The instinct behind object-level, or element-level, conflict detection is not unreasonable on its face. An element in Enterprise Architect is, after all, the natural unit most architects think in — you edit "the payment gateway component," not "field 14 of row 88213." Treating the whole element as the thing that either has or has not been touched concurrently is a simple rule, easy to implement and easy to explain. The trouble is that it silently assumes something false: that if two people touched the same element, they were probably doing related, and therefore possibly conflicting, work. In a real model, that assumption fails constantly. A status field and a notes field and a tagged-value map are, semantically, almost entirely independent of one another. They live on the same element because that is how EA organises information, not because editing one has any bearing on editing another. Bundling them together as a single unit of conflict detection conflates "sits on the same row in the database" with "represents the same decision," and those are very different things.
The practical consequence is a false-positive rate that scales with exactly the wrong thing: the popularity of an element. The elements every team relies on most — the shared services, the core domain objects, the components that show up in a dozen diagrams — are precisely the ones multiple people will legitimately need to update over the life of a project, for entirely unrelated reasons. An element-level conflict system does not get calmer around these central elements. It gets noisier, manufacturing more disputes exactly where the team can least afford the friction, and the natural adaptation teams make in response is corrosive: they start avoiding the shared, important elements, or funnel all changes to them through one gatekeeper, which quietly reintroduces the very bottleneck that collaborative modelling was supposed to remove.
The atom: the actual unit of disagreement
CelinQ's Fusion engine rejects the element as the unit of conflict and instead detects conflicts at what the engineering documentation calls a merge atom — the smallest piece of a model that can meaningfully be said to hold one fact. A scalar field like Name, Type, Stereotype, Notes, or Alias is its own atom. Each individual key in a tagged-value map is its own atom, not the map as a whole. The tree parent that determines where an element sits in the package hierarchy is its own atom, separate from anything about the element's own content. Each end of a connector — its source and its target — is its own atom, separate from the connector's scalar properties. And a diagram object's geometry is treated as one composite atom, decomposed internally into a translation and a size component so that a move and a resize can be recognised as touching different aspects of that one atom rather than colliding on it.
Once conflict detection operates at this granularity, the scenario this article opened with resolves itself correctly without anyone having to intervene. A status change touches one atom. A notes correction touches a different atom. A new tagged-value entry touches a third atom, distinct from any tagged-value key already on the element. Three edits, three atoms, zero actual overlap — and Fusion applies all three, recording the specific rule that proved each one safe, most commonly DISJOINT_PROPERTY_WRITES for the scalar fields and MAP_DISTINCT_KEYS for the tagged-value case. Nobody is asked to adjudicate a dispute, because there genuinely was not one. The mechanics of exactly how this fits into the broader three-way merge, and what happens on the rarer occasions where two edits do land on the same atom, are covered in the pillar article on conflict resolution, which this piece deliberately zooms in from — that article covers the whole shape of the problem; this one explains why the grain size chosen for detecting collisions is the single decision that determines how often the system cries wolf.
Granularity is not an implementation detail tucked away from the user experience. It is the user experience. Every conflict a team is asked to resolve that was not a real disagreement is a direct, measurable cost of choosing too coarse a unit for detecting them — and every one they are not asked to resolve, because the system correctly saw two unrelated atoms rather than one contested element, is a cost avoided that nobody consciously notices, which is exactly how good infrastructure is supposed to feel.
A worked example: one component over three weeks
It helps to trace a single element through an ordinary project timeline rather than reason about the problem in the abstract. Take an application component that sits near the centre of a solution architecture — call it the payment gateway component, the kind of thing that shows up in three or four diagrams and gets referenced by half the team's questions in review. In week one, the architect responsible for the integration layer adds two new relationships from this component to downstream systems and updates its notes with an integration summary. In week two, a governance reviewer, working entirely independently and without any coordination, adds a tagged value recording the data-classification level of the component, because a compliance pass is underway across the whole model. In week three, the original architect changes the component's lifecycle status from "In Development" to "In Test," while, on the same day, a different colleague nudges the component's position on one diagram to make room for a newly added neighbour.
None of these four people, across three weeks, ever disagreed with any of the others about anything. Under element-level detection, every one of these events after the first would have registered as a potential conflict on an element that "someone already touched," and depending on exactly how the tool surfaced that, the team would have faced anywhere from one to three unnecessary review moments over those three weeks — on one element, out of what might be several hundred actively maintained elements in the model. Multiply that pattern across a real project's actual population of frequently-touched elements and the unnecessary review load stops being a curiosity and becomes a standing tax on exactly the parts of the model the team relies on most. Under atom-level detection, all four changes land on four different atoms — two relationship endpoints, a notes field, a tagged-value key, a scalar status field, and a geometry translation — and every single one applies automatically, each with its own named rule recorded against the revision. Nobody in this story was ever asked to resolve anything, because nobody was ever actually in a dispute.
Scalar fields: the obvious case, done properly
Scalar fields are the easiest atoms to reason about and the ones most teams intuitively expect to be handled well: a name, a type, a stereotype, a note, an alias — single values, one per field, each independent of the others in principle. What element-level detection gets wrong is not the concept but the boundary: it treats all of an element's scalar fields as one unit rather than several. Atom-level detection simply respects the boundary that was already there in the data model — Name is not Stereotype is not Notes — and lets each be written independently by different people without manufacturing a conflict out of the coincidence that they happen to belong to the same element. Where two people do write different values to the genuinely same scalar field, that remains a real conflict, correctly surfaced as a ScalarConflict capsule, because at that specific point of contact there is no principled automatic answer.
Tagged-value maps: independence within a single container
Tagged values deserve particular attention because they are exactly the kind of content where a coarse-grained system does the most damage. A single element might carry a dozen tagged-value entries — deployment environment, owning team, cost centre, review date, compliance classification — added over the life of a project by different people for different reasons entirely. Treating the tagged-value collection as one indivisible field means any two people adding or updating different entries in that collection appear, to a coarse system, to have both "changed the tagged values," an apparent collision that is almost never a real one. Atom-level detection treats each key as its own fact: two additions under two different keys merge automatically as MAP_DISTINCT_KEYS, and only two genuinely conflicting writes to the identical key — both changing "Owning Team" to a different value — become a MapKeyConflict capsule that actually needs a decision. This is, in practice, one of the single largest sources of false conflict a coarser system would generate, precisely because tagged-value maps tend to accumulate the most independent, unrelated pieces of metadata on any one element.
Stereotype sets and notes: fields that look simple but are not always scalar
Not every field on an element behaves like a single indivisible value, and it is worth being honest about where the atom model has to be applied thoughtfully rather than mechanically. A stereotype is typically treated as a scalar for merge purposes — an element generally carries one applied stereotype relevant to the merge, and two different values written to it is a genuine ScalarConflict in the ordinary case. Notes fields raise a subtler question, because notes are free text that people often want to extend rather than replace — one person appending a clarification while another appends a separate observation is, in spirit, more like two independent additions than two competing rewrites of the same value. CelinQ does not silently reinterpret notes as append-only by default; a genuinely different value written to the same notes field is, by default, a real ScalarConflict like any other scalar, because assuming append-semantics on someone's behalf could just as easily discard a deliberate correction as preserve two comments. Where a workspace genuinely wants append-style behaviour for notes, that is available as an explicit, administrator-enabled F1 policy — POLICY_NOTES_APPEND — a deliberate trade-off an organisation opts into with open eyes, not a default assumption baked in on anyone's behalf.
Relationships and diagram geometry: atoms with structure of their own
Connectors introduce atoms that are not simple scalar values but references to other entities — the source end and the target end — and each is tracked independently from the connector's own scalar properties and from each other. A rename of the connector, a change to one endpoint, and a change to the other endpoint are three distinct atoms, and two people touching different ones of the three merge cleanly, while two people reassigning the same endpoint to two different destinations is a genuine topological disagreement, correctly surfaced rather than silently resolved in either direction.
Diagram geometry is the atom that most rewards careful decomposition, because a naive "the position and size changed" comparison would treat a huge fraction of genuinely compatible concurrent edits as conflicts. By splitting a diagram object's transform into a translation component and a size component, Fusion can recognise that one person moving an object and another independently resizing the same object are two edits to two different aspects of the geometry atom, and combine them — recorded as GEOMETRY_MOVE_PLUS_RESIZE — rather than forcing a choice between a correctly positioned but wrongly sized object or the reverse. Only a genuine collision within the same component of the atom, two different people moving the same object to two different places, remains a real conflict, surfaced as a GeometryConflict capsule unless a workspace has explicitly enabled a last-writer policy for that specific situation.
Independent edits to one element are the common case, not the exception
It is tempting to think of the scenario at the top of this article — three unrelated edits landing on one popular element — as an edge case worth handling gracefully but rare in practice. The opposite is closer to the truth. In any model that has been in active use for more than a few weeks, the elements at the centre of the architecture are exactly the ones that accumulate the most incidental, unrelated attention: a status update here, a documentation pass there, an ownership tag added during a governance review, a relationship corrected after a review meeting. None of these are coordinated with each other, and none of them need to be, because none of them are actually about the same fact. A system that cannot see this pattern clearly will make the busiest, most important parts of a model feel the most contentious to work in, which is precisely backwards — the parts of a model that matter most to the whole team are exactly where false friction does the most damage to how willing people are to keep the model current.
The reduction of false conflicts, measured
This is not a claim asserted without evidence. Fusion's own benchmark, a seeded and reproducible run of 100,000 operations across five concurrent clients through the real storage engine and merge pipeline, deliberately manufactured a workload with collisions denser than ordinary modelling produces — a small number of shared tagged-value keys spread across a thousand elements, specifically to stress the map-key merging logic — and even under that artificially dense collision rate, roughly seven in ten of the operations that genuinely collided on the same entity were resolved automatically, correctly, and without a human decision, because atom-level detection recognised most of the apparent overlaps as touching different fields or different keys rather than the same fact. Under an ordinary modelling workload, where concurrent edits to the identical field of the identical element are considerably rarer than the benchmark's deliberately adversarial mix, the proportion of apparent collisions that turn out to be false ones is expected to be considerably higher still — though any organisation should treat that expectation as exactly that, an expectation, and ask for measured evidence from its own usage rather than accepting the benchmark figure as a universal constant. The number that matters most from that run is not the resolution rate on its own but the human-decision rate it implies: roughly eighteen and a half decisions asked of a person per thousand operations, even under deliberately adversarial conditions — a workload most teams will comfortably absorb, because the alternative, an element-level system asking for a decision on every one of those thousand operations that happened to touch a busy element, would not be.
The right question to ask any merge engine is not "does it handle conflicts well" but "what does it consider a conflict in the first place." An engine that manufactures a dispute out of two people editing different fields of one popular element will always feel worse to use than the raw number of genuine disagreements would justify — and the fix is not a smarter resolution algorithm applied afterwards. It is choosing the right grain of comparison before the question of resolution even arises.
The honest limits
Fine-grained atoms are not a free improvement with no engineering cost, and it would be misleading to present them that way. Every kind of content EA supports has to be deliberately modelled at the atom level rather than handled by one generic mechanism — scalar fields, tagged-value maps, tree parentage, connector endpoints, and diagram geometry are each their own case, individually tested, individually reasoned about. A system that skipped this work and simply diffed whole elements would be materially simpler to build. It would also generate exactly the false-conflict problem this article describes, and that trade — less engineering effort for a worse day-to-day experience — is a bad one for any team that plans to actually live inside the tool for years rather than evaluate it for an afternoon.
It is also worth being precise that atom-level granularity narrows false conflicts; it does not eliminate genuine ones, and should not be expected to. Two people writing different values to the identical scalar field, the identical tagged-value key, or moving the identical element to two different destinations remain real disagreements under any granularity, because at that specific point of contact the two intentions genuinely do not agree, and no amount of decomposition changes that. What atom-level detection changes is how often a team is asked to make a decision about something that was never actually in dispute — which, over the life of a shared model touched by many hands, turns out to be most of what element-level detection was asking people to spend their attention on. The broader argument for why models cannot be merged the way source-code text files are, and what "model-aware" merging actually requires beyond fine granularity alone, is the subject of the companion piece on model merge, which this article's atom-level view sets up.