In response to Sergiy Yevtushenko's "The Quiet Consensus" and "Java Backend Design Technology: A Process-First Methodology"
Sergiy Yevtushenko's two recent articles make a concrete empirical observation: practitioners from F#, Rust/TypeScript, Java, Scala, and .NET have independently arrived at a shared structural insight about software decomposition. The insight is that processes — not data entities — are the more natural primary unit. Each practitioner he cites — Scott Wlaschin, Rico Fritzsche, Roman Weis, Sandro Mancuso, Jimmy Bogard, Debasish Ghosh — arrived at this conclusion from within their own tradition, without coordinating, solving problems at different scales and in different domains.
Independent convergence of this kind is methodologically significant. It suggests that the structural insight is not an artifact of a particular language or paradigm, but a response to a genuine property of the design problem itself. The problem, as Sergiy frames it, is that entity-first decomposition creates coupling through shared data models, and that coupling grows as the system grows. Process-first decomposition scopes data types to the processes that use them, so that changes in one process's requirements do not propagate through another process's code.
I have been developing a framework — the Independent Variation Principle (IVP) — that approaches the same structural territory from a different angle. This article examines where the two approaches meet, where they differ, and what each contributes.
The process-first framework
Sergiy's eight-question framework extracts a process structure from a feature description: what triggers the process, what data it needs, what success and failure look like, what its steps are, which steps depend on each other, whether there are conditional paths, and whether there is collection processing. The answers produce typed inputs, typed outputs, typed failure modes, step interfaces, and a dependency structure among the steps.
The dependency structure is the key output. Steps whose outputs are independent of each other can be composed in parallel. Steps where one requires the output of another must chain sequentially. The resulting composition — expressed as a data dependency graph using three operators (Sequential, ALL, ANY) — maps to code. Sequential becomes flatMap. ALL becomes a fork-join. ANY becomes a fallback that takes the first successful result.
The knowledge-gathering framing underlying this methodology has a structural consequence that extends beyond the surface description. Each step acquires a piece of knowledge. The process ends when enough knowledge has accumulated to formulate a response — success if the knowledge supports it, failure otherwise. A declined payment is not a mechanical error; it is a learned fact, and the process's response to it is structurally the same as its response to a successful payment, just with a different answer. This makes the semantics of failure modes explicit in the composition rather than leaving them as exception handling layered over a happy path.
The consequence for data modeling follows directly: rather than asking what data exists in the system, you ask what this process needs to know. Types are scoped to processes. Entities emerge afterward as the intersection of processes that need the same persistent facts. To use Sergiy's seat example: what booking needs to know about a seat differs from what pricing needs to know, which differs from what reservation management needs to know. A shared entity that serves all three is a compromise that fits none of them precisely.
The Independent Variation Principle
IVP starts from a different question: what causes each element of a software system to require modification? For each element, there is a set of change drivers — domain rules, regulations, operational constraints, anything that, when it changes, forces that element to change. The principle states that elements with the same set of change drivers belong in the same module, and elements with different sets belong in different modules.
Formally, this is a mapping Γ from elements to their driver sets. Two elements e and e′ belong in the same module if and only if Γ(e) = Γ(e′). The module structure that satisfies this condition is the partition of the element set induced by driver-set equality. This partition is unique given a fixed driver assignment, and it is a fact about the causal structure of the domain rather than a design preference.
The practical consequence is that IVP provides a criterion for adjudicating boundary decisions. When two engineers disagree about whether two elements belong together, the disagreement can be localized: instead of arguing about whether the boundary feels right, they are arguing about whether the elements share change drivers. That is a question domain expertise can investigate, and it is a question to which there is a fact of the matter.
Where the two frameworks meet
Both frameworks address the question of which elements of a software system should be grouped together and which should be separated. Sergiy's framework identifies what each process needs and scopes types accordingly. IVP asks what causes each element to change and groups by driver-set equality. The two approaches converge on the same structural observation: elements whose change is driven by independent forces should be separated, and elements driven by the same forces should be grouped.
The "entities are discovered, not invented" claim in process-first design maps onto what IVP would predict from driver analysis. Two processes share a persistent type when they share facts about the world governed by the same change drivers. If the price of a product changes for the same reasons regardless of which process queries it, the price data has a single driver set and belongs in a single location. If what booking calls a "seat" changes for logistics reasons and what pricing calls a "seat" changes for revenue management reasons, those are different driver sets, and the shared entity is a coupling that will surface as a coordination cost when either driver changes.
The knowledge-gathering framing and the driver analysis framing are also consistent at a deeper level. Knowledge is acquired by a process because the process needs facts about the world to formulate its response. Those facts are governed by domain rules, regulations, and operational constraints — precisely the forces IVP formalizes as change drivers. A process that needs to know whether a customer's credit score qualifies them for a loan is sensitive to credit scoring rules; if those rules change, the process changes. The two descriptions refer to the same underlying causal structure.
Where the two frameworks diverge
The eight-question framework is primarily an elicitation tool. Given a feature description, it extracts a process structure: the types, the failure modes, the steps, and the dependency graph among the steps. For most of the questions, the extraction is fairly direct. Question 6 — which steps depend on each other — requires more judgment, and this is where the frameworks diverge in what they offer.
Determining step dependencies requires knowing the causal relationships among the pieces of knowledge the process is acquiring. Sometimes this is unambiguous. Validation must precede inventory checking because the inventory check needs to know what was requested. Other cases are less clear. Whether fraud detection runs in parallel with payment processing or gates it depends on the failure semantics of the system — on what the process is supposed to do if fraud is detected while payment is being processed — and on operational constraints that may not be stated in the feature description. Two engineers reading the same requirements may answer question 6 differently, and both compositions may satisfy the stated requirements while behaving differently under failure.
IVP does not resolve this question directly either, but it provides a lens for examining it. If fraud detection changes for regulatory compliance reasons and payment processing changes for financial settlement reasons, their driver sets are different. The question of how they should be composed then becomes a question about the protocol between two independently varying modules — a question about interface design rather than step ordering. The driver analysis does not determine whether to run them in parallel or sequentially, but it identifies that the design goal should be to minimize coupling between them, because they will change for different reasons and at different times.
What the two approaches contribute to each other
Process-first design contributes an elicitation methodology: a set of questions that, applied to a feature description, extracts a process structure that can be encoded in types and compositions. The data dependency graph notation makes the dependency structure explicit in a form readable by both developers and domain experts. The three operators — Sequential, ALL, ANY — cover the structural cases that arise in practice.
IVP contributes an adjudication criterion: a way to evaluate proposed boundaries by asking whether the elements on each side of the boundary share change drivers. This is useful when elicitation produces ambiguous results, when a proposed boundary is challenged, or when a composition has evolved over time and its original rationale is no longer clear.
The two approaches are compatible and, in practice, complementary. A team doing process-first design and arriving at a contested step boundary can apply driver analysis to determine whether the proposed boundary reflects genuine causal independence in the domain. A team doing driver analysis and trying to understand what types and compositions a boundary implies can use the process-first framework to elicit the process structure from requirements.
Neither framework tells you what the change drivers actually are. Driver analysis consumes a driver assignment and produces a partition — it does not produce the driver assignment from a requirements description. The eight-question framework extracts a process structure from a feature description — it does not tell you at what granularity to define the steps, or when two candidate steps should be merged or split. Both frameworks shift the locus of judgment from "what structure feels right?" to "what are the causal facts about this domain?" That shift is their shared contribution. Causal facts can be investigated with domain experts and updated as understanding develops. Structural intuitions about what feels right cannot be grounded in the same way.
The convergence Sergiy documents across languages points toward a structural insight that both frameworks are approaching from different directions. The insight is that software boundaries should track causal independence in the domain. Process-first design operationalizes this by asking what each process needs to know. IVP operationalizes it by asking what causes each element to change. That they arrive at the same structural territory from different starting points is additional evidence that the territory is real.
Sergiy Yevtushenko's articles: The Quiet Consensus · Java Backend Design Technology
Independent Variation Principle (Preprint): doi.org/10.5281/zenodo.17677315
Top comments (0)