{"slug": "using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting", "title": "Using the Strangler Pattern to Add AI Around Legacy Systems Without Rewriting the Core", "summary": "An engineer outlined an approach for adding AI capabilities to legacy systems using the Strangler Fig pattern, wrapping existing applications with adapters rather than rewriting their cores. The design routes a narrow set of workflows through an AI component that proposes actions, while the legacy application validates and executes them through staged checks for schema validity, caller authorization, and business rules. The engineer warned that connecting AI directly to database tables or internal functions couples model output to interfaces never designed as public contracts.", "body_md": "A legacy system can contain years of business rules, data relationships, and operational behavior that nobody wants to rediscover during a full rewrite. Yet the same system may expose only batch interfaces, rigid APIs, or workflows that make introducing a new AI capability difficult.\n\nThe answer is not necessarily to replace the core application. A safer approach is to introduce a new capability at a well-defined boundary, route a limited set of workflows through it, and preserve the existing system as the authority for critical business operations.\n\nThis is where the Strangler Fig pattern becomes useful. Martin Fowler describes the pattern as an incremental approach to modernization: introduce new functionality around the existing system, establish seams between components, and gradually move behavior when there is a clear reason to do so. The pattern reduces the need for a single, high-risk replacement event, although it introduces temporary architectural complexity.\n\nAdding AI makes those boundaries even more important. An AI component can interpret requests, classify information, summarize records, or propose actions. It should not automatically inherit the authority to change business state simply because it can generate a plausible action.\n\nConsider a hypothetical order-management application that already handles customer records, inventory, pricing, and order updates. The system works, but support staff spend time interpreting requests and locating the relevant information.\n\nThe proposed AI capability could classify incoming requests, retrieve relevant order information, and suggest an action. That does not require replacing the order-management core. Instead, isolate one workflow with a clear input, output, and operational boundary.\n\nFor example:\n\nThe distinction is important: the AI proposes; the application validates and executes. This keeps the initial modernization scope narrow enough to test without turning the model into a second implementation of the core business logic.\n\nA common mistake is connecting an AI component directly to database tables or internal functions because those interfaces are convenient. This can couple model-generated decisions to implementation details that were never designed as public contracts. An adapter provides a more controlled boundary. It translates between the new capability's request format and the existing application's supported operations.\n\nFor example, an adapter might expose a conceptual operation such as:\n\nget_order_status(order_id)\n\nThe operation returns a defined response containing the order identifier, current status, and relevant timestamps. It does not expose unrestricted database access. For a state-changing operation, the boundary should be narrower still. Rather than accepting an arbitrary instruction, the adapter should accept a validated command with explicit fields, an authenticated caller, and a defined set of permitted operations.\n\nThe adapter should handle:\n\nThis layer is not merely a compatibility wrapper. It is the place where the new capability is prevented from bypassing established application controls.\n\nStructured output can make an AI integration easier to validate, but valid structure does not prove that an action is correct or authorized. Suppose the AI proposes changing an order's delivery address. A response may conform perfectly to the expected schema while referring to the wrong order or attempting an unauthorized change.\n\nThe execution path should therefore have separate validation stages:\n\nThese checks should not depend on the model's assurance that it has followed the rules.\n\nA conceptual execution boundary might look like this:\n\nrequest = receive_user_request()\n\nproposal = ai_component.propose_action(request)\n\nif not schema_is_valid(proposal):\n\n    reject(\"invalid proposal\")\n\nif not caller_is_authorized(proposal, caller):\n\n    reject(\"unauthorized\")\n\nif not business_rules_allow(proposal):\n\n    reject(\"business rule violation\")\n\nif requires_human_approval(proposal):\n\n    return request_approval(proposal)\n\nresult = legacy_adapter.execute(proposal)\n\nrecord_execution_result(result)\n\nreturn result\n\nThis is pseudocode, not a drop-in implementation. Each validation function must be implemented against the application's real identity model, business rules, and transaction semantics.\n\nThe important property is the separation between generating an action and granting permission to execute it.\n\nThe Strangler Fig approach depends on choosing a boundary that can be introduced without changing every consumer of the existing system. A routing layer can direct selected workflows to the new capability while keeping other workflows on their existing path. The routing decision should be explicit and observable.\n\nA practical rollout might proceed in stages:\n\n**Stage 1: Read-only assistance**\n\nAllow the AI capability to classify requests, summarize records, or retrieve information through approved interfaces. Keep state-changing operations disabled.\n\n**Stage 2: Shadow evaluation**\n\nRun the new path alongside the existing workflow without allowing it to commit changes. Compare its proposed output with the established process, using representative cases and defined acceptance criteria.\n\n**Stage 3: Limited execution**\n\nEnable one low-risk, reversible action for a controlled set of requests. Use explicit authorization, bounded permissions, and a defined approval policy.\n\n**Stage 4: Expand by capability**\n\nAdd further workflows only after the current boundary has demonstrated acceptable behavior, including failure handling and operational visibility. A feature flag can control exposure, but it is not an authorization mechanism. The adapter must enforce permissions regardless of how traffic reaches it.\n\nThe goal is not to move every request to the new path as quickly as possible. It is to learn where the new capability adds value without weakening the existing system's guarantees.\n\nAn AI service can become unavailable, exceed a timeout, return an unusable result, or propose an action that the core application rejects. The integration needs a deliberate response to each condition. For read-only assistance, a useful fallback may be to return the existing application's normal response without the AI-generated summary. For a state-changing workflow, fallback may mean returning control to the established manual process rather than attempting an alternative action automatically.\n\nRetries need particular care. If a write request reaches the legacy system but the response is lost, the caller may not know whether the operation succeeded. Repeating the request can create duplicate side effects unless the operation has suitable idempotency or deduplication semantics.\n\nFor state-changing operations, consider:\n\nDo not treat every timeout as proof that the operation failed. The system may have committed the change even though the response never reached the caller. Likewise, a fallback should not silently execute the same business action through a second path while the first path's outcome remains unknown.\n\nIntroducing AI around an existing application also creates a data-flow question: which information can leave the core, where is it processed, and what is retained? The adapter should return only the fields needed for the workflow. Sensitive fields should not be exposed simply because they are present in the underlying record.\n\nThe integration should also define what happens to prompts, retrieved records, model responses, and execution metadata. Retention, access, and redaction requirements depend on the data and the model provider, so they must be verified for the actual environment.\n\nObservability should capture enough information to reconstruct a failure without indiscriminately recording sensitive payloads. Useful fields include the correlation ID, workflow name, policy outcome, adapter latency, execution status, and escalation reason. A trace should make it possible to distinguish an AI failure from an authorization rejection, a legacy-system error, or a timeout with an uncertain outcome.\n\nThe pattern is not a reason to preserve every part of a legacy system indefinitely. A narrow adapter is useful when the existing application has stable business behavior and a manageable interface can be established. It becomes less useful when the integration requires extensive duplication of business rules, continuous synchronization of conflicting state, or workarounds for behavior that cannot be reliably isolated.\n\nAt that point, the modernization decision may need to change. A domain capability may be better extracted, a contract redesigned, or part of the core replaced. The decision should follow the constraints discovered at the boundary rather than an assumption that either replacement or preservation is always correct.\n\nThere is also a cost to transitional architecture. Every additional adapter, routing rule, and policy boundary becomes something the team must test, observe, secure, and eventually maintain or remove. The team should define ownership for those components and periodically reassess whether the boundary still serves a purpose.\n\nThe useful outcome of this approach is not simply that an AI feature has been attached to an older application. It is that the organization can introduce a new capability while retaining control over business state, authorization, failure handling, and operational ownership.\n\nStart with one workflow, one explicit interface, and a limited set of permitted actions. Measure whether the new path behaves correctly, identify where its assumptions fail, and keep the existing path available while those questions remain unresolved. Modernization becomes easier to reason about when the new capability can evolve independently without quietly taking ownership of the system around it.\n\nThe core does not need to disappear before the surrounding system can improve. The boundary is where that improvement becomes testable, controllable, and reversible.", "url": "https://wpnews.pro/news/using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting", "canonical_source": "https://dev.to/outworktech/using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting-the-core-35ll", "published_at": "2026-10-17 07:28:07+00:00", "updated_at": "2026-10-17 07:31:32.248576+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "ai-tools", "developer-tools"], "entities": ["Martin Fowler"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting", "markdown": "https://wpnews.pro/news/using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting.md", "text": "https://wpnews.pro/news/using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting.txt", "jsonld": "https://wpnews.pro/news/using-the-strangler-pattern-to-add-ai-around-legacy-systems-without-rewriting.jsonld"}}