Safely Evolving a 15-Year-Old Tax Execution Engine
Incremental legacy modernization with controlled blast radius, not a rewrite
Problem
Intuit's tax data platform runs a mature execution engine that processes data for tens of thousands of API and scraping-based providers, on behalf of downstream products like TurboTax, QuickBooks, and Credit Karma. Part of that platform still depended on a 15-year-old legacy scripting pipeline. It worked, but it was harder to extend and maintain than the modern engine the team had since built around an internal DSL (ISL). Replacing it outright, across every provider at once, would have put a huge and unpredictable surface of production tax data flows at risk simultaneously.
Context
This was not a greenfield rewrite. The legacy pipeline and its replacement both had to keep serving live provider traffic throughout the migration, with zero tolerance for customer-facing disruption during tax season. I was a core contributor on the team driving this migration, working within an established platform with existing conventions, downstream consumers, and provider contracts already in production.
Constraints
- Tens of thousands of providers depended on the legacy pipeline's existing behavior; none could be interrupted.
- The new ISL-based engine needed to prove equivalent behavior before taking over any provider's real traffic.
- Zero tolerance for customer-facing disruption during the cutover, in a system downstream products depend on directly.
- No appetite for a simultaneous, all-providers cutover: the risk of a single undetected behavioral difference multiplying across the entire provider base was the thing to avoid.
My Role
I drove the migration of the legacy scripts onto the modern ISL-based engine as a core contributor on the team responsible for it. The provider-scoped validation approach and rollout plan described below were team decisions, not something I owned solo. My individual, hands-on ownership sits in the surrounding engine work this migration depended on: the retry and failure-handling logic across the hybrid Kafka/Pulsar pipeline, the PDF-scraping extraction module, the @.Event.Publish extension for mid-execution event delivery, the external provider call flow, and the Raw Host Tax / S3 isolation for storing raw provider output securely.
Architecture / Approach
Rather than cutting every provider over to the new engine at once, we picked a single provider and ran its legacy and ISL-based execution paths in shadow, comparing behavior directly while every other provider kept running on the existing, unmigrated pipeline. Other providers were untouched by the validation work happening on that one provider; the two systems only needed to agree for the provider actually being validated. Once that shadow comparison held up, we wrote a rollout plan before touching production, and only deployed once both the validation and the plan were in place.
Key Decisions
- Provider-scoped shadow validation over a global cutover. Validating one provider's behavior in shadow before touching production kept the blast radius of any discrepancy contained to that provider, instead of exposing every provider to the same untested path simultaneously.
- Rollout plan before production deployment, not after. Production traffic only moved to the new path once the plan for how the rollout would proceed was written and the shadow comparison had already validated the target provider's behavior.
- Leave other providers on existing behavior during validation. Providers not yet validated kept running on the legacy pipeline unchanged, so the migration's risk surface grew one validated provider at a time rather than all at once.
Trade-offs
Validating provider by provider is slower than a single global cutover, and it meant carrying the legacy and modern paths side by side for longer. That cost bought confidence: each provider's behavior was proven equivalent before it depended on the new path, and a bad result during shadow comparison stayed contained to one provider instead of surfacing across the whole system after the fact. Maintaining two working paths simultaneously also added real engineering overhead, which is only worth it when the alternative, a synchronous full cutover, has a blast radius large enough to threaten downstream products directly.
Impact
The legacy tax scripting pipeline was migrated onto the modern ISL-based engine with zero customer-facing disruption. The provider-scoped approach meant that at every stage of the migration, only a bounded, already-validated slice of provider traffic was running on unproven code, rather than exposing the full provider base to an unvalidated path at once.
Lessons
Mature systems reward incremental change over aggressive rewrites, especially when the thing you're replacing already serves real production traffic you don't fully control the shape of. Compatibility is part of the feature, not a checkbox before the real work starts, and understanding what depends on the system you're changing matters more than how fast you can change it. Reducing blast radius mattered more here than maximizing rollout speed, and a provider-scoped shadow comparison was a concrete, low-drama way to buy that safety without inventing new infrastructure to do it.