CelinQ Insights · No. 43
Enterprise Architect Conflict Resolution: How Semantic Merge Handles Concurrent Changes
Most concurrent edits to a shared model are not really in conflict at all. This is how CelinQ tells the difference, and what happens on the rare occasions two people genuinely disagree.
Say the word "conflict" to a room of architects who have worked in a shared Enterprise Architect repository and you will get a wince before you get an explanation. Everyone has a story: a rename that clobbered a colleague's in-progress diagram, an afternoon of careful tagged-value work that vanished because someone else's save landed a minute later, a merge tool that presented two entire packages side by side and asked a tired reviewer to pick one, as if there were no way both sets of changes could simply be kept. Conflict resolution, in most people's experience, is not a feature. It is a chore that gets worse the more people you add to a model, and the natural conclusion many teams draw is that concurrent editing itself is the problem, and the only real defence is to prevent it — through locking, through strict division of labour, through simply not letting two people near the same package at the same time.
That conclusion is understandable and, on the evidence of most tooling, reasonable. It is also, on closer inspection, based on a false premise: that most concurrent edits are genuinely in conflict. They are not. Two architects working in the same package for an entire afternoon, touching dozens of elements between them, will in the overwhelming majority of cases have made changes that do not actually collide — different fields on the same element, different elements entirely, changes that happen to be identical on both sides, structural moves that combine cleanly with unrelated property updates. The measured evidence for this, discussed further below, is that roughly seven in ten of the changes that do overlap on the same entity resolve automatically and correctly, with no human decision required at all. What makes conflict resolution feel so painful in most tools is not that concurrent editing is inherently dangerous. It is that most tools cannot tell the difference between a real conflict and a false one, and so they either force every case to a person, or worse, silently guess.
Three-way merge: base, local, remote
CelinQ's reconciliation engine, Fusion, is built around the same core idea that has underpinned trustworthy merging in text-based version control for decades, applied to a model instead of a text file: a three-way comparison between a common ancestor, one side's changes, and the other side's changes. The ancestor — the base — is the state of a given entity the last time both sides genuinely agreed on it. Local is what one side did to it since then. Remote is what arrived from elsewhere since then. Given all three, Fusion can ask a much more precise question than "do these two states differ": it can ask "what did each side actually do, and are those two things compatible."
This is possible only because every change carries the base version it was made against, and the server tracks a version number per entity rather than per file. When an incoming change's declared base matches the entity's current version, nothing else happened in between — the change is sequential, and it is simply applied. When the declared base is older than the current version, real concurrency has occurred, and Fusion pulls the stored base state and runs the full three-way comparison. This is a deliberate design choice worth naming explicitly: the comparison is never done against a guessed common ancestor inferred by looking for similarities between two end states, which is the approach a plain diff has to fall back on and which is exactly where meaning gets lost. The base is recorded, not reconstructed.
Same object, different property — and why it is not a conflict
The simplest and most common case, by a wide margin, is two people changing different properties of the same element. One architect updates the notes field with a clarification. Another, working from the same starting point, changes the element's stereotype. Neither knows about the other's change. When both changes reach the server, Fusion sees two disjoint writes — different fields, same entity — and applies both without hesitation, recording the rule that proved it safe: DISJOINT_PROPERTY_WRITES. Nothing about this requires cleverness or heuristics. It requires only that the system track changes at the level of the individual field rather than the whole element, which is precisely the granularity argument developed at length in the companion piece on merge atoms — because an element-level lock or an element-level conflict flag would treat this entirely harmless situation as if it were a genuine collision, purely because both edits happened to land on the same row.
The same logic extends to tagged values, which are not single fields but maps of independent keys. If one architect adds a value under one tagged-value key and another adds a value under a different key on the same element, Fusion recognises MAP_DISTINCT_KEYS and combines both additions automatically. And where both sides happen to write the identical value to the identical field — which happens more often than intuition suggests, particularly with derived or convention-driven values — Fusion recognises CONVERGENT_WRITES and treats it as no conflict at all, because there genuinely is not one.
Same property, different value — a genuine conflict
Not every collision dissolves this cleanly, and it would be dishonest to pretend otherwise. When two people change the same scalar field to different values — both editing an element's status, one to "Approved" and the other to "Deprecated" — there is no safe automatic resolution, because there is no principled way for a machine to know which decision correctly reflects the team's actual intent. Picking one silently, even by a plausible-sounding rule like "the later timestamp wins," would be guessing dressed up as competence, and guessing wrong on something like an approval status is exactly the kind of quiet error that erodes trust in a shared model faster than any amount of visible friction ever could. Fusion does not guess. It opens a ScalarConflict capsule, preserves both proposed values in full, and leaves the canonical state exactly as it was until a person resolves it. The same honesty applies to the tagged-value case: two different values written to the same key becomes a MapKeyConflict capsule, not a coin flip.
Tree conflicts, graph conflicts, diagram conflicts
Beyond scalar fields, a model has structure, and structure creates its own categories of conflict, each handled on its own terms rather than folded into one generic "something differs" bucket.
Tree conflicts arise from the package hierarchy. Moving an element to a new parent while someone else renames it are two changes to two different fields of the same entity and merge automatically, recorded as TREE_MOVE_PLUS_RENAME; moving it while someone else updates one of its properties merges the same way, as TREE_MOVE_PLUS_PROPERTY_UPDATE. But two people moving the same element to two different new parents is a genuine structural disagreement about where that element belongs, and it is surfaced as a StructuralConflict capsule rather than silently accepting whichever move happened to arrive first.
Graph conflicts concern connectors — relationships with two identified ends. Changing a connector's name or stereotype while someone else changes a different property of the same connector is a disjoint write and merges cleanly. Reassigning which element a connector's endpoint actually points to, concurrently with any other change to that same endpoint, is a topological disagreement, surfaced as a TopologyConflict capsule, because two different opinions about what a relationship actually connects cannot both be quietly kept.
Diagram conflicts concern the geometry of objects placed on a canvas. A diagram object's position and size are decomposed into a translation component and a size component, and where those two kinds of change land on the same object from two different sides — one person moving it, another resizing it — they commute and combine automatically as GEOMETRY_MOVE_PLUS_RESIZE. Two people moving the same object to two different places does not commute, and becomes a GeometryConflict capsule — unless a workspace has explicitly opted into a last-writer policy for geometry, an F1-level choice an organisation makes deliberately rather than one Fusion assumes on anyone's behalf.
Auto-merge versus human decision: the levels
Fusion organises every outcome into a small number of named levels, and the naming matters because it is what makes the system's behaviour legible rather than opaque. F0, proven, covers outcomes that are safe by construction — disjoint writes, distinct map keys, convergent writes, a move paired with a rename or a property update, a move paired with a resize — situations where the two changes are, provably, non-overlapping or identical, and no policy choice is involved at all. F1, policy, covers outcomes that are only safe because a workspace administrator has explicitly said so for that specific situation, such as treating geometry conflicts with last-writer-wins, or appending rather than overwriting concurrent notes edits — real trade-offs an organisation opts into with open eyes, not defaults quietly baked in. F3, human, covers everything that remains genuinely ambiguous: a capsule is raised, the canonical state holds exactly where it was, and a person resolves it, optionally informed by an AI-generated recommendation that never has the authority to decide on its own — a distinction covered in full in the piece on AI-assisted conflict resolution without giving AI control of the model.
No level here means "the system decided this didn't matter." F0 means the system proved, by a named and inspectable rule, that both changes could be kept in full. F3 means the system proved the opposite — that keeping both, or picking one silently, would be a guess — and said so plainly rather than quietly picking a side.
Proof-carrying merge: why the rule name is the point
Every F0 and F1 outcome is not just applied; the specific rule that proved it safe is recorded against the revision, visible afterwards in the Control Plane's Fusion view alongside the open decisions still waiting on a person. This is a deliberate rejection of black-box automatic merging. A system that quietly combined changes without recording why would be asking an organisation to trust it on faith, and faith is a poor substitute for an inspectable record when the model in question is the shared source of truth for a public-sector or regulated architecture practice. Proof-carrying merges mean an administrator, an auditor, or simply a sceptical architect can look at exactly why two concurrent edits were combined automatically, by which named rule, rather than being told to trust the outcome. This is developed at length in the dedicated piece on proof-carrying merges, which is worth reading directly alongside this one — it is, in a real sense, the accountability half of the same story this article tells about the mechanics.
Fusion Capsules: where genuine disagreements live
Every conflict Fusion cannot resolve automatically becomes a capsule — a durable, specific record of exactly what collided, holding both sides' proposed state, that sits open until someone resolves it. This matters for two reasons beyond the obvious one. First, an open capsule does not block anyone else's unrelated work; the canonical model keeps moving forward around it, and the capsule is a scoped, addressable thing a person can come back to rather than a global stop-the-world event. Second, a capsule preserves everything: nothing is discarded to make the conflict "go away," which is precisely how the resurrection problem — a deleted element quietly reappearing because someone edited it while offline, unaware it had been removed — is avoided rather than merely mitigated after the fact. That specific failure mode, and the tombstone mechanism that prevents it, is the subject of a companion article; the recovery path for work that would otherwise be stranded under a concurrently deleted parent is covered in the piece on the Rescue Zone, and both connect directly back to the granularity discussion in merge atoms and the broader structural picture in model merge.
Resolving a capsule inside Enterprise Architect itself, through the add-in's Resolve Conflicts menu, is deliberately unglamorous: an architect sees the specific field or fields in dispute, both proposed values, and a small set of well-defined actions — keep one side, keep the other, or in the delete-related cases, restore the original, restore it with the surviving changes applied, or restore it as a new entity so neither side's intent is lost. The decision is recorded on the revision exactly like any other change, and the model moves forward with a complete account of what happened and why, which is a meaningfully different experience from being handed a raw diff of two divergent files and told to sort it out.
No AI required
It is worth stating plainly, because it runs against the current mood of "add AI to everything": none of the mechanics described in this article depend on AI in any form. Fusion is a deterministic, pure function of a base state, two sets of changes, and a workspace's policy — no external calls, no model inference, no randomness, no clock dependency. It runs entirely inside the server's own transaction and produces the same result every time it is given the same inputs, which is precisely the property that makes proof-carrying merges meaningful in the first place: a rule that sometimes fired differently for reasons nobody could explain would not be a rule worth trusting. An organisation can run CelinQ with external AI switched off entirely — the default posture — or in full sovereign mode with no external AI reachable at all, and every conflict-resolution guarantee described here holds exactly the same either way. Where AI does have a role, it is strictly downstream of Fusion's own decision about what is F0, F1, or F3: for the F3 cases that already require a human, an optional recommendation can be offered to help that person decide faster, never to decide on their behalf, and only when a workspace administrator has explicitly enabled it. The governance and data-handling model behind that optional layer, including sovereign and customer-hosted deployment patterns for organisations that cannot permit any external AI call at all, is covered in secure AI for enterprise architecture and sovereign and customer-hosted AI deployment patterns, and the complete end-to-end workflow that shows exactly where a human approval gate sits between any AI suggestion and a canonical revision is walked through in from prompt to production model.
The core claim of this article is narrower than it might sound, and the narrowness is deliberate: not "conflicts have been solved," but "the great majority of what looks like a conflict was never a real disagreement, and the system can now tell the difference reliably, deterministically, and with a rule it can name." The remaining genuine disagreements do not disappear. They are found precisely, preserved completely, and handed to a person with everything they need to decide — nothing more is claimed, and nothing less is delivered.
The measured evidence
Claims about merge behaviour are cheap to make and expensive to verify, so it is worth being specific about what has actually been tested rather than asserted. Fusion was exercised through a seeded, reproducible benchmark of 100,000 operations pushed by five concurrent simulated clients through the real storage engine and the real merge pipeline — the identical code path a live Enterprise Architect client's synchronisation takes, nothing simplified or mocked for the purpose of the test. Across that run, roughly seven in ten of the operations that genuinely collided on the same entity were resolved automatically under a named, inspectable rule; the remainder were correctly recognised as ambiguous and surfaced as capsules rather than resolved by guesswork. Every one of the five simulated clients converged to an identical final state when replayed independently from its own perspective and compared against the canonical server state, entity by entity. Zero operations were silently lost. Zero deleted elements resurrected. This is not a claim to take on faith; the full methodology, including exactly what was measured and how the workload was constructed to manufacture unusually dense collisions on purpose, is published, and any organisation evaluating a merge engine — CelinQ's or anyone else's — should expect the same standard of published method before trusting a headline number.
The honest limits
This approach earns its trust by being precise about what it does not claim. Genuine semantic disagreements — two architects who each, in good faith, believe a different name, status, or classification is correct — are not resolved by any of this machinery, and they should not be; that decision belongs to the people who understand the domain, not to a merge engine, however sophisticated. What Fusion promises is narrower and, for exactly that reason, more trustworthy: it will combine everything that can be combined without ambiguity, it will never silently discard or override either side's honest work to make a conflict disappear, and it will show precisely and only the specific points that genuinely need a human's judgement.
Concurrent pushes are currently reconciled pairwise against the latest canonical head rather than as a single simultaneous many-way comparison, which means correctness and convergence hold — proven at the five-client scale of the benchmark — even though a true simultaneous N-way visual diff across a much larger number of concurrently active authors remains a harder visualisation problem than the underlying merge logic itself, and is not yet a shipped capability. And a repository's very first connection to a workspace matters: entities with no recorded causal base — most commonly, older data migrated in from before this machinery existed — are handled conservatively, flagged for a person rather than merged against a base that was never actually captured, because a system that quietly guessed at a missing base would be trading a small, known limitation for an unknown and much worse one.
None of this replaces the judgement of the people building the model. What it replaces is the false choice teams have lived with for years: either lock the model down tightly enough that real conflicts cannot happen, at the cost of exactly the freedom that makes a shared model worth building together in the first place, or let people work concurrently and accept that a meaningful share of that work will be lost, overwritten, or painstakingly reconstructed by hand after the fact. Neither of those was ever the only option. It was simply the only option available to a system that could not tell a false conflict from a real one.