CelinQ Insights · No. 49

62 Technical Conflicts, One Human Decision: Root-Cause Conflict Grouping for EA Models

Most of a big cascading conflict is noise a good merge engine should never show you. What is left over deserves to be recognisable as one story, not sixty.

A NILUS perspective on collaborative modelling for Sparx Enterprise Architect

Imagine a package called Legacy Invoicing, deep in an old part of a client's application landscape. It contains an interface, six components, four connectors linking those components to each other and to the rest of the model, three diagrams that place various pieces of it, and a scattering of tagged values recording ownership and lifecycle status across all of it. During a portfolio cleanup, an architect deletes the whole package in one operation. Meanwhile, a colleague who has been offline for two days was, unknown to anyone, quietly finishing up documentation on two of those six components — correcting a tagged value on one, adding a retirement note to the other — and had also moved a third component into a slightly different subpackage as part of a tidy-up, and created a brand-new supporting component with a connector into an existing one, to cover a gap they had noticed. Reconnect that laptop, and a crude comparison of "everything that changed" would show something like sixty-two touched rows scattered across the deleted subtree: every element, every connector, every diagram, every tagged value that lived anywhere underneath Legacy Invoicing. The number is illustrative, not a measured statistic — but the shape of the problem it illustrates is entirely real, and any team that does periodic architecture cleanup while people travel will eventually meet a version of it.

Why a single deletion cascades so widely

The reason one action can touch so much is structural, not accidental. A package is a container, and everything it contains is, in some sense, downstream of it: every child element lived under it, every connector that touched one of those elements referenced it, every diagram that placed one of those elements or connectors depended on it being there, and every tagged value attached to any of that content travels with it. Delete the container and, from the point of view of a system that only knows how to compare "did this row change," essentially everything beneath it looks different from how it looked a moment ago. A tool built around whole-file or whole-subtree comparison has no way to distinguish a deletion's ordinary, uncontroversial ripple effects from a handful of genuine, competing intentions sitting inside that ripple. It would show you all sixty-two rows and ask you to make sense of them yourself.

What Fusion actually looks at

CelinQ's Fusion engine never compares subtrees. It compares individual entities, and within each entity, individual merge atoms, exactly as described in the earlier piece on why an element-level conflict is usually too large. This single design choice does almost all of the real compression work in this scenario, well before anything resembling a "grouping" feature enters the picture. Of the six components under Legacy Invoicing, four were never touched by the offline colleague at all during the window in question. For those four, there is no competing intention to protect — nobody has an unsynchronised change sitting against them — so they are simply deleted along with their parent, cleanly, with no capsule raised and nothing for a human to review. The same is true of the tagged values, connectors and diagram placements attached to those four untouched components: they ripple down with the deletion because there is genuinely nothing in dispute about them. A crude "everything under here changed" view would have flagged all of it. Fusion correctly recognises that the overwhelming majority of that fan-out was never actually contested.

What is actually left

What remains is small and specific. The two components the offline colleague edited — one with a corrected tagged value, one with a new retirement note — each collide with the deletion in exactly the way described in the earlier piece on the resurrection problem, and each raises its own TombstoneConflict capsule, evidence attached. The component that was moved into a different subpackage during the same window is a slightly different case again: because the move touched only the tree-parent atom of an element that has since been deleted from its original location, this too resolves as a tombstone-and-move collision, surfaced for review rather than silently applied or silently discarded. The newly created component and its connector, having never existed in the canonical workspace before this push, fall under the Rescue Zone mechanism covered in the previous article, preserved intact rather than either deleted along with a parent they never really belonged to or resurrected against the parent's wishes. Out of sixty-two touched rows, then, the number of entities that genuinely need a human decision is four: two tombstone collisions, one moved-and-deleted collision, and one rescued creation. The rest of the fan-out — every untouched component, every connector and diagram attached only to those untouched components, every tagged value nobody was fighting over — required no decision at all, because it was never actually contested.

A comparison worth making: what this would look like as a text diff

Anyone who has resolved a large merge conflict in a source-code repository has an intuitive feel for how badly this can go, and it is worth making the comparison explicit, because it explains why the atom-level approach matters so much more here than it might first appear. A line-based merge tool comparing two versions of a serialized model file would see the deleted package's descendants as a block of removed lines on one side and a block of modified or added lines on the other, tangled together in whatever order the file happened to serialize them. It has no concept of "this line is a tagged value on an untouched component" versus "this line is the one field anyone actually disagreed about" — every line is just a line, and the tool's only tool is textual proximity. Anyone who has tried to resolve a merge conflict in a large generated file, where genuine logic changes sit interleaved with cosmetic reordering nobody cares about, knows how quickly that experience turns into scanning past screens of irrelevant noise to find the two or three lines that actually matter. A model is worse than code for this purpose, not better, because a model's internal structure — packages containing elements containing tagged values, connectors referencing elements by position in a serialized dump — has none of the line-oriented regularity that makes source-code diffing tractable in the first place. Treating a model change as a text diff does not just produce more noise than treating it as a set of typed, identity-tracked facts; it produces noise that is actively harder to read, because the structure that would help a human orient themselves has been flattened away.

