{"id":132,"date":"2026-03-13T23:59:26","date_gmt":"2026-03-13T23:59:26","guid":{"rendered":"https:\/\/harmonic-framework.com\/whitepapers\/volatility-based-decomposition\/"},"modified":"2026-04-12T00:47:41","modified_gmt":"2026-04-12T05:47:41","slug":"volatility-based-decomposition","status":"publish","type":"page","link":"https:\/\/harmonic-framework.com\/es\/whitepapers\/volatility-based-decomposition\/","title":{"rendered":"Volatility-Based Decomposition (VBD) in Software Architecture"},"content":{"rendered":"<h1 id=\"volatility-based-decomposition-vbd-in-software-architecture\">Volatility-Based Decomposition (VBD) in Software Architecture<\/h1>\n<p><em>Organizing Architecture Around Anticipated Change: A Practitioner-Oriented Articulation<\/em><\/p>\n<p><strong>Author:<\/strong> William Christopher Anderson<br \/>\n<strong>Date:<\/strong> April 2026<br \/>\n<strong>Version:<\/strong> 1.0<\/p>\n<hr \/>\n<h2 id=\"executive-summary\">Executive Summary<\/h2>\n<p>Modern software systems rarely fail because of poor initial design; they fail because change accumulates faster than the architecture can absorb it. Volatility-Based Decomposition (VBD) addresses this problem by treating change as the primary organizing force in system design.<\/p>\n<p>Rather than decomposing systems solely by domain concepts or technical layers, VBD organizes architectural boundaries around anticipated sources of volatility \u2014 functional change, non-functional pressures, cross-cutting concerns, and environmental dependencies. By aligning components with these forces, systems can evolve without widespread refactoring.<\/p>\n<p>At a practical level, VBD applies established component roles:<\/p>\n<ul>\n<li><strong>Managers<\/strong> coordinate workflow and intent and remain stable over time.<\/li>\n<li><strong>Engines<\/strong> encapsulate business rules, computation, and transformation logic that change more frequently.<\/li>\n<li><strong>Resource Accessors<\/strong> isolate interactions with databases, external services, vendors, and infrastructure.<\/li>\n<li><strong>Utilities<\/strong> encapsulate cross-cutting capabilities such as logging, monitoring, security, and observability, allowing these concerns to evolve independently without contaminating core business logic.<\/li>\n<\/ul>\n<p>These roles are reinforced through explicit communication rules and validated against a small number of core use cases. Over time, this approach localizes change, reduces unintended coupling, and preserves architectural integrity even as systems and organizations grow.<\/p>\n<p>VBD is most effective in long-lived systems, platform architectures, and integration-heavy environments where change is constant and unavoidable. It provides architects and senior engineers with a clear, practical reference for applying volatility-first architectural thinking at scale.<\/p>\n<hr \/>\n<h2 id=\"abstract\">Abstract<\/h2>\n<p>Modern software systems operate in environments defined by continuous change \u2014 shifting business requirements, evolving user expectations, regulatory pressure, and rapid technological advancement. Traditional architectural decomposition techniques often fail to account explicitly for change as a primary design force, resulting in brittle systems that degrade over time. Volatility-Based Decomposition (VBD) is an architectural approach that treats change as a first-class concern by identifying, classifying, and isolating areas of anticipated volatility within a system. This paper presents a structured articulation of Volatility-Based Decomposition, covering functional and non-functional volatility, cross-cutting concerns, core use cases, and component role definition. By aligning architectural boundaries with volatility axes, VBD supports the design of flexible, maintainable, and evolvable software systems. The articulation emphasizes modularity, explicit communication rules, and continuous architectural evaluation, providing architects and senior engineers with a practical reference for applying VBD consistently in long-lived systems.<\/p>\n<hr \/>\n<h2 id=\"1-introduction\">1. Introduction<\/h2>\n<p>Software architecture exists to manage complexity over time. While many architectural approaches focus on current functional requirements, the dominant force acting on long-lived systems is change. Business models evolve, regulations shift, infrastructure platforms are replaced, and user expectations rise. Architectures that do not explicitly account for these forces tend to accumulate coupling, resist modification, and require costly refactoring or replacement.<\/p>\n<p>Volatility-Based Decomposition (VBD) addresses this problem by treating change \u2014 not functionality \u2014 as the primary driver of architectural structure. Rather than decomposing systems solely by domain concepts or technical layers, VBD decomposes systems along axes of anticipated volatility. This approach enables architects to localize the impact of change, reduce unintended coupling, and preserve system integrity as requirements evolve.<\/p>\n<p>This paper provides a practitioner-oriented articulation of VBD. It describes how to identify volatility, align components to volatility boundaries, apply established component roles and communication rules, and validate architectural decisions over time.<\/p>\n<p>Business strategy evolves continuously. Markets shift. Regulations change. Competitive pressures emerge without warning. To manage this complexity, organizations naturally structure themselves around functional responsibilities such as Sales, Operations, Finance, and Compliance. This functional decomposition brings clarity of ownership, accountability, and decision-making authority.<\/p>\n<p>Software systems frequently mirror this structure. Teams, codebases, and modules are aligned to functional domains in an attempt to reflect how the business operates. Early in a system&#8217;s life, this alignment can be effective, as changes tend to be localized and coordination costs remain manageable.<\/p>\n<p>Over time, however, tension emerges. The business adapts quickly, while software systems resist change. Most meaningful changes cut across functional boundaries rather than remaining contained within them. Enhancements require coordination across teams and components. Small adjustments trigger broad testing cycles. Risk increases as more parts of the system must move together.<\/p>\n<p>This divergence exposes a fundamental mismatch: while organizations decompose for accountability, volatility does not respect functional boundaries. Volatility-Based Decomposition addresses this mismatch by aligning architectural boundaries with change dynamics rather than organizational structure alone.<\/p>\n<hr \/>\n<h2 id=\"2-background-and-architectural-foundations\">2. Background and Architectural Foundations<\/h2>\n<p>Volatility-Based Decomposition builds upon established architectural principles, including separation of concerns, information hiding, modularity, and loose coupling. Classic decomposition strategies \u2014 such as layered architectures, service-oriented architectures, and microservices \u2014 implicitly attempt to manage change by isolating responsibilities. However, these approaches often rely on static assumptions about where change will occur.<\/p>\n<p>VBD makes these assumptions explicit. It acknowledges that not all parts of a system change at the same rate or for the same reasons. By identifying which aspects of a system are most likely to change, architects can proactively structure boundaries that align with those forces, rather than reacting after change has already caused architectural erosion.<\/p>\n<hr \/>\n<h2 id=\"3-defining-volatility-in-software-systems\">3. Defining Volatility in Software Systems<\/h2>\n<p>For the purposes of this paper, volatility is defined as the likelihood that a given system responsibility, requirement, or implementation detail will change over time, along with the frequency and impact of that change.<\/p>\n<h3 id=\"31-functional-volatility\">3.1 Functional Volatility<\/h3>\n<p>Functional volatility refers to changes in system behavior driven by evolving business needs, user feedback, or regulatory requirements. Examples include the addition of new features, modification of existing workflows, or removal of obsolete functionality. Functional volatility is most commonly associated with core use cases and domain logic.<\/p>\n<h3 id=\"32-non-functional-volatility\">3.2 Non-Functional Volatility<\/h3>\n<p>Non-functional volatility concerns changes to system qualities such as performance, scalability, reliability, security, and maintainability. These changes are often driven by external forces, including infrastructure upgrades, platform migrations, or increased usage demands.<\/p>\n<h3 id=\"33-cross-cutting-volatility\">3.3 Cross-Cutting Volatility<\/h3>\n<p>Cross-cutting concerns \u2014 such as logging, monitoring, authentication, authorization, and error handling \u2014 exhibit volatility that spans multiple components. Changes to these concerns can have widespread impact if not properly isolated.<\/p>\n<h3 id=\"34-environmental-and-infrastructure-volatility\">3.4 Environmental and Infrastructure Volatility<\/h3>\n<p>Infrastructure platforms, third-party services, deployment models, and hosting environments are subject to frequent change. Treating these elements as stable foundations often leads to tight coupling between business logic and infrastructure details.<\/p>\n<p><em>Figure 1 \u2014 The Four Axes of Volatility and the Component Roles That Encapsulate Them: each role addresses a primary axis of volatility, but the roles work in union \u2014 the Manager orchestrates the what, the Engine executes the how, the Resource Accessor isolates the where, and the Utility provides the with-what. No single role contains all change; the four together localize change across every axis.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">graph TB\n    subgraph axes[&quot;Axes of Volatility&quot;]\n        FV[&quot;Functional&lt;br\/&gt;&lt;em&gt;What changes \u2014 workflows and rules&lt;\/em&gt;&quot;]\n        NF[&quot;Non-Functional&lt;br\/&gt;&lt;em&gt;Performance, scalability, reliability&lt;\/em&gt;&quot;]\n        CC[&quot;Cross-Cutting&lt;br\/&gt;&lt;em&gt;With what shared capabilities&lt;\/em&gt;&quot;]\n        EV[&quot;Environmental&lt;br\/&gt;&lt;em&gt;Where data lives and flows&lt;\/em&gt;&quot;]\n    end\n\n    subgraph roles[&quot;Component Roles \u2014 Working in Union&quot;]\n        MGR[&quot;Manager&lt;br\/&gt;The &lt;strong&gt;What&lt;\/strong&gt;&lt;br\/&gt;Stable functional layer \u2014 orchestrates workflow&quot;]\n        ENG[&quot;Engine&lt;br\/&gt;The &lt;strong&gt;How&lt;\/strong&gt;&lt;br\/&gt;Volatile functional layer \u2014 executes business logic&quot;]\n        ACC[&quot;Resource Accessor&lt;br\/&gt;The &lt;strong&gt;Where&lt;\/strong&gt;&lt;br\/&gt;Isolates external boundaries&quot;]\n        UTL[&quot;Utility&lt;br\/&gt;The &lt;strong&gt;With What&lt;\/strong&gt;&lt;br\/&gt;Provides cross-cutting capabilities&quot;]\n    end\n\n    FV -.-&gt;|stable layer| MGR\n    FV -.-&gt;|volatile layer| ENG\n    EV -.-&gt;|primary axis| ACC\n    CC -.-&gt;|primary axis| UTL\n    NF -.-&gt;|addressed across all roles| MGR\n    NF -.-&gt;|addressed across all roles| ACC\n\n    MGR --&gt;|invokes| ENG\n    MGR --&gt;|invokes| ACC\n    ENG --&gt;|may call| ACC\n\n    UTL -.-&gt;|consumed by all| MGR\n    UTL -.-&gt;|consumed by all| ENG\n    UTL -.-&gt;|consumed by all| ACC\n\n    style FV fill:#f0f4ff,stroke:#0053e2,color:#0053e2,stroke-width:2px\n    style NF fill:#fff8e0,stroke:#e6a800,color:#333,stroke-width:2px\n    style CC fill:#f0fff0,stroke:#76c043,color:#333,stroke-width:2px\n    style EV fill:#e8f5e9,stroke:#2a8703,color:#2a8703,stroke-width:2px\n    style MGR fill:#0053e2,color:#fff,stroke-width:0px\n    style ENG fill:#ffc220,color:#000,stroke-width:0px\n    style ACC fill:#2a8703,color:#fff,stroke-width:0px\n    style UTL fill:#76c043,color:#000,stroke-width:0px\n<\/code><\/pre>\n<hr \/>\n<h2 id=\"4-identifying-core-use-cases-and-volatility-axes\">4. Identifying Core Use Cases and Volatility Axes<\/h2>\n<p>The first step in volatility analysis is identifying core use cases \u2014 the high-level behaviors that define the system&#8217;s purpose. Core use cases provide the context necessary to evaluate where change is most likely to occur.<\/p>\n<p>The term <em>core use case<\/em> is intentionally narrow. In practice, even very large organizations tend to have a surprisingly small number of truly core use cases \u2014 often fewer than five. These represent the fundamental value-producing behaviors of the system, not the many procedural variations that surround them.<\/p>\n<p>While business analysts may document dozens or even hundreds of use cases, the majority are not architecturally core. They are alternative paths, conditional flows, exception handling, or policy-driven variants of a much smaller set of essential behaviors. Treating all documented use cases as equal drivers of architecture obscures volatility rather than revealing it.<\/p>\n<p>Architects should identify volatility axes by:<\/p>\n<ul>\n<li>Reviewing existing requirements, user stories, and architectural documentation<\/li>\n<li>Interviewing stakeholders across business, engineering, and operations<\/li>\n<li>Analyzing historical change patterns in similar systems<\/li>\n<li>Considering plausible future business and technology shifts<\/li>\n<\/ul>\n<p>The goal is not to predict exact changes, but to identify where change is likely and why.<\/p>\n<hr \/>\n<h2 id=\"5-volatility-based-decomposition\">5. Volatility-Based Decomposition<\/h2>\n<p>Volatility-Based Decomposition proceeds through the following steps:<\/p>\n<ol>\n<li>Identify core use cases that represent the system&#8217;s primary value.<\/li>\n<li>Enumerate volatility axes across functional, non-functional, cross-cutting, and environmental dimensions.<\/li>\n<li>Classify responsibilities based on their likelihood and drivers of change.<\/li>\n<li>Define architectural boundaries that align with volatility classifications.<\/li>\n<li>Apply established component roles and communication rules to isolate volatile responsibilities from stable ones.<\/li>\n<\/ol>\n<p>This process results in an architecture where change is localized and predictable, reducing the risk of cascading modifications.<\/p>\n<hr \/>\n<h2 id=\"6-component-roles-and-communication-rules\">6. Component Roles and Communication Rules<\/h2>\n<p>Clear component roles and communication rules are essential to preserving volatility boundaries. In addition to Managers, Engines, and Resource Accessors, Volatility-Based Decomposition explicitly recognizes Utilities as a first-class role for isolating cross-cutting volatility. The roles and rules described in this section are derived from Juval L\u00f6wy&#8217;s IDesign methodology and component-oriented architecture teachings.<\/p>\n<p>One aspect of the methodology that is often undervalued is the explicit separation of business logic into two distinct concerns: orchestration and execution. Orchestration governs workflow sequencing, coordination, and intent, while execution encapsulates the business rules and policies that perform the work.<\/p>\n<p>When orchestration logic and execution logic are interwoven within the same unit, they become change-coupled. A modification to workflow sequencing can force changes in business rule implementation, and a modification to business rules can require restructuring the workflow. This tight coupling increases fragility by expanding the blast radius of change and reducing predictability.<\/p>\n<p>By separating orchestration from execution, architectures can absorb these changes independently, allowing workflows and business rules to evolve at different rates without destabilizing the system.<\/p>\n<p>A useful mental model for classifying components is to ask <strong>what<\/strong>, <strong>how<\/strong>, and <strong>where<\/strong>:<\/p>\n<table>\n<thead>\n<tr>\n<th>Role<\/th>\n<th>Question<\/th>\n<th>Concern<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Manager<\/strong><\/td>\n<td><strong>What<\/strong> does the system do?<\/td>\n<td>Orchestration \u2014 workflow, sequencing, intent<\/td>\n<\/tr>\n<tr>\n<td><strong>Engine<\/strong><\/td>\n<td><strong>How<\/strong> does it do it?<\/td>\n<td>Execution \u2014 business rules, calculations, policies<\/td>\n<\/tr>\n<tr>\n<td><strong>Resource Accessor<\/strong><\/td>\n<td><strong>Where<\/strong> does data live?<\/td>\n<td>Integration \u2014 databases, vendors, external systems<\/td>\n<\/tr>\n<tr>\n<td><strong>Utility<\/strong><\/td>\n<td><strong>With what support?<\/strong><\/td>\n<td>Cross-cutting \u2014 logging, auth, monitoring, observability<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>If a unit of work decides <em>what<\/em> happens next, it belongs in a Manager. If it computes <em>how<\/em> to do it, it belongs in an Engine. If it reaches out to <em>where<\/em> data or services live, it belongs in a Resource Accessor. If it supports everything but belongs to no domain, it is a Utility.<\/p>\n<h3 id=\"61-managers\">6.1 Managers<\/h3>\n<p>Managers coordinate operation flow and encapsulate high-level business orchestration. They represent business intent and workflow coordination and should remain stable over time.<\/p>\n<p>Managers <strong>MUST NOT<\/strong> perform heavy computation.<br \/>\nManagers <strong>MUST NOT<\/strong> directly share state.<br \/>\nManagers <strong>MAY<\/strong> communicate with other managers only through queued, fire-and-forget mechanisms.<br \/>\nManagers <strong>MAY<\/strong> invoke engines and resource accessors directly.<\/p>\n<p>Only Managers emit and consume events. Async dispatch, pub\/sub, and queued messaging are Manager-layer concerns. Engines and Resource Accessors operate synchronously within a request.<\/p>\n<p><strong>Illustrative Manager examples:<\/strong><\/p>\n<ul>\n<li><em>Order Processing Manager<\/em> \u2014 Coordinates the lifecycle of an order by sequencing steps such as validation, pricing, fulfillment, and confirmation without embedding business rules.<\/li>\n<li><em>Customer Interaction Manager<\/em> \u2014 Orchestrates user-facing workflows, invoking engines to fulfill intent and translating technical outcomes into business-level results.<\/li>\n<li><em>Batch Execution Manager<\/em> \u2014 Coordinates scheduled or bulk operations by partitioning work, invoking engines per unit of work, and handling workflow-level retries.<\/li>\n<\/ul>\n<p>Managers should not implement business rules, perform data aggregation, or contain persistence or integration logic. Their primary responsibility is to express what the system is trying to accomplish, not how it is achieved.<\/p>\n<h3 id=\"62-engines\">6.2 Engines<\/h3>\n<p>Engines execute complex business rules, transformations, or computationally intensive operations. They encapsulate the logic most likely to change due to policy shifts, experimentation, or optimization.<\/p>\n<p>Engines <strong>MUST NOT<\/strong> communicate with other engines.<br \/>\nEngines <strong>MUST NOT<\/strong> use queued or pub\/sub mechanisms.<br \/>\nEngines <strong>MAY<\/strong> call dependent services directly.<\/p>\n<p><strong>Illustrative Engine examples:<\/strong><\/p>\n<ul>\n<li><em>Pricing Engine<\/em> \u2014 Calculates prices based on rules, tiers, and promotions, evolving frequently as business strategies change.<\/li>\n<li><em>Eligibility or Policy Engine<\/em> \u2014 Evaluates compliance, qualification, or constraint logic driven by regulatory or policy updates.<\/li>\n<li><em>Recommendation or Matching Engine<\/em> \u2014 Performs scoring, ranking, or matching algorithms that change due to tuning or experimentation.<\/li>\n<li><em>Transformation Engine<\/em> \u2014 Converts, normalizes, or enriches data representations without awareness of workflow or persistence.<\/li>\n<\/ul>\n<p>Engines must not coordinate workflows, interact with messaging infrastructure, or embed persistence concerns. They are invoked by managers and remain unaware of the broader execution context.<\/p>\n<h3 id=\"63-resource-accessors\">6.3 Resource Accessors<\/h3>\n<p>Resource accessors manage interaction with persistence layers, external systems, vendors, and infrastructure-facing resources. They isolate environmental and integration volatility from the rest of the system.<\/p>\n<p>Resource accessors <strong>MUST NOT<\/strong> communicate with engines or other resource accessors.<br \/>\nResource accessors <strong>MUST NOT<\/strong> use queued or pub\/sub mechanisms.<br \/>\nResource accessors <strong>MAY<\/strong> call dependent services directly.<\/p>\n<p><strong>Illustrative Resource Accessor examples:<\/strong><\/p>\n<ul>\n<li><em>Order Repository Accessor<\/em> \u2014 Encapsulates database access and schema evolution, shielding the system from persistence changes.<\/li>\n<li><em>External Payment Gateway Accessor<\/em> \u2014 Manages vendor-specific APIs, retries, error translation, and versioning.<\/li>\n<li><em>Messaging or Queue Accessor<\/em> \u2014 Publishes or consumes messages while hiding transport protocols and infrastructure configuration.<\/li>\n<li><em>Configuration or Secrets Accessor<\/em> \u2014 Retrieves environment-specific configuration values without leaking deployment concerns.<\/li>\n<\/ul>\n<p>Resource accessors must not apply business rules, coordinate workflows, or make policy decisions. Their responsibility is to interact with external resources reliably and predictably.<\/p>\n<h3 id=\"64-utilities\">6.4 Utilities<\/h3>\n<p>Utilities encapsulate cross-cutting concerns that apply broadly across the system and evolve independently of business workflows. They are orthogonal to core behavior and should remain free of domain-specific knowledge.<\/p>\n<p><strong>Illustrative Utility Component examples:<\/strong><\/p>\n<ul>\n<li><em>Logging Utility<\/em> \u2014 Provides standardized logging APIs, log formatting, and correlation identifiers without embedding business meaning.<\/li>\n<li><em>Monitoring and Telemetry Utility<\/em> \u2014 Collects metrics, traces, and health signals to support observability without influencing execution flow.<\/li>\n<li><em>Error Classification and Mapping Utility<\/em> \u2014 Normalizes and categorizes errors across components, translating low-level failures into consistent error types.<\/li>\n<li><em>Feature Flag Utility<\/em> \u2014 Enables conditional behavior toggling and experimentation while remaining decoupled from business rules.<\/li>\n<li><em>Security Utility<\/em> \u2014 Supports cryptographic operations, token validation helpers, or hashing functions without making authorization decisions.<\/li>\n<\/ul>\n<p>Utilities must not coordinate workflows, enforce business policy, or directly interact with external systems on behalf of managers or engines. Their role is to provide shared capabilities that reduce duplication while preserving architectural boundaries.<\/p>\n<p><em>Figure 2 \u2014 Component Roles and Communication Rules: illustrates the four component roles in VBD \u2014 Managers, Engines, Resource Accessors, and Utilities \u2014 along with their permitted communication patterns and constraints.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">flowchart TB\n    MGR[&quot;Manager&quot;] --&gt;|invokes| ENG[&quot;Engine&quot;]\n    MGR --&gt;|invokes| ACC[&quot;Resource Accessor&quot;]\n    ENG --&gt;|may call| ACC\n\n    MGR -.-&gt;|consumes| UTL[&quot;Utility&quot;]\n    ENG -.-&gt;|consumes| UTL\n    ACC -.-&gt;|consumes| UTL\n\n<\/code><\/pre>\n<hr \/>\n<h2 id=\"7-core-use-cases-as-architectural-validation\">7. Core Use Cases as Architectural Validation<\/h2>\n<p>Core use cases are end-to-end scenarios that exercise all relevant ancillary behaviors. These core use cases serve as validation mechanisms, ensuring that architectural boundaries support real execution paths without introducing hidden coupling or responsibility leakage.<\/p>\n<p>If a core use case requires bypassing defined communication rules, the architecture should be reconsidered.<\/p>\n<hr \/>\n<h2 id=\"8-continuous-evaluation-and-architectural-evolution\">8. Continuous Evaluation and Architectural Evolution<\/h2>\n<p>Volatility analysis is not a one-time activity. As systems evolve, new volatility axes emerge and existing assumptions may become invalid.<\/p>\n<p>To maintain architectural integrity:<\/p>\n<ul>\n<li>Monitor changes in requirements, infrastructure, and usage patterns<\/li>\n<li>Conduct periodic architectural reviews<\/li>\n<li>Update volatility classifications and component boundaries<\/li>\n<li>Communicate architectural changes clearly to all stakeholders<\/li>\n<\/ul>\n<hr \/>\n<h2 id=\"9-architectural-watchpoints\">9. Architectural Watchpoints<\/h2>\n<p>Volatility-Based Decomposition is most effective when applied intentionally and proportionally. Like any architectural approach, it introduces forces that must be actively managed over time. The following watchpoints highlight areas that warrant ongoing attention rather than serving as hard limitations.<\/p>\n<p><strong>Decomposition Granularity<\/strong><br \/>\nOver-decomposition can increase cognitive overhead and coordination cost. Architects should monitor whether component boundaries continue to align with meaningful volatility axes or whether decomposition has become finer than the rate of change justifies.<\/p>\n<p><strong>Organizational Discipline<\/strong><br \/>\nThe effectiveness of VBD depends on consistent adherence to component roles and communication rules. When these boundaries are eroded \u2014 often in the interest of short-term delivery \u2014 volatility begins to leak across components, reintroducing change coupling.<\/p>\n<p><strong>System Scale and Lifespan<\/strong><br \/>\nSmaller or short-lived systems may not benefit from full application of VBD. Architects should assess expected system longevity and change rate to determine the appropriate level of rigor.<\/p>\n<p><strong>Evolution of Volatility Axes<\/strong><br \/>\nVolatility is not static. Axes that were once stable may become volatile as business strategy, technology, or regulatory environments change. Periodic architectural review is required to ensure boundaries remain aligned with current realities.<\/p>\n<hr \/>\n<h2 id=\"9a-volatility-based-decomposition-in-real-world-systems\">9A. Volatility-Based Decomposition in Real-World Systems<\/h2>\n<p>The principles of Volatility-Based Decomposition are most clearly demonstrated when applied to real, long-lived software systems operating under continuous change. The following examples are intentionally domain-agnostic and generalized, focusing on architectural forces rather than implementation specifics.<\/p>\n<h3 id=\"example-1-long-lived-enterprise-platform\">Example 1: Long-Lived Enterprise Platform<\/h3>\n<p>In large enterprise platforms supporting multiple business units, functional requirements evolve unevenly. Core workflows may remain stable for years, while regulatory logic, reporting requirements, and integration points change frequently.<\/p>\n<p>Applying VBD in this context typically reveals:<\/p>\n<ul>\n<li>Managers remain stable, coordinating high-level workflows and orchestration that change infrequently.<\/li>\n<li>Engines absorb volatility related to business rules, calculations, policy enforcement, and workflow-specific decisioning.<\/li>\n<li>Resource Accessors isolate churn driven by database migrations, schema evolution, vendor swaps, and third-party integrations.<\/li>\n<li>Utilities encapsulate cross-cutting concerns such as auditing and compliance logging, which evolve independently of business logic.<\/li>\n<\/ul>\n<p>This decomposition localizes regulatory- and integration-driven change, preventing widespread refactoring when external requirements shift.<\/p>\n<p><em>Figure 3 \u2014 Core Use Case: Order Processing: demonstrates how a core use case flows through VBD component roles, with Managers coordinating, Engines executing business logic, Accessors handling persistence, and Utilities providing cross-cutting capabilities.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">sequenceDiagram\n    actor Client\n    participant OM as OrderManager\n    participant VE as ValidationEngine\n    participant PE as PricingEngine\n    participant OR as OrderRepository\n    participant PG as PaymentGateway\n    participant LOG as LoggingUtility\n\n    Client-&gt;&gt;OM: submitOrder(orderRequest)\n    OM-&gt;&gt;LOG: log(Order received, correlationId)\n    OM-&gt;&gt;VE: validateOrder(orderRequest)\n    VE--&gt;&gt;OM: ValidationResult\n\n    alt Validation passed\n        OM-&gt;&gt;PE: calculatePrice(orderRequest)\n        PE--&gt;&gt;OM: PricedOrder\n        OM-&gt;&gt;OR: saveOrder(pricedOrder)\n        OR--&gt;&gt;OM: orderId\n        OM-&gt;&gt;PG: processPayment(orderId, amount)\n        PG--&gt;&gt;OM: PaymentConfirmation\n        OM-&gt;&gt;LOG: log(Order complete, orderId)\n        OM--&gt;&gt;Client: OrderConfirmation\n    else Validation failed\n        OM-&gt;&gt;LOG: log(Order rejected, errors)\n        OM--&gt;&gt;Client: ValidationError\n    end\n<\/code><\/pre>\n<h3 id=\"example-2-integration-heavy-or-platform-systems\">Example 2: Integration-Heavy or Platform Systems<\/h3>\n<p>Systems that serve as integration hubs \u2014 connecting internal services, external partners, and third-party APIs \u2014 experience high environmental and infrastructural volatility. APIs version independently, protocols evolve, and reliability characteristics vary widely.<\/p>\n<p>Under VBD:<\/p>\n<ul>\n<li>Managers remain insulated from integration complexity, focusing on orchestration and intent.<\/li>\n<li>Engines handle transformation, enrichment, and aggregation logic without direct exposure to external systems.<\/li>\n<li>Resource Accessors encapsulate protocol translation, retries, circuit breaking, vendor-specific behavior, and API version management.<\/li>\n<\/ul>\n<p>This structure allows integrations to be replaced or upgraded with minimal impact beyond the accessor layer.<\/p>\n<h3 id=\"example-3-rapidly-evolving-product-systems\">Example 3: Rapidly Evolving Product Systems<\/h3>\n<p>Product-focused systems often face intense functional volatility driven by experimentation, user feedback, and market pressure. Performance and scalability concerns may also shift rapidly as adoption grows.<\/p>\n<p>VBD enables such systems to evolve by:<\/p>\n<ul>\n<li>Keeping Managers stable, preserving workflow integrity and orchestration even as underlying behavior shifts.<\/li>\n<li>Allowing Engines to absorb frequent algorithmic, rules, and decision-logic changes.<\/li>\n<li>Using Resource Accessors to isolate churn in persistence choices, external dependencies, and infrastructure-facing concerns.<\/li>\n<li>Using Utilities to adapt cross-cutting needs such as observability and feature flagging without contaminating core logic.<\/li>\n<\/ul>\n<p>This separation enables rapid iteration while maintaining architectural coherence.<\/p>\n<h3 id=\"observed-outcomes\">Observed Outcomes<\/h3>\n<p>Across these scenarios, consistent outcomes emerge:<\/p>\n<ul>\n<li>Change is localized rather than systemic.<\/li>\n<li>Architectural intent remains visible and enforceable.<\/li>\n<li>Teams can evolve different parts of the system independently.<\/li>\n<\/ul>\n<p>These results reinforce VBD&#8217;s central premise: aligning architectural boundaries with volatility produces systems that are resilient over time.<\/p>\n<hr \/>\n<h2 id=\"9b-practitioner-observations\">9B. Practitioner Observations<\/h2>\n<p>The following observations emerge from applying Volatility-Based Decomposition across multiple systems over extended periods. They are not specific to any organization or domain. Rather, they describe recurring patterns, tensions, and emergent behaviors that practitioners are likely to encounter when VBD is applied consistently as a system matures.<\/p>\n<h3 id=\"observation-1-volatility-migration\">Observation 1: Volatility Migration<\/h3>\n<p>Volatility axes are not permanent. What was stable for years can become intensely volatile due to external forces, and what was once highly volatile can stabilize as a domain matures. A common example is compliance logic: rules that remained unchanged for a decade may suddenly enter a period of rapid, continuous change when new regulation is introduced. Architectures that hardcoded compliance assumptions into Managers or even Utilities find themselves performing invasive surgery across the system. The practical implication is that volatility classification must be revisited periodically. Systems designed under VBD absorb this migration more gracefully because the boundaries already exist \u2014 the work becomes reclassification and, at worst, extraction of logic from one role into another, rather than a fundamental restructuring.<\/p>\n<h3 id=\"observation-2-accessor-accumulation\">Observation 2: Accessor Accumulation<\/h3>\n<p>As systems grow, Resource Accessors tend to proliferate. Each new vendor integration, database, external API, or infrastructure dependency typically receives its own Accessor, which is correct according to VBD principles. Over time, however, the sheer number of Accessors can become a management burden. The diagnostic question is whether multiple Accessors share the same volatility profile \u2014 if two Accessors change for the same reasons, at the same rate, and are owned by the same team, consolidation is appropriate. If they change independently, they should remain separate regardless of superficial similarity. The temptation to merge Accessors for tidiness should be resisted when their volatility profiles differ, as doing so reintroduces the coupling VBD was designed to eliminate.<\/p>\n<h3 id=\"observation-3-engine-extraction\">Observation 3: Engine Extraction<\/h3>\n<p>Logic that begins inside a Manager has a natural tendency to migrate into Engines over time. In early development, when the business rules are not yet fully understood, teams often embed decision logic directly in the Manager&#8217;s orchestration flow because the rules seem simple or because the team is still discovering what the rules actually are. As the system matures and the rules become clearer, more complex, or more independently volatile, practitioners consistently find themselves extracting that logic into dedicated Engines. This is not a failure of initial design \u2014 it is a healthy and expected progression. VBD accommodates this migration by design: the Manager&#8217;s orchestration structure remains intact while the extracted Engine absorbs the volatile logic behind a clean interface.<\/p>\n<h3 id=\"observation-4-the-utility-trap\">Observation 4: The Utility Trap<\/h3>\n<p>Utilities are the most frequently misused component role in VBD. Because they are accessible to all other roles and represent &#8220;shared&#8221; capabilities, there is a persistent temptation to place logic in a Utility simply because multiple consumers need it. The diagnostic is straightforward: if the Utility contains domain knowledge \u2014 if it knows about orders, customers, pricing, or any business concept \u2014 it is not a Utility. It is an Engine or an Accessor that has been misclassified for convenience. True Utilities are domain-agnostic: logging, cryptographic hashing, date formatting, correlation identifier generation, metric collection. When a Utility begins accumulating business-aware conditional logic, it should be reclassified and relocated before it becomes a hidden coupling point that undermines the entire decomposition.<\/p>\n<h3 id=\"observation-5-conways-law-alignment\">Observation 5: Conway&#8217;s Law Alignment<\/h3>\n<p>VBD interacts productively with Conway&#8217;s Law \u2014 the observation that system structure tends to mirror organizational communication structure. When component boundaries are aligned with volatility axes, team ownership naturally follows. The team that owns pricing policy owns the Pricing Engine. The team that manages vendor relationships owns the relevant Resource Accessors. This alignment reduces cross-team coordination costs because changes are localized not only architecturally but organizationally. Conversely, when VBD boundaries conflict with team structure, one of two things must change: either the architecture is adjusted to reflect organizational reality, or the organization is restructured to match the architecture. In practice, the most successful outcomes occur when both are considered together.<\/p>\n<h3 id=\"observation-6-emergent-configuration-drivenness\">Observation 6: Emergent Configuration-Drivenness<\/h3>\n<p>Systems built under VBD tend to become configuration-driven over time, even when this was not an explicit design goal. The mechanism is straightforward: because Engines encapsulate business rules behind stable interfaces, and because those rules change frequently, teams naturally begin externalizing rule parameters into configuration rather than modifying code for each change. Pricing tiers become configuration tables. Eligibility thresholds become feature flags. Validation constraints become schema-driven. This emergent behavior is a structural consequence of properly isolating volatile logic \u2014 once the volatility boundary is clean, the path of least resistance for absorbing change shifts from code modification to configuration update. Practitioners should recognize and embrace this tendency rather than treating it as accidental.<\/p>\n<h3 id=\"observation-7-the-stability-paradox-of-managers\">Observation 7: The Stability Paradox of Managers<\/h3>\n<p>Managers are designed to be the most stable component in a VBD system, yet they are often the first component written and the last to be understood correctly. Early in a system&#8217;s life, Managers tend to accumulate logic that belongs elsewhere \u2014 business rules, data transformation, error handling policy \u2014 because the team has not yet identified which concerns are independently volatile. The paradox is that achieving Manager stability requires the most architectural discipline, precisely because Managers sit at the top of the invocation hierarchy and are the most convenient place to add logic quickly. Teams that enforce Manager stability from the outset consistently report lower long-term maintenance costs, while teams that allow Managers to accumulate non-orchestration logic find themselves performing costly extractions later.<\/p>\n<h3 id=\"observation-8-boundary-pressure-as-a-health-signal\">Observation 8: Boundary Pressure as a Health Signal<\/h3>\n<p>In mature VBD systems, the points where teams feel the most pressure to violate communication rules serve as reliable indicators of architectural misalignment. When an Engine needs to call another Engine, it typically signals that the Manager above them is not properly coordinating the workflow, or that the two Engines should be merged because they share a volatility axis. When a Resource Accessor begins applying business rules, it signals that an Engine is missing from the architecture. Rather than treating boundary violations as failures of discipline alone, experienced practitioners use them as diagnostic signals \u2014 the pressure to violate a rule reveals where the current decomposition no longer matches the system&#8217;s actual volatility profile.<\/p>\n<hr \/>\n<h2 id=\"10-conclusion\">10. Conclusion<\/h2>\n<p>Volatility-Based Decomposition provides a disciplined approach to software architecture that treats change as an explicit design constraint rather than an afterthought. By identifying functional, non-functional, cross-cutting, and environmental sources of volatility, architects can align system boundaries with the forces most likely to cause erosion over time.<\/p>\n<p>Through established component roles, strict communication rules, and continuous validation against core use cases, Volatility-Based Decomposition supports the creation of architectures that remain adaptable as systems grow in scale, complexity, and organizational impact.<\/p>\n<p>In many organizations, architectural weakness is revealed not by the initial change itself, but by the unintended side effects that follow. A seemingly localized modification triggers a cascade of downstream impacts, forcing broad testing cycles, emergency fixes, and production instability. These domino effects erode confidence, slow delivery, and increase operational risk.<\/p>\n<p>By aligning architectural boundaries with volatility and validating changes against a small set of core use cases, VBD localizes change and limits its blast radius. While no approach can eliminate change, volatility-based decomposition reduces the likelihood that a single modification will destabilize unrelated parts of the system, preserving architectural integrity and lowering long-term maintenance costs.<\/p>\n<p>As software systems continue to operate in increasingly dynamic environments, architectures that explicitly design for volatility will prove more resilient than those optimized solely for present-day requirements.<\/p>\n<hr \/>\n<h2 id=\"appendix-a-glossary\">Appendix A: Glossary<\/h2>\n<p><strong>Blast Radius<\/strong> \u2014 The extent of system impact caused by a single change. VBD aims to minimize blast radius by aligning boundaries with volatility axes.<\/p>\n<p><strong>Change Coupling<\/strong> \u2014 A condition where modifying one component forces changes in another, even when the two have no logical dependency. Indicates misaligned volatility boundaries.<\/p>\n<p><strong>Communication Rules<\/strong> \u2014 The explicit constraints governing which component roles may invoke which others, and through what mechanisms. Prevents dependency erosion and preserves volatility isolation.<\/p>\n<p><strong>Component Role<\/strong> \u2014 One of the four architectural roles assigned to a component based on the type of concern it encapsulates: Manager, Engine, Resource Accessor, or Utility.<\/p>\n<p><strong>Core Use Case<\/strong> \u2014 A high-level system behavior that defines primary business value and exercises all component tiers. Used to validate architectural decisions and communication rules.<\/p>\n<p><strong>Decomposition<\/strong> \u2014 The process of breaking a system into components along boundaries that align with anticipated sources of change.<\/p>\n<p><strong>Engine<\/strong> \u2014 A component that encapsulates business rules, calculations, transformations, and policy logic. Engines answer <em>how<\/em> the system performs its work and absorb functional volatility as business rules evolve.<\/p>\n<p><strong>Environmental Volatility<\/strong> \u2014 Change driven by infrastructure platforms, third-party services, vendor APIs, deployment models, and hosting environments.<\/p>\n<p><strong>Functional Volatility<\/strong> \u2014 Change driven by evolving business behavior, workflows, features, regulations, and user requirements.<\/p>\n<p><strong>Information Hiding<\/strong> \u2014 Parnas&#8217;s principle of decomposing systems based on design decisions likely to change. VBD generalizes this from individual modules to architectural boundaries.<\/p>\n<p><strong>Manager<\/strong> \u2014 A component that coordinates workflow, sequencing, and intent. Managers answer <em>what<\/em> the system does and remain stable over time by containing no business logic or infrastructure awareness.<\/p>\n<p><strong>Non-Functional Volatility<\/strong> \u2014 Change driven by performance, scalability, reliability, and other quality-of-service requirements.<\/p>\n<p><strong>Orchestration<\/strong> \u2014 The coordination of workflow steps, sequencing, and intent. Separated from execution in VBD to allow workflows and business rules to evolve independently.<\/p>\n<p><strong>Resource Accessor<\/strong> \u2014 A component that isolates interactions with databases, external APIs, vendors, and infrastructure. Resource Accessors answer <em>where<\/em> data and services live and shield the system from environmental volatility.<\/p>\n<p><strong>Stability<\/strong> \u2014 The property of a component that changes infrequently relative to others. Managers are designed to be the most stable components in a VBD system.<\/p>\n<p><strong>Utility<\/strong> \u2014 A component that encapsulates cross-cutting concerns such as logging, monitoring, security, and observability. Utilities are orthogonal to business logic and may be called by any other component.<\/p>\n<p><strong>Volatility<\/strong> \u2014 The likelihood, frequency, and impact of change affecting a system responsibility or requirement. The primary organizing force in VBD.<\/p>\n<p><strong>Volatility Axis<\/strong> \u2014 A dimension along which change is expected to occur. The four primary axes are functional, non-functional, cross-cutting, and environmental.<\/p>\n<p><strong>Volatility Boundary<\/strong> \u2014 An architectural seam placed to contain a specific source of change, preventing it from propagating to unrelated components.<\/p>\n<p><strong>Volatility Migration<\/strong> \u2014 The phenomenon where a concern shifts from one volatility axis to another over time, requiring reassessment of component boundaries.<\/p>\n<hr \/>\n<h2 id=\"appendix-b-applicability-checklist\">Appendix B: Applicability Checklist<\/h2>\n<p>Volatility-Based Decomposition is particularly well-suited for systems that:<\/p>\n<ul>\n<li>Are expected to evolve over multiple years<\/li>\n<li>Operate across changing infrastructure or regulatory environments<\/li>\n<li>Support multiple teams or organizational boundaries<\/li>\n<li>Require long-term maintainability and extensibility<\/li>\n<\/ul>\n<hr \/>\n<h2 id=\"appendix-c-case-study-multi-tenant-saas-billing-platform\">Appendix C: Case Study \u2014 Multi-Tenant SaaS Billing Platform<\/h2>\n<p>This appendix presents a fictional but architecturally realistic case study applying Volatility-Based Decomposition to a multi-tenant SaaS billing platform. The system is responsible for generating invoices, calculating charges based on usage and subscription tiers, applying externally-imposed adjustments across multiple jurisdictions, processing payments through multiple providers, and notifying tenants of billing activity.<\/p>\n<h3 id=\"c1-volatility-analysis\">C.1 Volatility Analysis<\/h3>\n<p>The first step is identifying what changes and what remains stable.<\/p>\n<p><strong>High Volatility:<\/strong><\/p>\n<ul>\n<li><strong>Pricing rules<\/strong> \u2014 Subscription tiers, volume discounts, promotional offers, and per-unit rates change continuously as business strategy evolves. Pricing data lives behind an accessor because where and how prices are stored is itself a volatility axis.<\/li>\n<li><strong>External adjustments<\/strong> \u2014 Tax rates, nexus rules, exemption categories, regulatory fees, and reporting obligations change across jurisdictions independently and unpredictably. External tax services and local databases are isolated behind an accessor.<\/li>\n<li><strong>Payment providers<\/strong> \u2014 New providers are added, existing providers change APIs, and regional payment methods must be supported. All provider volatility is isolated behind a single accessor.<\/li>\n<li><strong>Invoice storage<\/strong> \u2014 Where and how invoices are persisted \u2014 schema, storage technology, archival strategy \u2014 is isolated behind an accessor owned by the InvoicingEngine.<\/li>\n<li><strong>Notification channels<\/strong> \u2014 How tenants are notified (email, SMS, webhook, in-app) changes based on product decisions and tenant preferences.<\/li>\n<\/ul>\n<p><strong>Low Volatility:<\/strong><\/p>\n<ul>\n<li><strong>Billing lifecycle<\/strong> \u2014 The fundamental sequence of calculating charges, applying adjustments, generating an invoice, collecting payment, and notifying the tenant has remained stable across billing systems for decades.<\/li>\n<li><strong>Audit requirements<\/strong> \u2014 The need to maintain a complete, immutable audit trail of all financial transactions is a permanent architectural requirement.<\/li>\n<\/ul>\n<h3 id=\"c2-component-identification\">C.2 Component Identification<\/h3>\n<p><strong>Managers:<\/strong><\/p>\n<ul>\n<li><strong>BillingManager<\/strong> \u2014 Orchestrates the end-to-end billing lifecycle: delegates pricing calculation, adjustment application, invoice creation and persistence, payment collection, and tenant notification. Contains no business rules. Expresses intent and sequence only. Fires an async event to NotificationManager after payment is confirmed.<\/li>\n<li><strong>NotificationManager<\/strong> \u2014 Orchestrates tenant notification delivery. Receives a billing completion event asynchronously from BillingManager and coordinates the appropriate notification channels. Decoupled from the billing flow \u2014 notification failure does not affect billing outcome.<\/li>\n<\/ul>\n<p><strong>Engines:<\/strong><\/p>\n<ul>\n<li><strong>PricingEngine<\/strong> \u2014 Encapsulates all pricing logic: subscription tier calculations, usage-based metering aggregation, volume discounts, and promotional adjustments. Retrieves current pricing rules via PriceAccessor. Discounts are an aspect of pricing strategy and belong here.<\/li>\n<li><strong>AdjustmentEngine<\/strong> \u2014 Encapsulates all externally-imposed modifications to a priced transaction: tax calculations, regulatory fees, payment processing surcharges, and any other obligations not owned by the business&#8217;s pricing strategy. Tax is the primary case \u2014 AdjustmentEngine retrieves rates via TaxAccessor and applies jurisdiction-specific rules \u2014 but the Engine&#8217;s boundary is defined by the volatility axis, not the adjustment type. When a new regulatory fee or cross-border surcharge must be applied, AdjustmentEngine is the only component that changes.<\/li>\n<li><strong>InvoicingEngine<\/strong> \u2014 Assembles the invoice from priced and adjusted line items, calculates totals, and persists the completed invoice via InventoryAccessor. Owns both creation and persistence \u2014 BillingManager receives only the invoiceId in return.<\/li>\n<\/ul>\n<p><strong>Resource Accessors:<\/strong><\/p>\n<ul>\n<li><strong>PriceAccessor<\/strong> \u2014 Retrieves pricing rules, tier definitions, and discount schedules from the pricing data store. Isolates PricingEngine from changes in pricing data structure, storage technology, and external pricing service APIs.<\/li>\n<li><strong>TaxAccessor<\/strong> \u2014 Retrieves tax rates and jurisdiction rules from external tax services (Avalara, TaxJar) or local tax databases. Isolates AdjustmentEngine from changes in data sources and service provider APIs.<\/li>\n<li><strong>InventoryAccessor<\/strong> \u2014 Manages persistence of generated invoices, line items, and billing history. Called by InvoicingEngine, not by BillingManager directly.<\/li>\n<li><strong>PaymentAccessor<\/strong> \u2014 Manages integration with external payment providers (Stripe, PayPal, bank ACH, and future providers). Translates provider-specific protocols into a uniform PaymentConfirmation interface.<\/li>\n<\/ul>\n<h3 id=\"c3-component-architecture\">C.3 Component Architecture<\/h3>\n<p><em>Figure C.1 \u2014 Billing Platform Component Architecture: BillingManager orchestrates the billing lifecycle, delegating to each Engine and calling PaymentAccessor directly. Each Engine owns its own accessor boundary. NotificationManager receives an async event after payment is confirmed and operates independently of the billing flow.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">graph TB\n    BM[BillingManager]\n    PE[PricingEngine]\n    TE[AdjustmentEngine]\n    IGE[InvoicingEngine]\n    PA[PaymentAccessor]\n    PRA[PriceAccessor]\n    TSA[TaxAccessor]\n    ISA[InventoryAccessor]\n    NM[NotificationManager]\n\n    BM --&gt; PE\n    BM --&gt; TE\n    BM --&gt; IGE\n    BM --&gt; PA\n    BM -.-&gt;|async event| NM\n\n    PE --&gt; PRA\n    TE --&gt; TSA\n    IGE --&gt; ISA\n\n    style BM fill:#0053e2,color:#fff,stroke-width:0px\n    style NM fill:#0053e2,color:#fff,stroke-width:0px\n    style PE fill:#ffc220,color:#000,stroke-width:0px\n    style TE fill:#ffc220,color:#000,stroke-width:0px\n    style IGE fill:#ffc220,color:#000,stroke-width:0px\n    style PA fill:#2a8703,color:#fff,stroke-width:0px\n    style PRA fill:#2a8703,color:#fff,stroke-width:0px\n    style TSA fill:#2a8703,color:#fff,stroke-width:0px\n    style ISA fill:#2a8703,color:#fff,stroke-width:0px\n<\/code><\/pre>\n<h3 id=\"c4-communication-rules-applied\">C.4 Communication Rules Applied<\/h3>\n<table>\n<thead>\n<tr>\n<th>Source<\/th>\n<th>Target<\/th>\n<th>Permitted<\/th>\n<th>Rationale<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>BillingManager<\/td>\n<td>PricingEngine<\/td>\n<td>Yes<\/td>\n<td>Manager invokes Engine<\/td>\n<\/tr>\n<tr>\n<td>BillingManager<\/td>\n<td>AdjustmentEngine<\/td>\n<td>Yes<\/td>\n<td>Manager invokes Engine<\/td>\n<\/tr>\n<tr>\n<td>BillingManager<\/td>\n<td>InvoicingEngine<\/td>\n<td>Yes<\/td>\n<td>Manager invokes Engine<\/td>\n<\/tr>\n<tr>\n<td>BillingManager<\/td>\n<td>PaymentAccessor<\/td>\n<td>Yes<\/td>\n<td>Manager invokes Accessor \u2014 after invoice is complete<\/td>\n<\/tr>\n<tr>\n<td>BillingManager<\/td>\n<td>NotificationManager<\/td>\n<td>Yes (async)<\/td>\n<td>Manager-to-Manager via event \u2014 fire and forget<\/td>\n<\/tr>\n<tr>\n<td>BillingManager<\/td>\n<td>InventoryAccessor<\/td>\n<td><strong>No<\/strong><\/td>\n<td>Invoice persistence is InvoicingEngine&#8217;s responsibility<\/td>\n<\/tr>\n<tr>\n<td>PricingEngine<\/td>\n<td>AdjustmentEngine<\/td>\n<td><strong>No<\/strong><\/td>\n<td>Engine-to-Engine communication prohibited<\/td>\n<\/tr>\n<tr>\n<td>PricingEngine<\/td>\n<td>PriceAccessor<\/td>\n<td>Yes<\/td>\n<td>Engine calls its own Accessor<\/td>\n<\/tr>\n<tr>\n<td>AdjustmentEngine<\/td>\n<td>TaxAccessor<\/td>\n<td>Yes<\/td>\n<td>Engine calls its own Accessor<\/td>\n<\/tr>\n<tr>\n<td>InvoicingEngine<\/td>\n<td>InventoryAccessor<\/td>\n<td>Yes<\/td>\n<td>Engine calls Accessor to complete its responsibility<\/td>\n<\/tr>\n<tr>\n<td>PaymentAccessor<\/td>\n<td>InventoryAccessor<\/td>\n<td><strong>No<\/strong><\/td>\n<td>Accessor-to-Accessor communication prohibited<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>BillingManager does not call InventoryAccessor directly. Invoice persistence is encapsulated within InvoicingEngine, which calls InventoryAccessor as part of fulfilling its own responsibility. BillingManager receives only the invoiceId in return.<\/p>\n<h3 id=\"c5-core-use-case-walkthrough-generate-and-process-monthly-invoice\">C.5 Core Use Case Walkthrough: Generate and Process Monthly Invoice<\/h3>\n<ol>\n<li><strong>BillingManager<\/strong> receives a trigger to generate the monthly invoice for a tenant.<\/li>\n<li><strong>BillingManager<\/strong> calls <strong>PricingEngine<\/strong> with the tenant&#8217;s usage data and subscription tier. PricingEngine retrieves current pricing rules via <strong>PriceAccessor<\/strong>, calculates line items, applies discounts and pro-rations, and returns a priced line item set.<\/li>\n<li><strong>BillingManager<\/strong> calls <strong>AdjustmentEngine<\/strong> with the priced line items and transaction context (jurisdiction, payment method, tenant classification). AdjustmentEngine applies all externally-imposed obligations \u2014 retrieving tax rates via <strong>TaxAccessor<\/strong>, applying jurisdiction-specific rules, and layering in any applicable fees or surcharges \u2014 and returns the adjusted line items. BillingManager has no knowledge of which adjustment types were applied or how many.<\/li>\n<li><strong>BillingManager<\/strong> calls <strong>InvoicingEngine<\/strong> with the priced and adjusted line items. InvoicingEngine assembles the invoice document, calculates totals, and persists the completed invoice via <strong>InventoryAccessor<\/strong>. BillingManager receives only the invoiceId in return.<\/li>\n<li><strong>BillingManager<\/strong> calls <strong>PaymentAccessor<\/strong> with the invoiceId, total amount, and payment method. PaymentAccessor interacts with the configured payment provider, handles provider-specific protocols, and returns a PaymentConfirmation.<\/li>\n<li><strong>BillingManager<\/strong> fires an async event to <strong>NotificationManager<\/strong> with the billing result. NotificationManager operates independently \u2014 it coordinates notification delivery without blocking or affecting the billing outcome.<\/li>\n<\/ol>\n<p><em>Figure C.2 \u2014 Core Use Case: Generate and Process Monthly Invoice. Steps 1\u20134 are sequential \u2014 pricing before adjustments, adjustments before invoice, invoice before payment. Step 5 is fire-and-forget.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">graph TB\n    U([Tenant])\n    BM[BillingManager]\n    PE[PricingEngine]\n    PRA[PriceAccessor]\n    TE[AdjustmentEngine]\n    TSA[TaxAccessor]\n    IGE[InvoicingEngine]\n    ISA[InventoryAccessor]\n    PA[PaymentAccessor]\n    NM[NotificationManager]\n\n    U --&gt;|generateInvoice| BM\n    BM --&gt;|&quot;1 \u00b7 calculateCharges&quot;| PE\n    PE --&gt;|getPricingRules| PRA\n    PRA --&gt;|PricingRules| PE\n\n    BM --&gt;|&quot;2 \u00b7 applyAdjustments&quot;| TE\n    TE --&gt;|getTaxRates| TSA\n    TSA --&gt;|TaxRates| TE\n\n    BM --&gt;|&quot;3 \u00b7 createInvoice&quot;| IGE\n    IGE --&gt;|persist| ISA\n    ISA --&gt;|invoiceId| IGE\n\n    BM --&gt;|&quot;4 \u00b7 collectPayment&quot;| PA\n\n    BM -.-&gt;|&quot;5 \u00b7 async event&quot;| NM\n\n    style U fill:#f8f9fa,stroke:#636e72,color:#636e72,stroke-width:1px\n    style BM fill:#0053e2,color:#fff,stroke-width:0px\n    style NM fill:#0053e2,color:#fff,stroke-width:0px\n    style PE fill:#ffc220,color:#000,stroke-width:0px\n    style TE fill:#ffc220,color:#000,stroke-width:0px\n    style IGE fill:#ffc220,color:#000,stroke-width:0px\n    style PA fill:#2a8703,color:#fff,stroke-width:0px\n    style PRA fill:#2a8703,color:#fff,stroke-width:0px\n    style TSA fill:#2a8703,color:#fff,stroke-width:0px\n    style ISA fill:#2a8703,color:#fff,stroke-width:0px\n<\/code><\/pre>\n<h3 id=\"c6-internal-design-paymentaccessor-and-the-strategy-pattern\">C.6 Internal Design: PaymentAccessor and the Strategy Pattern<\/h3>\n<p>VBD defines the boundaries between components and the rules governing communication across those boundaries. It says nothing about how a component is organized internally. That is deliberate \u2014 once a boundary is established, the team that owns the component is free to structure its internals however best serves maintainability, testability, and extensibility, without any obligation to the rest of the system.<\/p>\n<p>PaymentAccessor illustrates this clearly. Its contract to the outside world is simple: receive a payment request, return a PaymentConfirmation or failure. How it fulfills that contract is entirely its own concern. Internally, PaymentAccessor implements the Strategy pattern \u2014 a <strong>PaymentProviderFactory<\/strong> resolves the correct <strong>IPaymentProvider<\/strong> implementation based on the context of the call (payment method, region, tenant configuration, or any other dispatch criterion), and delegates execution to it.<\/p>\n<p><em>Figure C.3 \u2014 PaymentAccessor internal structure. The Strategy pattern isolates provider-specific implementations behind IPaymentProvider. PaymentProviderFactory resolves the correct implementation at runtime based on call context. The rest of the system sees none of this.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">graph TB\n    subgraph boundary[&quot;PaymentAccessor \u2014 internal structure&quot;]\n        direction TB\n        F[&quot;PaymentProviderFactory&quot;]\n        I[&quot;&amp;lt;&amp;lt;interface&amp;gt;&amp;gt; IPaymentProvider&quot;]\n        S1[&quot;StripeProvider&quot;]\n        S2[&quot;PayPalProvider&quot;]\n        S3[&quot;ACHProvider&quot;]\n\n        F --&gt;|resolves| I\n        I -.-&gt;|implemented by| S1\n        I -.-&gt;|implemented by| S2\n        I -.-&gt;|implemented by| S3\n    end\n\n    style F fill:#e8f4fd,stroke:#0053e2,color:#0053e2,stroke-width:1px\n    style I fill:#f8f9fa,stroke:#636e72,color:#2d2d2d,stroke-width:1px,stroke-dasharray:4\n    style S1 fill:#2a8703,color:#fff,stroke-width:0px\n    style S2 fill:#2a8703,color:#fff,stroke-width:0px\n    style S3 fill:#2a8703,color:#fff,stroke-width:0px\n<\/code><\/pre>\n<p>Because BillingManager holds only a reference to PaymentAccessor \u2014 not to any of its internals \u2014 the team owning PaymentAccessor can:<\/p>\n<ul>\n<li><strong>Add a new provider<\/strong> by writing a new IPaymentProvider implementation. No other component changes.<\/li>\n<li><strong>Refactor the factory<\/strong> \u2014 change dispatch logic, add caching, introduce weighted routing \u2014 without touching BillingManager or any other component.<\/li>\n<li><strong>Replace the internal architecture entirely<\/strong> \u2014 swap the Strategy pattern for a plugin registry, a configuration-driven resolver, or anything else \u2014 as long as the external contract is preserved.<\/li>\n<li><strong>Test provider implementations in isolation<\/strong>, mock at the IPaymentProvider boundary, and evolve internal test strategy independently of the rest of the system.<\/li>\n<\/ul>\n<p>This is the compounding benefit of a well-placed boundary. VBD does not prescribe how PaymentAccessor is built \u2014 it only prescribes where its boundary is and what may cross it. Everything inside that boundary is a local decision, free from the coordination cost that would accompany any change visible to the rest of the system.<\/p>\n<p>The same principle applies to every component. PricingEngine may internally maintain a chain of discount calculators. InvoicingEngine may use a template engine or a document builder. AdjustmentEngine may dispatch to multiple adjustment strategies in sequence. These are internal implementation choices. The system does not know and does not need to know.<\/p>\n<h3 id=\"c7-volatility-isolation-demonstrated-adding-crypto-payments\">C.7 Volatility Isolation Demonstrated: Adding Crypto Payments<\/h3>\n<p>The business decides to accept cryptocurrency payments. A new <strong>CryptoProvider<\/strong> implementation is written \u2014 handling blockchain confirmation logic, wallet address validation, exchange rate locking, and the crypto processor&#8217;s API \u2014 and registered with the factory. That is the entirety of the change.<\/p>\n<p><em>Figure C.4 \u2014 CryptoProvider added to PaymentAccessor. One new class, registered with the factory. The interface contract is unchanged. No other component in the system is modified or redeployed.<\/em><\/p>\n<pre><code class=\"\" data-line=\"\">graph TB\n    subgraph boundary[&quot;PaymentAccessor \u2014 after adding crypto support&quot;]\n        direction TB\n        F[&quot;PaymentProviderFactory&quot;]\n        I[&quot;&amp;lt;&amp;lt;interface&amp;gt;&amp;gt; IPaymentProvider&quot;]\n        S1[&quot;StripeProvider&quot;]\n        S2[&quot;PayPalProvider&quot;]\n        S3[&quot;ACHProvider&quot;]\n        S4[&quot;CryptoProvider&quot;]\n\n        F --&gt;|resolves| I\n        I -.-&gt;|implemented by| S1\n        I -.-&gt;|implemented by| S2\n        I -.-&gt;|implemented by| S3\n        I -.-&gt;|implemented by| S4\n    end\n\n    style F fill:#e8f4fd,stroke:#0053e2,color:#0053e2,stroke-width:1px\n    style I fill:#f8f9fa,stroke:#636e72,color:#2d2d2d,stroke-width:1px,stroke-dasharray:4\n    style S1 fill:#2a8703,color:#fff,stroke-width:0px\n    style S2 fill:#2a8703,color:#fff,stroke-width:0px\n    style S3 fill:#2a8703,color:#fff,stroke-width:0px\n    style S4 fill:#2a8703,color:#fff,stroke:#fff,stroke-width:2px,stroke-dasharray:4\n<\/code><\/pre>\n<p>BillingManager still calls <code class=\"\" data-line=\"\">collectPayment(invoiceId, amount, paymentMethod)<\/code> \u2014 the same call it has always made. It has no knowledge that a new payment type exists. PricingEngine, AdjustmentEngine, InvoicingEngine, and NotificationManager are untouched. The factory now routes crypto payment requests to CryptoProvider; everything else routes exactly as before.<\/p>\n<p><strong>One class added. Eight components untouched.<\/strong> The payment provider axis of volatility is fully contained within PaymentAccessor, and the boundary enforces that containment regardless of how many providers are added over time.<\/p>\n<hr \/>\n<h2 id=\"references-and-influences\">References and Influences<\/h2>\n<p>The concepts presented in this paper are informed by, and build upon, established work in software architecture, component design, and object-oriented systems. Volatility-Based Decomposition is not presented as a novel invention, but as a practitioner-oriented articulation of principles that have emerged and matured through decades of architectural thought and practice.<\/p>\n<p><strong>Juval L\u00f6wy<\/strong><br \/>\nL\u00f6wy, Juval. <em>Righting Software.<\/em> Addison-Wesley, 2019.<br \/>\nL\u00f6wy, Juval. <em>Programming .NET Components.<\/em> O&#8217;Reilly Media, 2005.<\/p>\n<p>Juval L\u00f6wy&#8217;s work is the primary foundation for Volatility-Based Decomposition. His IDesign methodology explicitly frames volatility as the dominant architectural force and emphasizes designing systems around anticipated change rather than static functionality. The Manager, Engine, and Resource Accessor role taxonomy, along with the associated communication rules and component interaction discipline described in this paper, are derived directly from IDesign training. This paper builds upon L\u00f6wy&#8217;s work by consolidating these principles into a single, cohesive decomposition process and demonstrating their application across diverse system contexts.<\/p>\n<p><strong>David L. Parnas<\/strong><br \/>\nParnas, David L. &#8220;On the Criteria To Be Used in Decomposing Systems into Modules.&#8221; <em>Communications of the ACM<\/em>, 1972.<\/p>\n<p>Parnas introduced the principle of information hiding, arguing that systems should be decomposed based on the design decisions most likely to change. This idea is foundational to Volatility-Based Decomposition. VBD can be viewed as a system-level extension of Parnas&#8217;s insight, generalizing information hiding beyond individual modules to entire architectural boundaries aligned with volatility axes.<\/p>\n<p><strong>Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides)<\/strong><br \/>\nGamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. <em>Design Patterns: Elements of Reusable Object-Oriented Software.<\/em> Addison-Wesley, 1994.<\/p>\n<p>The Gang of Four cataloged recurring object-oriented patterns that encapsulate and localize variation at the class and collaboration level. These patterns demonstrate how volatility can be managed through indirection, composition, and role separation. Volatility-Based Decomposition extends this pattern-based thinking from the object scale to the architectural scale, applying the same principles of variation isolation across components and services.<\/p>\n<p><strong>Robert C. Martin<\/strong><br \/>\nMartin, Robert C. <em>Clean Architecture.<\/em> Pearson, 2017.<br \/>\nMartin, Robert C. <em>Agile Software Development: Principles, Patterns, and Practices.<\/em> Pearson, 2002.<\/p>\n<p>Martin&#8217;s work emphasizes responsibility-driven design, stable dependency direction, and the separation of policy from implementation details. These ideas complement VBD&#8217;s focus on isolating volatile concerns and enforcing communication rules that prevent dependency inversion from eroding architectural boundaries over time.<\/p>\n<p><strong>Eric Evans<\/strong><br \/>\nEvans, Eric. <em>Domain-Driven Design: Tackling Complexity in the Heart of Software.<\/em> Addison-Wesley, 2003.<\/p>\n<p>Domain-Driven Design introduces bounded contexts as strategic boundaries for managing conceptual and organizational complexity. While VBD does not prescribe domain boundaries, it aligns with Evans&#8217;s emphasis on explicit boundary definition. Volatility-Based Decomposition can coexist with DDD by treating bounded contexts as one possible axis of volatility among others, such as regulatory change or infrastructure churn.<\/p>\n<p><strong>Gregor Hohpe and Bobby Woolf<\/strong><br \/>\nHohpe, Gregor; Woolf, Bobby. <em>Enterprise Integration Patterns.<\/em> Addison-Wesley, 2003.<\/p>\n<p>Hohpe and Woolf formalized integration and messaging patterns that address the volatility inherent in distributed systems. Their work informs the disciplined communication rules emphasized in VBD, particularly around asynchronous messaging, decoupling, and the containment of integration complexity within well-defined architectural boundaries.<\/p>\n<p><strong>Mary Shaw and David Garlan<\/strong><br \/>\nShaw, Mary; Garlan, David. <em>Software Architecture: Perspectives on an Emerging Discipline.<\/em> Pearson, 1996.<\/p>\n<p>Shaw and Garlan helped establish software architecture as a first-class discipline distinct from programming and design. Their work provides the conceptual grounding for system-level decomposition approaches like Volatility-Based Decomposition, reinforcing the idea that architectural structure must be reasoned about explicitly and evaluated continuously as systems evolve.<\/p>\n<hr \/>\n<h2 id=\"authors-note\">Author&#8217;s Note<\/h2>\n<p>Volatility-Based Decomposition (VBD), including its terminology, volatility-first orientation, component role taxonomy, and communication rules, originates from Juval L\u00f6wy&#8217;s IDesign methodology. This paper does not introduce a new architectural approach. It provides a consolidated, practitioner-oriented articulation of VBD, emphasizing decomposition mechanics, validation strategies, and real-world application across long-lived software systems.<\/p>\n<p>The intent of this paper is to serve as a durable reference that translates volatility-centered principles into a form suitable for consistent application, discussion, and review within modern engineering organizations.<\/p>\n<hr \/>\n<h2 id=\"distribution-note\">Distribution Note<\/h2>\n<p>This document is provided for informational and educational purposes. It may be shared internally within organizations, used as a reference in architectural discussions, or adapted for non-commercial educational use with appropriate attribution. This paper does not represent official policy, standards, or architectural mandates of any current or former employer. All examples are generalized and abstracted to avoid disclosure of proprietary or sensitive information.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Volatility-Based Decomposition (VBD) in Software Architecture Organizing Architecture Around Anticipated Change: A Practitioner-Oriented Articulation Author: William Christopher Anderson Date: April 2026 Version: 1.0 Executive Summary Modern software systems rarely fail because of poor initial design; they fail because change accumulates faster than the architecture can absorb it. Volatility-Based Decomposition (VBD) addresses this problem by treating &#8230; <a title=\"Volatility-Based Decomposition (VBD) in Software Architecture\" class=\"read-more\" href=\"https:\/\/harmonic-framework.com\/es\/whitepapers\/volatility-based-decomposition\/\" aria-label=\"Read more about Volatility-Based Decomposition (VBD) in Software Architecture\">Read more<\/a><\/p>","protected":false},"author":0,"featured_media":0,"parent":11,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","footnotes":""},"methodology":[],"class_list":["post-132","page","type-page","status-publish"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"trp-custom-language-flag":false,"post-thumbnail":false,"hf-card":false,"hf-hero":false},"uagb_author_info":{"display_name":"","author_link":"https:\/\/harmonic-framework.com\/es\/author\/"},"uagb_comment_info":0,"uagb_excerpt":"Volatility-Based Decomposition (VBD) in Software Architecture Organizing Architecture Around Anticipated Change: A Practitioner-Oriented Articulation Author: William Christopher Anderson Date: April 2026 Version: 1.0 Executive Summary Modern software systems rarely fail because of poor initial design; they fail because change accumulates faster than the architecture can absorb it. Volatility-Based Decomposition (VBD) addresses this problem by treating&hellip;","_links":{"self":[{"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/pages\/132","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/types\/page"}],"replies":[{"embeddable":true,"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/comments?post=132"}],"version-history":[{"count":8,"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/pages\/132\/revisions"}],"predecessor-version":[{"id":696,"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/pages\/132\/revisions\/696"}],"up":[{"embeddable":true,"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/pages\/11"}],"wp:attachment":[{"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/media?parent=132"}],"wp:term":[{"taxonomy":"methodology","embeddable":true,"href":"https:\/\/harmonic-framework.com\/es\/wp-json\/wp\/v2\/methodology?post=132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}