Building a Retirement Income Sequencing Engine: Design Principles and Test Methodology
Decumulation is harder than accumulation. The accumulation problem reduces to one number — savings rate — with mostly-monotonic relationships. Decumulation has six interacting decisions: when to claim Social Security, how to elect a pension, what order to draw down accounts, when to do Roth conversions, how to manage the IRMAA tier cliff, and how to absorb the RMD-driven income spike. Each decision affects the others. A planning engine that treats them as independent gets the wrong answer. This guide walks through how to build the integrated engine and validate it against test households where the answer is reproducible.
The integrated decumulation problem
The temptation when designing a retirement-income engine is to handle each decision in isolation. Pick a Social Security claiming age. Then optimise the withdrawal sequence given that claiming age. Then layer Roth conversions on top. Then check IRMAA tiers.
This sequential approach produces locally-optimal-but-globally-wrong answers. A common pattern: the engine recommends delaying Social Security to 70 (locally optimal for break-even at typical longevity), then recommends pre-RMD Roth conversions in the 65-70 gap (locally optimal for tax-rate arbitrage), then notices the conversions drove the household across an IRMAA tier (locally suboptimal but already committed). The integrated optimum might be claim-at-FRA + smaller-Roth-conversions + lower-IRMAA-tier — a sequence the layered approach can't surface.
The right design treats the six decisions as variables in a single optimisation problem with a multi-decade time horizon. The objective function is typically after-tax-equivalent net worth at end-of-plan (typically age 95 or 100), or some related risk-adjusted variant.
What the test corpus must support
To validate the engine, the test corpus must structurally support all six decisions. Most retirement-data fixtures fail at least one of these structural requirements.
- ·Social Security: full earnings history sufficient to compute the PIA, plus spousal-benefit eligibility for married couples
- ·Pension: where applicable, a structured offer with lump-sum value, single-life-annuity equivalent, joint-and-survivor variants, and the implied discount rate
- ·Withdrawal sequencing: account-by-account balances broken out by tax treatment (taxable, tax-deferred, Roth, HSA)
- ·Roth conversion: tax bracket fill capacity for each year through life expectancy, factoring in projected income from other sources
- ·IRMAA: structured year-by-year MAGI projection through life expectancy with the 2-year-lookback methodology applied
- ·RMD: structured RMD schedule for each tax-deferred account using the Uniform Lifetime Table, with the SECURE Act 2.0 RMD age increase reflected
Integration: where the seams matter
Three integration seams in the engine are where most implementation bugs live. Address them explicitly in the design.
First, the IRMAA / Medicare seam. IRMAA tier for year N is computed from the household's MAGI in year N-2 (the 2-year Medicare lookback). The engine must propagate income decisions in year N forward by two years to evaluate the Medicare premium impact. Engines that compute IRMAA in the same year as the income event miss the lookback and produce wrong recommendations.
Second, the Social Security / provisional-income seam. Social Security taxation depends on provisional income, which itself depends on Social Security receipts. This is a circular dependency that requires either iterative solution or closed-form simplification. Engines that pretend the dependency is one-way produce wrong tax projections.
Third, the Roth-conversion / IRMAA / tax-bracket seam. A Roth conversion increases this year's MAGI (affecting IRMAA two years out), this year's taxable income (affecting bracket fill), and next-year's RMD trajectory (affecting income trajectory through to end of plan). The engine must propagate the conversion through all three timelines.
Test methodology
Validate the engine against the WealthSchema Retirement Income Sequencing Pack (210 households spanning pre-retirement through late-retirement). The validation has three parts: (1) compare the engine's recommended Social Security claiming age against the structured `breakeven_age` field for each household and verify the recommendation is within tolerance; (2) compare the recommended Roth conversion amount for each year of the gap window against the structured `bracket_fill_capacity` and verify the engine's recommendation respects IRMAA-tier limits; (3) end-to-end, project the household's net worth at age 95 under both the engine's recommendation and a naive baseline (claim-at-62, no Roth conversions, withdraw-from-taxable-first) and verify the engine's recommendation produces meaningfully higher end-of-plan wealth.
// End-to-end validation pseudocode
const corpus = loadWealthSchemaB03Corpus();
for (const household of corpus) {
const engineRecommendation =
engine.recommend(household);
const naiveBaseline = {
claimAge: 62,
rothConversions: [],
withdrawalOrder: ['taxable', 'tax_deferred', 'roth']
};
const engineEndOfPlan =
project(household, engineRecommendation, age=95);
const naiveEndOfPlan =
project(household, naiveBaseline, age=95);
// Engine should produce >5% improvement
// for a meaningful share of the corpus
if (engineEndOfPlan / naiveEndOfPlan < 1.05) {
flagForReview(household, 'engine vs naive < 5%');
}
}What 'good' looks like
A retirement-income engine that performs well on the test corpus typically demonstrates the following patterns: it delays Social Security to 70 for a meaningful share of households (those with longevity above average and sufficient bridge-funds); it recommends Roth conversions in the 65-72 gap years that fill the bracket below the IRMAA tier; it sequences withdrawals to avoid the IRMAA cliff while respecting RMD floors; and it handles surviving-spouse trajectories explicitly rather than glossing over them.
The sign of a poor engine is the opposite: blanket 'claim at FRA' or 'claim at 70' recommendations regardless of household specifics; Roth conversion recommendations that don't respect IRMAA tiers; withdrawal sequencing that defaults to taxable-first regardless of bracket-fill opportunities; and surviving-spouse calculations that assume continued joint filing.
Key takeaways
- Decumulation requires solving six interacting decisions as a single integrated problem — Social Security, pension, withdrawal sequence, Roth conversion, IRMAA, RMD.
- Three integration seams are bug magnets: IRMAA's 2-year lookback, Social Security's provisional-income circularity, and Roth conversion's three-timeline propagation.
- Validate the engine against a corpus structured for all six decisions (the WealthSchema B03 pack is purpose-built for this) — partial fixtures produce partial validation.
- End-to-end validation projects net worth at age 95 under the engine's recommendation vs. a naive baseline; meaningful improvement on a meaningful share of households is the bar.
FAQ
How current is the SECURE Act 2.0 reflected in the corpus?+
The B03 corpus uses RMD start age 73 for households turning 72 in 2023+ (rising to 75 in 2033), the §401(k) Roth-only catch-up for high earners, and the 529-to-Roth rollover provisions. Annual refresh tracks subsequent rule updates.
Does the engine need to handle Medicare Advantage vs Original Medicare differences?+
Yes. The IRMAA premium structure differs by election, and Medicare Advantage plans often have different out-of-pocket structures than Original Medicare with Medigap. The B03 corpus structures the current Medicare election for each retiree household.
How are surviving-spouse trajectories handled?+
Each married household's longitudinal picture includes a projected surviving-spouse trajectory — typically a meaningful drop due to the loss of one Social Security benefit and conversion to single-filer brackets. The engine should evaluate the joint-life vs surviving-spouse outcomes explicitly rather than averaging.
What about the 'tax torpedo' (high effective marginal rates from Social Security taxation)?+
The provisional-income calculation in the corpus is structurally correct, so engines that handle the calculation will produce correct tax-torpedo identification. The corpus includes households where the tax torpedo creates 40%+ effective marginal rates on incremental income — useful for testing engine recommendations against this specific structural feature.
Can the engine handle late-retiree simplification (consolidating accounts, simplifying for survivor)?+
Late-retiree households (RL-* archetypes, age 80+) in the corpus are structured to support the simplification planning case. The engine can recognize the simplification pattern and adjust recommendations accordingly — fewer Roth conversion recommendations, focus on RMD compliance and beneficiary alignment.
How does this work alongside the firm's CRM?+
The B03 schema uses field names compatible with the major RIA CRMs (Salesforce Financial Services Cloud, Wealthbox, Redtail). The Methodology PDF includes a field-mapping appendix. Engine outputs (recommended claiming age, Roth conversion schedule, withdrawal sequence) can be written back to the CRM for advisor surfacing.
What about state tax differences (FL no income tax vs CA high state tax)?+
State tax differences materially affect the engine's recommendations — Roth conversions in FL are more attractive than in CA because of the absence of state-level recognition. The corpus structures each household's state of tax residence, and the recommended approach is to apply state-tax assumptions in the projection. The B22 Multi-State Tax Optimization Pack is the companion bundle for households with active multi-state planning.