Root-cause visibility, even without a single button

It would overstate things to claim CelinQ collapses those four remaining capsules into one clickable decision today, and this article is not going to claim that. What it does do is make the shared cause of those four capsules obvious the moment a reviewer looks at them. Each capsule carries its own evidence — the base state, the local state, the remote state, and the specific rule or capsule kind that explains why it needed attention — and in this scenario, all four independently name the same deleted parent, the same deletion revision, and roughly the same timing. In the Control Plane's Fusion view, where open decisions and recent auto-merges are listed together, a reviewer scanning that short list does not need to be told these four are related; the evidence tells them so on its own. What today's mechanism does not yet do is let that reviewer act on all four with a single motion. Each capsule is still opened, reviewed and resolved individually, even when the answer to all four turns out to be the same — "yes, the cleanup was right, move the surviving work into the replacement package."

The real compression in this story happens before any human ever opens the Fusion view: fifty-eight of the illustrative sixty-two touched rows were never a conflict to begin with, because nobody had an unsynchronised change sitting against them. The four that remain are a genuinely small number of decisions — they are just not yet a single click.

Where the human decision genuinely does compress

There is a real sense, though, in which the decision compresses even without a bulk-resolve button, and it is worth naming precisely rather than either overselling or dismissing it. The cognitive work of resolving these four capsules is not four independent judgement calls; it is one judgement call — "was the Legacy Invoicing cleanup correct, and if so, where should the surviving offline work land" — applied consistently four times. A reviewer who has understood the root cause from the first capsule they open is not starting from zero on the second, third and fourth; they are confirming the same conclusion against slightly different evidence each time. That is a meaningfully lighter task than four genuinely unrelated conflicts would be, even though the interface still asks for four separate clicks. The distinction matters because it is the honest version of the promise in this article's title: the thinking compresses to one decision well before the clicking does.

A pile of conflicts that all trace back to the same root cause is not the same problem as a pile of conflicts that are all genuinely different from each other, even when both piles are the same size. Recognising the difference is most of what makes the smaller pile manageable.

What isn't automated yet, said plainly

CelinQ's own engineering documentation is direct about this, and this article should be equally direct rather than letting an SEO-friendly title imply more than the product currently does. Bulk intent grouping — recognising that a set of individual operations was really one coherent action, like "move this whole subtree," and presenting it as such — currently records the individual operations that make it up rather than coalescing them into a single grouped capsule. Capsules today are raised and resolved per entity. A workspace administrator working through the four capsules in the scenario above will genuinely open and resolve four items, not one, even though the underlying story is singular. This is worth stating without hedging, because the value of a truthful technical article is precisely that it tells you what is real today and what is direction rather than blurring the two. The direction is clear and the reasoning behind it is sound — grouping correlated capsules by shared root cause, so a reviewer can apply one resolution across all of them at once, is a natural and valuable extension of a mechanism that already does the harder, less visible part of the compression work. It is not yet a shipped capability, and a fair article about this feature says so rather than implying a bulk-resolve button exists when it does not.

Why the atom-level compression matters more than a grouping button would

It is tempting to treat the missing bulk-resolve step as the headline gap, but it is worth resisting that framing, because the compression that already exists is doing the bulk of the useful work, and a grouping button without it would not actually help very much. Picture the counterfactual: a system that raised a capsule for every one of the sixty-two touched rows, and then offered a "resolve all sixty-two together" button. That button would be dangerous, not convenient, because it would be asking a reviewer to apply one blanket decision across rows that include genuine, unrelated disputes buried inside the noise — the four real collisions hidden among fifty-eight rows that were never actually contested. The correct order of operations is the one CelinQ already applies: first, use atom-level classification to eliminate every row that was never genuinely in dispute, so that what remains is small enough to actually read; only after that reduction does it make sense to talk about grouping what is left by shared cause. Grouping fifty-eight uncontested rows together with four contested ones would be worse than not grouping at all. Grouping four already-isolated, already-evidenced capsules that share an obvious root cause is a much smaller and much safer step — which is exactly why it is the sensible next one rather than a foundational requirement the current design is missing.

What the numbers say about the general pattern

The Legacy Invoicing scenario is a hand-picked illustration, chosen to be easy to follow, but the underlying pattern it demonstrates is not a story CelinQ has to ask you to take on faith. The Fusion benchmark referenced elsewhere in this series pushes a hundred thousand operations through the real store and merge pipeline from five concurrent simulated clients, seeded and fully reproducible, deliberately engineered to manufacture far denser collisions than an ordinary working team would ever produce — the test workload reuses a handful of shared tagged-value keys across a thousand elements specifically to force more contention than real modelling generates. Even under that artificially hostile load, roughly seven in ten of the operations that turned out to be genuinely concurrent were resolved automatically, without a human decision, because the atom-level classification correctly recognised that most of them touched disjoint facts rather than the same one. The remainder — the genuine collisions — were the ones surfaced as capsules, with the invariants that matter most held throughout the entire run: zero silent loss of anyone's work, zero unwanted resurrection of anything that had been deleted, and every client converging afterwards to an identical final state. A benchmark deliberately built to be harder than reality, showing that most apparent conflict is not real conflict, is exactly the same shape of finding as the Legacy Invoicing example above, just measured at scale instead of illustrated by hand. Readers evaluating any vendor's merge claims, CelinQ included, should expect exactly this kind of evidence — a described methodology, a reproducible run, and invariants that are checked rather than assumed — rather than a bare percentage asserted without a way to verify it.

What this means for teams planning a large cleanup

There is a practical takeaway here for any team about to run a portfolio rationalisation, a package restructuring, or any other exercise that deletes a meaningful chunk of a shared model. The temptation, understandably, is to schedule the deletion for a quiet week and hope nobody is offline doing conflicting work at the time — the same informal coordination habit that locking-based tools have always relied on and that this series has argued, repeatedly, does not survive contact with a distributed, travelling team. A more realistic approach is to expect that some capsules will appear after a large deletion, budget a short review session for them rather than being surprised by them, and use the evidence each capsule carries to move through them quickly rather than trying to prevent them from ever occurring. Because the number of capsules a deletion like this produces scales with how much genuinely concurrent, conflicting work was happening underneath it — not with the size of the subtree being deleted — a well-scoped cleanup of an already-quiet, already-deprecated part of the model tends to produce very few capsules in practice, even when the subtree itself is large. The sixty-two-row scenario in this article is illustrative precisely because it assumes an unusually active colleague working inside a package that was about to be retired; a genuinely dormant package produces close to nothing to review at all.

Auditability across the cascade

Every one of the four capsules in this scenario, resolved individually or not, becomes part of the same ordered revision history as everything else CelinQ tracks. Nothing about the cascade is summarised away or lost in translation between "sixty-two rows changed" and "four decisions were made." Months later, an architect reconstructing why Legacy Invoicing looks the way it does today — which parts were retired outright, which survived under a new name, which were recreated fresh — can trace every one of those outcomes back to a specific capsule, a specific reviewer, and a specific piece of evidence, the same traceability discipline covered more broadly in the earlier piece on keeping a model's history honest. A grouped, one-click resolution in some future version of this mechanism would still need to preserve that same granularity underneath the surface, recording each individual decision even while presenting them together — because compressing the audit trail down to "resolved in bulk, no further detail" would trade away exactly the property that makes any of this trustworthy in a regulated environment.

CelinQ Control Plane audit trail showing a fusion.resolved event with resolution=keep-local, alongside ai.config and workspace.created entries.
The Control Plane's audit trail. Every capsule resolution, automatic or human, lands here as a permanent, attributable event — this is a demonstration workspace with fictional content, used to illustrate the interface.

The honest limits

The plain summary is this: CelinQ already prevents the worst version of this problem, which is a reviewer being handed sixty-two undifferentiated changed rows and asked to make sense of them unaided. Atom-level classification means the vast majority of a cascading deletion's fan-out is never shown to anyone at all, because it was never in dispute. What remains is a small, evidenced, individually-resolvable set of capsules that, in a realistic scenario like the one above, usually share an obvious common cause a reviewer can recognise at a glance. What CelinQ does not yet offer is a single action that resolves a whole correlated cluster of capsules at once, and a workspace that does frequent large deletions alongside frequent offline work should expect to spend a few minutes moving through a handful of related capsules individually rather than clearing them in one motion. That is a real, current limitation, not a hidden one, and it is the honest note this article ends on: the hardest part of this problem — telling a genuine conflict apart from ordinary noise — is already solved. The remaining part — turning "four related decisions" into "one click" — is a direction the product is heading, not a claim it makes about itself today.

It is worth ending on why that ordering of priorities was the right one to solve first. A grouping button bolted onto a system that still raised sixty-two capsules for every large deletion would have been a worse product than the one described here, because it would have hidden the real cost of the noise problem behind a slightly more convenient way of clicking through it. Solving the classification problem first — making sure a capsule only ever appears when something genuinely needed a person's judgement — is what makes the eventual grouping feature worth building at all, because it means that feature will only ever have to group a small number of already-meaningful decisions rather than trying to make sense of a much larger pile that should never have been shown to anyone in the first place.