Changelog
A complete record of every update shipped to RetIQ. Newest first. No entries are ever removed.
Wage-only local tax handled automatically, and a state tax rate you can set yourself
Local and county income tax for wage-only states is now handled automatically. In Ohio, Pennsylvania, Kentucky, and Missouri — where local income tax falls on wages, not on pensions, IRA or 401(k) withdrawals, or Social Security — RetIQ now applies your local rate to earned income only. A retiree with no wages correctly owes no local tax there, while someone still working has it applied to their wages. Every other state continues to apply the local rate to your full state taxable income, as before.
You can also set your own state tax rate. On the Assumptions tab, any state with an income tax now shows RetIQ’s modeled effective rate, with an option to replace it with your own number — handy if you know your real effective rate or want to match a tax return. The override applies a flat rate to your income in place of the bracket model; any county or city tax you’ve entered still applies on top. It’s off by default, so nothing changes unless you turn it on.
Local and county income tax for states beyond Maryland
You can now add a local or county income tax rate for states other than Maryland. If your city or county taxes income on top of the state — common in much of Ohio and Pennsylvania, and parts of Indiana, Kentucky, and Missouri — enter that rate on the Assumptions tab and it’s added on top of your state tax, with the projection breaking it out as “State & Local Tax.” It defaults to zero, so nothing changes unless you set it, and Maryland’s local-rate field works as before. Note that some local taxes apply only to wages, not retirement income.
The Strategy Report’s relocation suggestion now refers to “a no-income-tax state” instead of naming Florida specifically — the estimated savings are the same for any no-income-tax state, so the wording no longer implies a particular destination.
Projection table — every column now has a tappable info marker
Each column header in the Projection data table now shows a small info marker. Hover it on a computer or tap it on a phone to see a plain-language explanation of what that column includes and how it relates to your Expenses total. This covers every column — including the withdrawal-detail, harvesting, inherited-account, QLAC, and charitable-bunching columns — and replaces the older hover-only tooltips, which appeared slowly and did not work on touch devices.
Projection table — column headers now explain each column
Hover over any column header in the Projection data table for a short explanation of what that column includes — for example, that working-year Expenses use your Pre-Retirement amount, that Debt and Long-Term Care are part of the Expenses total rather than added on top of it, and that one-time costs sit in their own column. It makes it easier to trace each number back to where you entered it.
Retirement timing corrected for later-in-the-year birthdays
When you set a specific Month of Retirement, RetIQ could place your retirement one calendar year too late if your birthday falls later in the year — and carry your earned income an extra year in the projection as a result. The retirement date shown on the Personal tab and the income in your projection now reflect the year you actually retire. Plans left on “Not sure / no specific month” were never affected.
A spouse’s QLAC now counts toward net worth
For couples where the non-primary spouse holds a QLAC — a deferred annuity held inside a retirement account — that balance is now included in your net worth, the same way the primary account holder’s QLAC already was. If this applies to you, your net worth will show higher than before, correcting an asset that was previously left out.
Projection table — Debt, Long-Term Care, and a Net Worth breakdown
The Projection data table now shows Debt and Long-Term Care as separate columns, broken out from your total Expenses so you can trace each one back to where you entered it. Both are included in the CSV export, and both are part of the Expenses total rather than added on top of it.
Net Worth in the Projection table is now clickable — click any year's value to expand a breakdown of how it splits across your accounts: Pre-Tax, Roth, Cash/HYS, Brokerage, HSA, inherited accounts, and QLAC.
Long-term care — plan for each spouse separately
You can now model a separate long-term care need for each spouse, each with its own start age, duration, annual cost, and insurance. Care for your spouse is timed to their age, not yours, and if both of you need care in overlapping years the costs add together. Households with a single long-term care scenario see no change.
Roth Optimizer now weighs ACA subsidies
The optimizer tests the new Cliff-Aware Fill strategy and shows two new columns: ACA Kept (how much Marketplace subsidy a strategy preserves) and NIIT (Net Investment Income Tax paid). The optimizer's ranking now also accounts for ACA subsidies retained — so if you buy Marketplace coverage in early retirement, the recommended strategy may change to one that protects those subsidies. Households not on a Marketplace plan will see effectively the same ranking as before.
New Roth conversion strategy — Cliff-Aware Fill
A new strategy that fills your target tax bracket each year while holding your income below the thresholds that matter most: the ACA Marketplace subsidy cliff, Medicare's IRMAA surcharge tiers, and the Net Investment Income Tax threshold. Useful in the pre-Medicare years when a large conversion could cost more in lost ACA subsidies than it saves in tax. The ACA ceiling is adjustable, and the NIIT guard can be switched off.
ACA plan cost — model the plan you'll actually buy
On ACA Marketplace coverage you can now enter the annual premium of the plan you'll actually enroll in. RetIQ keeps your premium tax credit based on the benchmark Silver plan and applies it to your plan, so a lower-cost Bronze plan shows its true net cost. The Year-1 preview now shows your plan premium and net cost side by side.
Also fixed: for single-person households, the Benchmark Premium Override now correctly flows into the projection.
Expenses shown consistently across the Dashboard and Projection tabs; one-time expenses now visible
The Expenses figure on the Projection tab now matches the Dashboard's Income vs Expenses chart. Previously the Projection tab subtracted healthcare and Medicare costs from its Expenses number while the Dashboard showed the full total, so the same plan appeared to have two different expense figures. Both now show your complete annual spending. In the Projection table, the Healthcare, Medicare, and IRMAA columns break out parts of that total rather than adding to it.
One-time expenses now appear in the Projection table and chart as their own "One-Time" line. Previously a one-time expense reduced an account balance silently, with nothing in the projection showing where the money went; you can now see it year by year.
Net Worth chart: zero-balance account lines no longer cover the account below
On the Dashboard Net Worth chart, when an account was drawn down to zero — for example a Brokerage balance emptied by Roth conversions or withdrawals — that account's line was still drawn directly on top of the account line stacked beneath it, hiding the lower account (such as Roth) for those years. The chart now draws each account's line only for the years that account actually holds a balance, so every account with a balance stays visible.
Retirement month accuracy
The Month of Retirement field now accounts for your birth month. If you retire in a month that falls before your birthday, RetIQ places your retirement in the following calendar year — so the retirement date shown on the Personal tab matches the year you actually retire.
The retirement-month dropdown now includes a “Not sure / no specific month” option. Choosing it keeps your projection on a whole-year basis, exactly as before. Existing plans are unchanged on load — they stay on the whole-year basis and only adopt the new behavior if you pick a specific month.
One-Time Income Events now warn you when an event’s age falls outside your projection range — before your current age or after your plan ends — so a severance or bonus entered against the wrong age no longer disappears without explanation.
Percent-of-income contribution routing
Contribution Routing now lets you enter your 401(k) and IRA contributions as a percentage of your income instead of a fixed dollar amount. A new toggle on the routing card switches between "$ Amount" and "% of Income." In percent mode, your contributions automatically rise and fall with your income each year — including through raises and any pay-cut years you've modeled with Pre-Retirement Income Phases — with no extra steps. Dollar-amount routing stays the default, and existing plans are unchanged.
Fix: Routed contributions could exceed your available savings
When Contribution Routing was turned on, the projection could direct more money into 401(k) and IRA contributions than your savings for that year actually covered. Two situations caused this. If your routed contributions came to more than your savings, the engine funded them in a fixed order, so one spouse’s contributions and employer match could be cut to nothing before the other spouse’s were reduced at all. And when one spouse used Contribution Routing while the other used the default allocation, the routed spouse’s contributions could draw against the other spouse’s savings, pushing the household’s total contributions above its total savings. Both are now corrected: when routed contributions exceed available savings, each one is scaled down proportionally, and a routed spouse’s contributions are limited to that spouse’s own savings. Projections where contributions always fit within savings are unchanged. If you use Contribution Routing — especially with a reduced-income phase, or with one spouse routing and the other not — re-check your plan, since the corrected projection may show a lower contribution total.
The Contribution Routing card’s savings warning is now phase-aware. It previously checked only your current annual savings; it now checks every year through retirement, including reduced-income phases, and shows which years your routed contributions would exceed your savings. The card also states plainly that routed 401(k) and IRA amounts are fixed dollar contributions that do not grow from year to year. And the Annual Savings fields gained help text noting that this figure grows each year at your savings growth rate, and pointing to Pre-Retirement Income Phases as the way to use a different amount for a specific age range.
Fix: Healthcare tab pre-Medicare cost estimate
The Healthcare tab displayed two pre-Medicare healthcare cost totals — a headline estimate and the year-by-year Cost Summary below it — calculated by separate code paths that could disagree. The headline estimate is now drawn from the same projection as the Cost Summary, so the two always match. Only the headline estimate changed; the Cost Summary figure was already correct. This affected plans that retire before Medicare eligibility.
Survivor scenario rework
This release completes the survivor-scenario rework. Planning for the loss of a spouse is now a clear, guided part of the app — you can model what happens if either spouse passes at an age you choose, see the financial picture the survivor would face, and carry that scenario forward as your active plan. Labels and section headings throughout the Survivor area have been rewritten to plainly say what each part does.
Fix: pre-tax balance growth after a spouse’s death
Corrected an error where, after the first spouse died, the surviving spouse’s pre-tax (Traditional IRA / 401k) balance could grow at the plan’s default Nominal Return rate even when the underlying accounts were set to a different return rate. The growth rate now always follows the accounts that actually hold the money. This affected projections where one spouse held all the pre-tax savings and the other held none. Plans where both spouses hold pre-tax balances, and plans without a death in the projection, were not affected.
Fix: pre-tax balance accuracy in survivor scenarios
Corrected an error in how the pre-tax (Traditional IRA / 401k) balance was tracked after the first spouse’s death. The surviving-spouse share of the pre-tax pool was grown as a separate figure from the pool itself, which could let the two diverge once an inherited IRA rolled over — producing small inaccuracies in the displayed pre-tax balance and in required minimum distributions in later years. The share is now always derived directly from the pool, so the two cannot drift. Plans without a death in the projection are unaffected.
v6.7 — Life Expectancy: projections now reflect mortality
This entry summarizes the v6.7 release, delivered across the five point releases below (v6.61.2 through v6.62.3). Life Expectancy is no longer just a Survivor-tab input — it now drives the entire projection.
What changed. When you set Life Expectancy on the Personal tab to an age below Plan Through Age, the projection reflects that death: after the death age, the plan continues as a single-survivor scenario. Medicare drops to one enrollee, filing status shifts to Single, Social Security survivor benefits apply, expenses adjust by the survivor ratio, and any configured life insurance death benefit deposits tax-free. Healthcare costs, IRMAA, lifetime taxes, end-of-life net worth, and every analytical tool — Strategy Report, Roth Optimizer, Monte Carlo — reflect this automatically.
If you never set Life Expectancy, nothing changed: both spouses are still assumed alive through Plan Through Age, exactly as before. The feature is opt-in by setting the fields.
New transparency. The Healthcare tab gained a per-spouse Medicare & IRMAA detail table. The Survivor tab’s Three Futures and Robust vs Fragile views were repositioned so their “upper bound” column is an explicit comparison rather than a hidden assumption. The Personal tab Life Expectancy card explains the engine behavior directly.
See the five entries below for the per-release detail. No engine or behavior change ships with this v6.62.4 entry itself — it is the consolidated summary plus documentation refinements.
Strategy resilience & term-life checks aligned with Life Expectancy
Two refinements completing the v6.7 Life Expectancy work. The Survivor tab’s Strategy Resilience — Robust vs Fragile table now labels its first column Both Reach Plan End and computes it as a true upper bound (both spouses alive through Plan Through Age), consistent with the Three Futures table. Previously, when Life Expectancy was set, that column silently reflected LE-driven mortality.
The Strategy Report’s term-life-insurance warning — which flags a term policy that expires before the modeled death age — now also accounts for Life Expectancy. Previously it only fired for explicit Survivor-tab scenarios; a plan with Life Expectancy set but no Survivor scenario received no warning even when its term coverage lapsed early.
A full review confirmed the Strategy Report Card, Roth Optimizer, and Monte Carlo all already handle Life Expectancy correctly — their baseline and every alternative run against the same plan, so comparisons stay consistent. No changes were needed there. No engine changes; all test suites pass at baseline.
Survivor tab repositioned around Life Expectancy
The Survivor tab’s three sub-tabs now reflect the post-v6.7 reality where Life Expectancy drives the projection by default. Three Futures at a Glance: the first column is now labeled Both Reach Plan End and overrides Life Expectancy for that column only, showing the upper-bound comparison. The other two columns continue to use Survivor scenarios with LE inherited from plan params for the non-selected spouse.
Survivor Impact Analysis: description reframed from “model death” to “test what happens if death occurs at a different age than your configured Life Expectancy.” When LE is set on the Personal tab, a small blue inline note now appears showing the assumed ages so users can see what the analysis is overriding.
Adopt Plan: added a clarifying note explaining when to use Adopt Plan (death has happened or is imminent) versus setting Life Expectancy on the Personal tab (modeling a future death age that hasn’t happened yet).
No engine changes; all six test suites pass at baseline.
Per-spouse Medicare & IRMAA detail panel
New Per-Spouse Medicare & IRMAA Detail card on the Healthcare tab. Breaks down each year’s Medicare costs by enrollee — base Part B premium, Part B IRMAA surcharge, and Part D IRMAA surcharge — alongside the household total. For couples, both spouses appear side-by-side; for single filers, the table collapses to one column per cost type. Death transitions surface as zeroed cells, making the survivor scenario behavior visible at a glance. Note: base Part D plan premiums are user-paid privately and are not modeled by the engine; only the income-based IRMAA surcharge on Part D appears.
The lifetime-totals footer below the Medicare summary now reflects the actual life expectancy assumption: when Life Expectancy is set, the footer reads “Reflects life expectancy: you to age X and spouse to age Y. After each death age, the plan continues as a single-survivor scenario” (Medicare drops to one enrollee, filing shifts to Single, Social Security survivor benefits apply). When Life Expectancy is not set, the footer continues to note that both spouses are assumed alive through Plan Through Age and links to the Personal tab.
Engine: per-enrollee Medicare values now expose on year rows as y.partBBasePrimary, y.partBBaseSpouse, y.partBIrmaaPrimary, y.partBIrmaaSpouse, y.partDIrmaaPrimary, y.partDIrmaaSpouse. Existing y.medicareCost and y.irmaa household totals are unchanged; the six new scalars sum to y.medicareCost + y.irmaa within rounding. 9 new tests in test-mortality-resolution.js verify the exposure, MFJ-MAGI bracket sharing, single-filer collapse, post-death zeroing, consistency with household totals, and inflation accuracy.
Life Expectancy now drives your projection (v6.7 begins)
The Life Expectancy values on the Personal tab now drive your full projection — not just the Survivor tab. After each spouse’s death age, the plan continues as a survivor scenario: Medicare drops to one enrollee, filing shifts to Single, Social Security survivor benefits apply, and Medicare/IRMAA surcharges adjust accordingly. End-of-life net worth, lifetime taxes, and Roth Optimizer comparisons all reflect mortality automatically.
If you had Life Expectancy set on a saved plan: your projection numbers changed starting with v6.61.2 (the engine plumbing release that preceded this UI update). The Personal tab now shows a one-time banner explaining this. Plans without Life Expectancy set continue to assume both spouses live through Plan Through Age — behavior unchanged.
The Personal tab Life Expectancy card now also renders for single filers (previously couples-only). The Survivor tab Impact Analysis remains the place to test “what if death happens at a different age than expected” — configured survivor scenarios still override the Personal tab values, as before.
v6.7 release continues in subsequent point releases: Healthcare tab rebuild with per-spouse IRMAA detail, Survivor tab repositioning, Strategy Report / Roth Optimizer recalibration. This is the user-visible kickoff.
Engine plumbing for upcoming v6.7 mortality features
Internal engine change wiring primaryLifeExpectancy and spouseLifeExpectancy into the projection engine’s death-age resolution. Plans without Life Expectancy set on the Personal tab continue to behave exactly as before — both spouses are assumed alive through Plan Through Age. Plans that explicitly set Life Expectancy below Plan Through Age will see their projection reflect mortality in subsequent v6.7 UI work (next release). No user-visible behavior change in this release.
47 new tests in test-mortality-resolution.js verify the resolution logic, downstream cascades (Medicare enrollee count, IRMAA, filing status, spouse age nulling, SS survivor, pension joint50, spousal RMD rollover, expense reduction), and edge cases. All existing test suites pass at baseline.
Clearer labels around Life Expectancy and Medicare totals
Clearer labels around the Life Expectancy fields on the Personal tab — these values feed the Survivor tab's analysis, not the base plan's main projection. Added a note on the Healthcare tab's Medicare summary so it's clear lifetime Medicare and IRMAA totals assume both spouses live through Plan Through Age; to model one spouse passing earlier, use the Survivor tab.
Healthcare transition years
Fixed how pre-Medicare healthcare costs are pro-rated in the year you
or your spouse turns 65. Previously, the transition year could under- or
over-count cost depending on the household structure — for example, a
household with a 7-year-younger spouse might see only one or two
thousand dollars of healthcare cost in the primary's age-65 row when the
correct number was much higher (because the spouse still needed ACA
coverage for the rest of that year).
The new model accounts for each person's own birth month independently,
so the transition year is now blended between couple-on-ACA, primary-alone,
and spouse-alone phases as appropriate. Survivor years also benefit:
ACA cost in the years between a spouse's death and their own Medicare age
is now computed at the single rate at the survivor's actual age.
Retirement marker now lands on the actual month
The orange dashed line that marks retirement on the projection chart used to snap to the start of the year — if you set retirement at age 65 in June, the line drew at age 66 instead of midway between 65 and 66. We've shifted it to reflect the month you actually set. No projection math changes; the engine has always pro-rated retirement-year earned income and savings by the month you choose. The fix applies across every chart that shows the retirement transition.
Roth Optimizer: preview a strategy before applying
Click any row in the optimizer's Top 8 to expand it in place. The expanded panel shows three charts — net worth, federal tax per year, and IRMAA surcharges per year — comparing your no-conversion baseline against that strategy. Click the same row to collapse, or click a different row to swap. The charts use your real per-account returns, so what you see in the preview is what you'd get if you clicked Apply.
Apply still works exactly the same. Preview is a way to compare scenarios visually without committing to any of them.
Roth Optimizer: diversity-aware top 8
The Top 8 strategies table now guarantees at least one row per strategy and bracket-target combination (Fill 12% / 22% / 24%, Smart Fill 12% / 22% / 24%, plus fixed-amount) before filling the remaining slot with the next-highest scoring candidate. Previously high-balance plans often saw eight near-identical “Fill 24%” variants on slightly different age windows, hiding meaningful alternatives at lower brackets or fixed-amount strategies. Row 0 is still the global highest-scoring strategy; diversification only affects rows 1–7. The Score column makes the underlying ranking visible.
Retirement date display on the Personal tab
The Personal tab now shows the derived retirement date — month and year — directly below the Retirement Age input. Same for the spouse row when enabled. Previously the date was implicit in Current Age + Retirement Age + Month of Retirement, leaving room for ambiguity about which calendar year the engine actually treated as the retirement year. The new caption pulls them together so you can confirm your intent at a glance. Pure display addition; no engine math change.
One-Time Expenses: category-aware default name
When you add a one-time expense, the default name now reflects the category you've selected instead of always reading “Home Renovation”. If you change the category later, the name updates to match — unless you've typed a custom title, in which case your edit is preserved. The category dropdown options and labels are unchanged.
Today's $ deflation accuracy fix
Today's $ mode now uses different deflators for end-of-year balances and within-year cash flows. Previously the same deflator was applied to both, which slightly over-deflated cash-flow values like lifetime taxes, healthcare costs, and Roth conversion totals.
You'll see this as cash-flow tiles shifting ~1.5–3% in Today's $ mode from before. Balance tiles, Future $ mode, comparison deltas, and strategy rankings are unchanged.
Return rate fixes, Maryland local tax & life expectancy
Per-Account Return Rates
Individual account return rates are now fully independent. Previously, changing the Nominal Return on the Assumptions tab could silently overwrite rates you had set on specific accounts. That propagation is removed — each account keeps the rate you gave it. New accounts still inherit the current Nominal Return as their starting value, but changing Nominal Return later won’t reach back and overwrite them.
Monte Carlo stress simulations now scale volatility from a portfolio-weighted average of your actual account rates instead of tying to the Nominal Return slider. Shock scenarios reflect your real portfolio mix.
Maryland Local Tax
Maryland plans now include county/city local income tax in the projection. The rate defaults to 3.20% (Baltimore City) and is editable on the Tax tab. The Dashboard shows the combined line as “State & Local Tax” when a local rate is active.
Life Expectancy
New life expectancy fields on the Personal tab for you and your spouse. These feed into Survivor Planning defaults and will inform future planning scenarios.
Fixes
MAGI restored to the Projection chart’s selectable overlays — it had dropped off in a prior update. Switching tabs now scrolls to the top of the page.
Per-spouse healthcare transition, Today’s $ fix, JSON export
Per-spouse healthcare & Medicare transition. When spouses reach Medicare at different ages, RetIQ now models three distinct phases. While both are pre-Medicare, couple rates and a household-size-2 ACA benchmark apply. When the older spouse hits 65 and moves to Medicare, the younger spouse continues on your chosen coverage source at an individual rate — the Cost Summary table marks these rows with an Enrollees column showing the transition. Once both are on Medicare, pre-Medicare costs end. All six coverage sources (ACA, COBRA, Employer/Retiree, Spouse’s Plan, VA, Other) handle the split. For non-ACA sources, you can now enter an optional Individual Rate for the split-phase years; if left blank, RetIQ estimates a single rate from the couple rate. SSDI early Medicare is handled independently per spouse.
Today’s $ deflation fix. The Today’s $ toggle was deflating values one year too aggressively — Year 1 was treated as two years out instead of one. Fixed across all charts and projection tables.
JSON export. Your plan can now be exported as a JSON file from the Save menu (header ↓ button or overflow menu). Useful for backups or transferring plan data.
Income & Expenses rename. The former “Income & Spending” chart tab is now “Income & Expenses” with a guidance note explaining which cost categories are included.
Medicare now chartable on Projection tab. Medicare base cost was in the data table but missing from the chart category selector. Now available alongside IRMAA and Healthcare.
HSA contributions now reduce payroll tax
If you contribute to an HSA through your employer's cafeteria plan, those contributions are exempt from Social Security and Medicare tax. Previously, the projection engine calculated payroll tax on your full salary without accounting for this exclusion — overstating FICA by up to ~$750/year depending on your contribution level. Now fixed: your projected payroll taxes will be lower and more accurate.
Mixed-retirement tax accuracy fix
Fixed an issue where retirement projections could overstate taxes for households where one spouse retires while the other continues working. The working spouse's 401(k) contributions are now correctly reflected in income calculations, reducing projected tax burden during the overlap years.
Guide+ withdrawal answers, dashboard expense fix, collapsible assumptions
Guide: improved answers for questions about how account withdrawals work. Dashboard: fixed expense breakdown showing inflated totals. Inputs: modeling assumptions section is now collapsible.
Lees example family configuration update
Lees example family: updated account configuration to better demonstrate the Roth Optimizer workflow.
Medicare and IRMAA column accuracy
Fixed
The Medicare and IRMAA columns in the projection table and CSV export are now disjoint. Previously the Medicare column quietly included the IRMAA surcharge, so adding it to the IRMAA column over-stated total Medicare cost. After this release, the Medicare column shows base Part B premiums only and the IRMAA column shows the surcharge only. Their sum equals total annual Medicare cost.
In constant-dollar mode, the Medicare and IRMAA columns now adjust consistently across IRMAA tier transitions. The two columns previously used different inflation treatments, which made the totals appear to jump at tier boundaries that weren't real cost changes.
The Retirement Cash Flow chart on the Dashboard no longer over-states age-65+ deficits. It had been counting Medicare twice when totaling retirement outflows.
The Lifetime Medicare totals on the Healthcare and Survivor Center cards now correctly include both base premiums and IRMAA surcharges.
This release does not change net worth, taxes, account balances, or money-lasts-to-age. If you reload a saved plan, year-by-year totals are unchanged — only the Medicare/IRMAA split presentation has been corrected.
Take more control over your RMDs
RetIQ now gives you two new options for handling Required Minimum Distributions. The first is a checkbox that says "use my RMD to fund expenses first" — for most retirees this matches reality, since the IRS is forcing the money out anyway and it lands in checking. The second is a choice for where any leftover RMD cash goes: brokerage (reinvested) or cash/HYS (kept liquid). Both controls are in Inputs → Withdrawal Strategy.
The Projection chart and table now also split the Withdrawals line into two: "spending" (what you actually live on) and "RMD reinvested" (cash that just shuffles from pre-tax to brokerage because the IRS required it). The old "Withdrawals" line was the sum of both, which made post-RMD years look more dramatic than they really were.
Existing plans keep their previous behavior unchanged. Open the new RMD Handling panel to opt in.
More accurate projections for Roth 401(k) contributors
If you contribute to a Roth 401(k), your projected federal tax and Medicare premium estimates are now more accurate. Plans with Roth 401(k) contributions will show higher tax projections after this update — bringing them into alignment with how Roth 401(k) deferrals are actually treated on your W-2.
Year 1 baseline note on Projection tab
Added a small note clarifying that the first projection year shows expenses at today’s values and account balances after one year of growth, with inflation compounding thereafter. The convention was always intentional but unexplained — making it explicit so the chart and table read as expected.
CSV export and Expense Inflation Rate fixes
Two user-facing fixes. The CSV export Expenses column now matches the projection table (lifestyle only); Medicare and IRMAA appear as separate columns rather than bundled together. The Expense Inflation Rate input now uses general inflation when left blank, as the help text describes — previously the blank state was treated as 0%.
Tax accuracy fix for senior filers
Corrected federal tax computation for filers age 65+ with income above $75,000 (single) or $150,000 (married filing jointly). Affects projection years 2026–2028. The fix produces a slightly higher federal tax estimate in those scenarios — bringing projections into alignment with IRS authority for the new senior deduction provision.
More accurate tax calculations the year you turn 65
The engine now uses the IRS year-end age rule when checking eligibility for senior provisions: the additional standard deduction, the One Big Beautiful Bill Act senior bonus, HSA penalty rules at 65, and Medicare/IRMAA enrollment. Previously, projections could lag these by one year for users not born in January.
Social Security FRA recalculation now modeled
If you claim Social Security before your full retirement age (FRA) and continue working, SSA may temporarily withhold part of your benefits under the earnings test. That money isn’t lost — at FRA, SSA recalculates your monthly check upward to credit the withheld months back. RetIQ now reflects this in your projection.
Note: this update covers your own retirement benefit. Survivor benefits and the spousal-top-up portion of combined benefits aren’t yet adjusted, so projections in those cases remain slightly conservative.
Mega Backdoor Roth
Solo 401(k) users can now model the Mega Backdoor Roth strategy. Enable the toggle on the Self-Employed card to contribute after-tax dollars up to the remaining annual addition limit, then immediately convert to Roth. The engine auto-maximizes the headroom after your employee deferral and employer profit-share, or you can set a manual cap.
This strategy requires a Solo 401(k) plan that permits voluntary after-tax contributions and in-plan Roth conversions — not all custodians offer this feature. The after-tax amount goes directly to your Roth balance with no tax impact (assuming immediate conversion). No AGI or QBI changes from the after-tax contribution itself.
SIMPLE-IRA Contributions
Self-employed users can now model SIMPLE-IRA contributions alongside Solo 401(k) and SEP-IRA. Select SIMPLE-IRA from the Retirement Plan dropdown on the Self-Employed card. The engine calculates employee deferrals (up to the $17,000 limit plus age-based catch-up) and your choice of employer contribution: a 3% dollar-for-dollar match or a 2% non-elective contribution.
All the same tax interactions apply: traditional deferrals reduce AGI and QBI, Roth deferrals are available, and S-corp owners with high FICA wages get the SECURE 2.0 §603 mandatory Roth catch-up treatment. The engine uses standard SIMPLE limits — enhanced limits for employers with 25 or fewer employees are a known simplification noted in the help text.
SEP-IRA Support
Self-employed users can now choose SEP-IRA as their retirement plan. SEP-IRA contributions are employer-only — the same rates as Solo 401(k) employer contributions (20% for sole proprietors, 25% of salary for S-corps) but with no employee deferral component. This option is common for sole proprietors who want simplified retirement savings without the record-keeping of a Solo 401(k).
§199A W-2 Wage and UBIA Limits
The §199A QBI deduction now accounts for W-2 wages and qualified property (UBIA) when calculating the deduction limit above the income threshold. S-corp owners automatically include their salary in the W-2 wage calculation, which means the deduction is no longer forced to $0 at high income levels. The full formula — the greater of 50% of W-2 wages or 25% of wages plus 2.5% of UBIA — now matches the statute. Businesses with additional employees or significant qualified property can access these inputs via saved plan data; a dedicated UI is planned.
SECURE 2.0 §603 Roth Catch-Up
S-corp owners with FICA wages above $145,000 now have catch-up contributions automatically designated as Roth, per SECURE 2.0 §603 (effective January 2026). Your base deferral still follows your traditional/Roth choice — only the catch-up portion above the §402(g) limit is forced Roth. This does not affect sole proprietors, SMLLCs, or partnerships.
S-Corporation Support
Self-employed users can now choose S-corporation as their business structure. The engine models S-corp income correctly: your reasonable salary is subject to FICA (no self-employment tax), and distributions flow as ordinary income without additional payroll tax. Solo 401(k) employer contributions use the S-corp rate of 25% of W-2 salary instead of the sole-prop 20% rate. The §199A QBI deduction properly excludes your salary from qualified business income.
Roadmap: SECURE 2.0 §603 mandatory Roth catch-up for high-earning S-corp owners (prior-year FICA wages > $145K) is planned as a follow-up. SEP-IRA, SIMPLE-IRA, defined benefit plans, and Mega Backdoor Roth contributions remain Phase 2 enhancements.
State tax precision for self-employed users with QBI
State tax projections for self-employed users are now more precise. Idaho, Iowa, North Dakota, and Colorado users will see lower state tax — these states allow the federal QBI deduction to flow through to state income. California, New Jersey, and Pennsylvania users will also see lower state tax than v6.35.0; this corrects an over-count introduced last release. New York and all other states are unchanged.
Three precision improvements for self-employed users
Solo 401(k) deferral capacity is now reported more accurately for self-employed users whose annual savings can't fund the full W-2 401(k) deferral target. The engine previously assumed you'd hit your full W-2 target even when your annual savings were too small, which understated how much you could still contribute to a Solo 401(k).
Self-employed users with negative qualified business income (QBI) in one year now see that loss carry forward to offset positive QBI in future years, matching IRS rules. A new field on your projection year-rows tracks the carryforward in and out.
Users in California, New Jersey, or Pennsylvania now see correct state-tax treatment when they claim the federal QBI deduction — these states don't allow it at the state level, so the engine adds it back to your state taxable income.
More accurate Medicare premium estimates for retirees with active income streams
If you're already retired with active income streams (rental, consulting, annuities, etc.) and haven't filled in the prior-year MAGI fields, the engine now factors those streams into your IRMAA estimate for years 1–2 instead of treating early-year MAGI as zero.
If you've already entered prior-year MAGI in the Medicare & IRMAA card, those values continue to take precedence — this only changes behavior for users who left those fields blank.
Sharper Medicare premium estimates for your first two retirement years
Medicare premium surcharges (IRMAA) are based on your tax return from 2 years prior — so the first 1–2 years of any retirement projection have to estimate something the actual lookback doesn't cover yet. If you know your MAGI from 1 and 2 years ago, you can now enter them in the Medicare & IRMAA card to refine your IRMAA projections.
Filling these new fields replaces the engine's estimate with your real numbers. Leave them blank if you'd rather use the estimate.
Guide+ improvements
Some questions about retirement income from investment accounts were getting routed to the wrong canned answer (the Legacy one about leaving money to heirs). Fixed.
Also fixed an unhelpful "Cloud AI is not configured" message that showed up even when Cloud AI was configured correctly but the call had just failed. Now it distinguishes between the two cases.
Strategy Report polish
Cleaned up two small inconsistencies in the Strategy Report. The Tax-Free Legacy goal now highlights the actual tax-adjusted legacy value instead of raw end-of-plan net worth — what gets shown matches what the strategy was scored on. The illustrative QLAC annual payout in suggestion cards now reads from a documented source instead of an inline magic number; the displayed amount is unchanged.
Healthcare cost calibration and verdict accuracy
Refreshed Medicare IRMAA and ACA marketplace subsidy values to match the official 2026 published numbers from CMS and the IRS, and updated the QCD (Qualified Charitable Distribution) annual limit to $111,000 for 2026. Plan Health verdicts are now more accurate over long horizons — previously the cushion check could miss thin plans because it didn't fully account for inflation.
Faster Roth conversion optimizer
Made the Roth conversion optimizer noticeably faster. The optimizer searches over many candidate conversion schedules to find the one that minimizes lifetime taxes — it was running a full tax calculation loop for each candidate when a faster equivalent was available. Same recommendation, less waiting.
Also tidied up some platform-detection code that became redundant after last release's access-check fix. No user-visible change.
Native app access check hardened
Fixed an access check on iOS and macOS. Some premium features could be opened on the native apps without an active purchase. The check now verifies your purchase status the same way on every platform.
The JSON export option now uses the same access check as the other export formats — it had been missing one. If you've already purchased the full version, none of this changes what you see.
2026 Social Security values + refreshed Model Notes
Updated Social Security calculations to use the 2026 statutory values announced by SSA in October 2025. PIA bend points and earnings-test limits now reflect current-year amounts. For users projecting Social Security benefits via earnings-history estimation, this corrects an understatement of about 1.5% in projected benefits. If you've already provided your PIA from your SSA statement, this change doesn't affect your projection.
Refreshed the Model Notes shown in Inputs and the Strategy Report. Notes now affirmatively describe how federal tax brackets, standard deduction, capital gains breakpoints, QBI thresholds, and IRMAA tier amounts are projected forward from 2026 base values year-over-year. Added a note covering the OBBB §70103 senior deduction (available 2025-2028, sunsets December 31, 2028 unless extended). Fixed three stale year references in input field help text — IRMAA bracket label, earnings-test prose, and QCD limit (now $111,000 per IRS Notice 2025-67).
More accurate Roth conversion and Tax-Aware Drawdown recommendations near the senior-deduction phase-out
Improved Roth conversion and Tax-Aware Drawdown recommendations for users in the new senior-deduction phase-out range. The optimizer now uses the same income definition as the underlying tax calculation when sizing conversions or withdrawals, so its recommendations more accurately hit the bracket targets it claims.
Affects users age 65 or older with income near the phase-out band. Outside that band, recommendations are unchanged.
Social Security wage base projections updated to SSA Trustees intermediate growth
Updated the Social Security wage base projection to match the latest SSA Trustees Report intermediate growth assumption (3.6% per year, up from 3.0%). This affects retirement projections that reach the wage base cap, providing more accurate Social Security benefit estimates and FICA / self-employment tax projections for high earners over long horizons.
The change also tracks the annual Social Security earnings test limits, which grow at the same rate.
Medicare IRMAA tier thresholds adjust for inflation
The Medicare IRMAA income brackets that determine your Part B and Part D surcharges now adjust for inflation across your plan's projection years. Previously, the brackets were held at 2026 values for the life of your plan, which slightly overstated your projected Medicare costs in later years. Plans projecting income near the IRMAA thresholds may now show somewhat lower projected Medicare premiums in later years. The top tier ($750K MFJ / $500K Single) is statutorily frozen until 2028, then begins indexing — engine reflects this correctly.
Tax bracket and deduction indexing across projection years
Federal income tax brackets, standard deduction, senior addition, OBBB §70103 senior deduction, capital gains breakpoints, and QBI thresholds now adjust for inflation across your plan's projection years. Previously these were held at 2026 values for the life of your plan, which meant late-year projections overstated your tax bill. Plans that extend more than a few years into the future may now show somewhat lower projected taxes in the later years.
Tax accuracy fixes for IRMAA and ACA
Two related accuracy fixes for users in specific situations. If you're still working with 401(k) contributions, the engine no longer overstates your income when checking your future Medicare premium tier. If you're collecting Social Security and using ACA marketplace coverage before Medicare, your projected ACA subsidy is now correctly calculated against the income definition the IRS actually uses for that program. Plan results may shift slightly for these scenarios; everyone else is unaffected.
IRA catch-up updated to $1,100 for 2026
Updated the IRA catch-up contribution limit (the extra you can contribute starting at age 50) from $1,000 to $1,100 to match the 2026 IRS-published amount. The HSA over-55 catch-up stays at $1,000 (not indexed to inflation by statute).
Catch-up contribution caps
Fixed a small projection issue where IRA catch-up contributions (the extra $1,000 you can contribute starting at age 50) and HSA catch-up contributions (the extra $1,000 if you're 55 or older) were being inflated each year. Both amounts are set by statute and don't change with inflation. The correction mostly affects retirement-prep plans 10+ years out, where projected contribution caps are now slightly lower (and accurate).
Social Security and self-employment tax projections
Multi-decade plans now project the Social Security wage base forward each year using the annual indexing rate, instead of holding it flat at the current-year value. This makes the FICA and self-employment tax cap track inflation across long retirement plans, which mostly matters for self-employed retirees and high-earners with W-2 wages above the cap.
Also fixed an edge case where Additional Medicare tax (the 0.9% surtax for high-income households) wasn't being applied during retirement years for self-employed households on the TAD strategy branch. The total tax bill in those years is slightly higher and more accurate.
State-tax accuracy and Social Security guidance
Maryland's local income tax (county and Baltimore City rates of 2.25% to 3.30%) is now factored into your projection. Default rate is 3.30%, the statutory cap matching Baltimore City and several counties. If your county uses a different rate, you can override it in the State for Tax Purposes section.
New Jersey's pension and IRA exclusion now correctly phases out across four tiers based on your gross income, with separate maximum values for joint filers ($100K) and single filers ($75K). Previously the engine applied a flat exclusion regardless of income or filing status, which over-excluded most NJ retirees and entirely missed the cliff at $150K.
If you're under 62 and using the average-income-based estimate for Social Security, the calculator now includes a brief note explaining that this estimate may understate your benefit by 10 to 15 percent, and points you to your SSA statement for a more accurate projection.
Social Security COLA accuracy fix
Fixed a long-running bug where projected Social Security benefits didn't reflect cost-of-living adjustments between today and your planned claim age. If you're 62 and planning to claim at 67, your statement-PIA now grows with your assumed COLA over those 5 years before claim, then continues annually thereafter — matching how SSA actually calculates benefits.
Users with 5+ years between today and claim see meaningfully higher projected lifetime SS. The largest corrections are for users delaying claim past full retirement age. Already-collecting users see no change — their entered current monthly already reflects past COLAs.
Phase C engine accuracy
Several federal tax calculations have been tightened. You'll see slightly different numbers if you have self-employment income above the IRS Additional Medicare Tax threshold ($200K single / $250K joint), ordinary (non-qualified) dividends from a taxable brokerage account, or a spouse claiming Social Security before their full retirement age. Plans without those features won't show changes.
The Medicare cost inflation rate is now a user-configurable input on the Healthcare tab (default still 5%/year), so you can stress-test against your own assumptions about Medicare premium growth.
Survivor Plan now shown on every tab
When a Survivor Plan is active, a banner now appears at the top of every tab so you always know which mode you're in. The banner includes an Exit button. Previously the active state was only indicated on the Adopt Plan sub-tab, which made it possible to forget you were in single-person mode.
Survivor benefit now pays automatically once the survivor reaches Full Retirement Age, regardless of the Survivor SS Claim Age setting.
ACA subsidy fix for early-retirement first year
The Pre-Medicare Healthcare projection underreported the ACA premium tax credit in the first year for retirees who fund their living expenses primarily from pre-tax withdrawals before Social Security or pension income begins. In that scenario the first-year subsidy could show as $0 even when the displayed MAGI was clearly within the eligible range. Subsequent years calculated correctly. The first-year estimate now reflects the same income proxy used in the input-screen subsidy preview, so the subsidy shown on the input screen matches what the projection delivers from year one.
Dashboard: still-working spouse income on retirement-view card
For households where one spouse has retired but the other is still employed, the Dashboard’s “This Year’s Retirement Plan” card now shows the working spouse’s earned income as a row in the Inflows section. Previously the retirement-view card had no earned-income line at all, so a working spouse’s salary was invisible despite being correctly taxed under the hood. Rows are labeled “Your Income (still working)” or “Spouse Income (still working)” to disambiguate from the working-view card.
The Net Annual Cash Flow bar for retired plans now correctly includes the working spouse’s wages as external income. If your plan has a retired primary plus a working spouse whose salary covers most retirement expenses, you may see this bar shift from amber (portfolio drain) to green (surplus). The previous behavior was a gap, not a feature — W-2 wages from a working spouse are external income, just like Social Security or pension.
Plans where both spouses are retired, solo plans, and plans where the retired person has no working spouse are unaffected.
Hotfix: blank Dashboard for dual-spouse plans with spouse-owned pre-tax accounts
Users with both spouses enabled AND at least one pre-tax account marked as spouse-owned would see a blank Dashboard tab whenever the engine output triggered the dual-owner RMD badge code path. Other tabs (Inputs, Projection, Monte Carlo, etc.) worked normally; only Dashboard rendering was affected. Engine math was unaffected throughout — this was purely a UI render-time crash.
Cause: a v6.18.14 dashboard change referenced a local variable rmdAge that didn't exist in the renderDashboard function's scope. The variable was declared in a sibling helper function further up the file, and the v6.18.14 brief assumed scope membership based on lexical presence rather than enclosing-function membership. JavaScript threw ReferenceError: rmdAge is not defined the first time the dual-owner badge code executed, aborting the dashboard render mid-write and leaving a blank tab.
Fix: declared rmdAge at the top of renderDashboard's scope using the same expression the sibling helper uses. One-line addition. Also flipped a related || to ?? in the sibling helper to match the project's defensive-coercion convention (consistent with the v6.17.x coercion sweep).
Cleaner Projection table Expenses, Medicare, and IRMAA columns
The Expenses, Medicare, and IRMAA columns on the year-by-year Projection table previously included one another — Expenses silently included Medicare premiums and IRMAA surcharges, and the Medicare column duplicated the IRMAA portion. Adding all three together produced a number much larger than reality. Now the columns decompose cleanly: Expenses shows your non-Medicare retirement spending, Medicare shows the base premium only, and IRMAA shows the surcharge. Adding the three together matches the engine's full expense total. The chart line for Expenses uses the same decomposition so chart and table agree.
RMD card now reflects both spouses; new inherited-distributions card; RMD badge added to the Dashboard
The RMD information card on the Accounts tab now shows the right thing for households where both spouses have their own pre-tax accounts — it surfaces both ages, both first-year estimates, and orders them by who reaches RMD age first. Single-owner households see the same card as before.
A new inherited-distributions card appears below the RMD card when you have an inherited IRA. It shows the inherited balance and the SECURE Act 10-year deadline. Inherited distributions are separate from your own RMDs and the card is labeled accordingly so the two never get confused.
Finally, an RMD badge has been added to the Dashboard's Active Strategies row, alongside Roth Conversions, Tax-Aware Drawdown, Social Security, and Inherited. It shows your lifetime RMD total and when RMDs start.
Two UI fixes from user feedback
The Dashboard "Active Strategies" Social Security badge displayed the FRA monthly amount times twelve, ignoring early/late claim-age adjustments, ignoring COLA accrual, and ignoring the Today's $ / Future $ toggle — so the badge value didn't match what the projection actually used. The fix pulls the badge value from the first projection year where Social Security is paid, deflated per year. All engine adjustments (ssaAdjustPIA early/late credits, COLA, earnings-test withholding, SSDI auto-conversion, "already collecting") are now reflected automatically, and the badge honors the dollar toggle the same way the sibling Roth Conversion and Tax-Aware Drawdown badges already did. The badge age also now reflects SSDI's FRA-conversion override when active, matching the Inputs → SS tab.
The Charitable Giving Annual Amount field rejected $0 once any other value had been entered — typing zero stored zero correctly, but the next render fell back to the default $10,000 because of a ||-vs-?? coercion bug. Now respects an explicit zero. Same pattern that v6.16/v6.17.5/v6.17.6 swept across roughly 30 sites; this site was missed.
Engine math and state management are unchanged in both fixes — both bugs lived purely in the render layer.
Per-account post-2019 inherited IRA distributions
Two bugs fixed in the SECURE Act 10-year forced-distribution path. Multiple post-2019 inherited IRAs with different inheritedYear values previously shared a single deadline (the earliest), so an account inherited in 2026 alongside one inherited in 2021 was forced to deplete on the 2031 deadline instead of 2036 — reported by a user testing v6.18.10. Independently, inherited Roth distributionTiming used .find() on the accounts array, applying the first account's regime to all pooled inherited Roth balances; now respected per-account.
The post-2019 distribution math now mirrors the per-account loop already in place for pre-2020 stretch IRAs. Pooled inheritedPreTax / inheritedRoth are kept as derived sums for downstream consumers (growth, net worth, year-record); invariant pool == sum(working copies) maintained through distribution, growth, and one-time-expense paths.
Authority: IRC §401(a)(9)(H)(i) (per-decedent 10-year window); IRS T.D. 10001 (July 19, 2024) (no annual RMD requirement on inherited Roth during the window); IRC §408A(c)(5) (beneficiary-discretionary timing). 3 new validation tests under the “Inherited Per-Account” category lock the per-account schedule, the depletion-order invariant, and per-account regime selection on inherited Roth.
Also: minor test arg-order tidy in test-validation.js (one assertion in the new Inherited Per-Account category had expected and actual swapped — passed correctly because the assertion is symmetric, but reordered to match the rest of the suite for readability).
QLAC per-spouse modeling
Each spouse can now hold their own QLAC, tied to their own pre-tax balance and their own RMDs. A married couple can model up to $420,000 in combined QLACs ($210,000 each in 2026 per IRS Notice 2025-67). When you have a spouse enabled with at least one pre-tax account marked as theirs (in Accounts), a separate Spouse QLAC card appears in Inputs → Pension below the primary QLAC card.
This is also a correctness fix. Previously, a single household-level QLAC purchase drew proportionally from both spouses' pre-tax shares. Under Treas. Reg. §1.401(a)(9)-6, a QLAC reduces only its owner's IRA balance and only that owner's RMD. The engine now attributes purchase and payout to the correct owner. For a couple with equal pre-tax balances, this means a $200K primary QLAC fully reduces primary's RMD instead of half-reducing each spouse's RMD.
The Strategy Report Card now suggests up to three QLAC alternatives where appropriate: Primary QLAC (when primary's pre-tax balance exceeds $300K), Spouse QLAC (when spouse's exceeds $300K), and Dual QLAC (when both qualify and neither is currently enabled). The "No QLAC" alternative considers whichever combination is currently active.
Engine year-output adds four per-owner fields: qlacBalancePrimary, qlacBalanceSpouse, qlacPayoutPrimary, qlacPayoutSpouse. The existing qlacBalance and qlacPayout fields keep their household-sum meaning — charts, dashboard, CSV export, and native iOS/macOS continue to work without modification. Six new validation tests on a spouse-enabled fixture cover dual-disabled, primary-only attribution, dual-purchase totals, the backward-compatibility sum invariant, and spouse-age-driven payout timing.
Sources: IRC §401(a)(9)(F); Treas. Reg. §1.401(a)(9)-6 Q&A-17(b); SECURE 2.0 Act §202; IRS Notice 2025-67; Form 1098-Q.
QLAC purchase cap updated to 2026 limit ($210,000)
The QLAC purchase cap moves from the SECURE 2.0 base of $200,000 to the 2026 inflation-adjusted limit of $210,000. The cap is now sourced from REGS.retirement_accounts.qlac_limit — the same regulatory data layer that holds federal brackets, contribution limits, and IRMAA thresholds — so future inflation adjustments land via the regulatory data feed without code changes. Updated in the engine, Inputs → Pension & QLAC card, Strategy Report alternative, manual, features page, and AI guide. Sourced from IRS Notice 2025-67; SECURE 2.0 Act §202; Treas. Reg. §1.401(a)(9)-6.
Two new validation tests cover the constant value and the engine's enforcement of the cap when a user requests more than the limit.
This release does not change the per-individual nature of the cap. RetIQ currently models a single household-level QLAC; a future release will add per-spouse QLAC modeling so married couples can reflect the full $420,000 of combined eligibility ($210,000 each).
Separately, repaired the QLAC test fixture in test-validation.js. The previous minimal fixture was missing several engine-required fields (birthYear, nominalReturn, SS config, etc.), which caused runProjection() to return NaN throughout the projection. Three of the four existing QLAC tests had been passing for the wrong reason — their boolean-ternary outputs fell through to 0, and the integer tolerance of 1 absorbed the failure. Fixture repaired to a complete params object; all four tests now pass against real numeric output. No engine changes; the assertions were correct, only the inputs feeding them were broken.
Today's $ toggle: inline rate is now read-only and links to Assumptions
The small % infl. input on the Today's $ toggle looked editable but discarded any value typed into it — both render() and renderDollarToggle() reassigned the displayed rate from state.params.inflation on every redraw, overwriting any inline edit before it could take effect.
The inline input is now a read-only, clickable label that jumps to Inputs → Assumptions and scrolls the Inflation Rate field into view. Single source of truth: change the rate once, in Assumptions, and the toggle reflects it everywhere — matching what the iOS and macOS apps already do. Allowing a divergent display rate would produce mathematically meaningless numbers (deflating nominal projections by a rate that doesn't equal the engine's inflation yields neither today's dollars nor future dollars), so removing the editable surface is also the mathematically correct choice.
New regression tests in test-ui-paths.js lock in the read-only markup and the navigation helper export.
Dashboard — per-spouse income rows
The "This Year" card on the dashboard now shows Your Income and Spouse Income as separate rows when a spouse is enabled, mirroring the labels on the Inputs tab. Solo plans continue to show a single Employment Income row.
Engine: new primaryEarned and spouseEarned fields on the year-output object. Additive only — no math changes. The existing earned field is unchanged and still equals primaryEarned + spouseEarned. Three new validation tests assert field presence and the sum invariant.
Healthcare tab card order fix
v6.18.6 missed a card when merging Medicare into Healthcare. The Pre-Medicare Coverage Cost Summary — which shows gap length, total net cost, and a year-by-year cost table for the pre-Medicare years — was sitting at the bottom of the Healthcare tab, separated from its config card by Medicare and LTC. Moved it to immediately follow Pre-Medicare Healthcare. New order: Pre-Medicare Healthcare config → its Cost Summary → Medicare & IRMAA → Long-Term Care. Pre-Medicare config and its derived display now sit together; Medicare and LTC come after as the later phases.
Healthcare and Medicare combined into one tab
The Inputs → Medicare tab had no inputs — just an IRMAA bracket table, lifetime stats, and a chart, all computed from the projection. A user pointed out the disconnect: the tab name promised inputs, the page delivered display. The fix is structural rather than cosmetic: combine Healthcare and Medicare into a single Healthcare tab with three cards stacked vertically — Pre-Medicare Healthcare, Medicare & IRMAA, and Long-Term Care. Reading order matches age progression (before 65, 65+, typically 80+).
The web sub-nav drops from 14 tabs to 13. The Medicare card content is unchanged — same bracket table, same chart, same lifetime stats — just relocated. If a saved plan was sitting on the Medicare tab when it last loaded, the next render quietly redirects to Healthcare so nothing appears broken. Plan Health levers and AI guide references that pointed at the old Medicare tab now point at Healthcare.
This brings the web app's IA in line with the iOS native app, which already groups Pre-Medicare and Medicare under a single Healthcare disclosure.
Peak Net Worth and Peak RMD now correct in Today's $
A user diagnosed this one cleanly: "the peak is identified in future $s, and then displayed (accurately) in both toggle settings. That can lead to the scenario where the peak in future $s (converted to current $s) is less than the current value (current $s), so the display is off." Exactly right.
The Snapshot was identifying the peak year by largest nominal Net Worth, then deflating that single value when the Today's $ toggle was on. For retirement plans where Net Worth grows nominally for a decade or two before declining, the nominal-peak year is far enough in the future that its deflated value is smaller than year 0 (Current Net Worth). One user saw $4.0M Current and $2.9M Peak in Today's $ — mathematically impossible when computed correctly, since year 0 is always one of the candidates for "max."
Fix: deflate each year individually first, then take the max. The maximum of the per-year deflated values can never be less than year 0's value. Matches the v6.18 Projection Table totals fix — same pattern, single-statistic version.
Same fix applies to Peak RMD in the Active Strategies card and to the Plan Health levers helper. The dual-owner Peak RMD sub-line now reads per-owner amounts from the year where the deflated total RMD peaks, so the sub-line reconciles with the main value. 11 new regression tests in test-ui-paths.js reproduce the reported scenario and lock the corrected behavior.
Future $ display is unchanged. For retirement plans declining in real terms (the common case), Peak Today's $ will typically equal Current Today's $ — today is your peak purchasing-power year, before withdrawals erode it.
Honest stress test labels and std dev guidance
The Monte Carlo Stress Test was advertised as "worse than historical" but at default settings (6% return std dev, fat-tailed distribution) it was actually gentler than Historical replay — because Historical inherits the actual ~19% S&P 500 variance from 1928–2024 data, while Stress Test's variance is governed by the std dev parameter you set. Six percent fat-tailed is dominated by Historical's nineteen percent intrinsic variance, regardless of fat tails.
Three honesty fixes:
- Help text numbers corrected. "Return Std Dev: Historical ~6%" was misleading — that's a 20/80 stocks/bonds portfolio, not historical. Now shows allocation-aware guidance: 6% (20/80), 9% (40/60), 12% (60/40), 15% (75/25), 19% (100% stocks). "Inflation Std Dev: Historical ~1.5%" was wrong (actual is 3.9% from 1928–2024) — now explains that 1.5% reflects post-1990 calm and the full-historical figure is 3.9%.
- Model description rewritten. Stress Test no longer claims to be "worse than historical." Now explains honestly: heavy-tailed at the std dev you pick. To make it genuinely worse than Historical, set Return Std Dev to 19%+ to match S&P historical variance.
- Allocation guide added. A reference card under the Simulation Settings shows the typical std dev for each common stock/bond mix, so picking a value isn't a guess.
The default values (6% / 1.5%) are unchanged so saved plans don't shift. Users who want a real stress test now have correct guidance to set honest values.
Engine math is unchanged. Validation tests unaffected.
Pensions and QLACs honor fractional start ages
If you set a pension's start age to a fractional value like 65.5, the engine was using integer-floor activation: at age 65 the comparison 65 >= 65.5 is false, so the pension was skipped entirely. At age 66 it activated with the full annual amount. The user who reported this had a $36K pension starting at 65.5 and lost six months of income (~$18K) from the projection.
Now the engine activates the pension when the user's age year overlaps the start age and pays a prorated amount for the first partial year. Setting startAge: 65.5 with a $36K annual amount pays $18K in the age-65 fiscal year, then $36K every year after. Same fix applies to the spouse pension and to QLAC payout start age. Integer start ages (the most common case) produce identical results to before — this is a backward-compatible bug fix.
Tax treatment: pension payments are gross income in the year received per IRC §61(a)(11), and QLAC payouts are taxable as ordinary income per IRC §401(a)(9)(F) and Treas. Reg. §1.401(a)(9)-6 Q&A-17 — both fully consistent with reporting the prorated cash actually received in a partial year. taxablePercent and survivorBenefit ratios apply post-proration; the math is associative.
11 new regression tests in test-validation.js covering integer baseline, fractional 0.25/0.5/0.75 cases, pre-activation zero, lifetime invariant, spouse pension proration, COLA compounding over fractional years, and taxablePercent post-proration application. Engine validation total goes from 519 to 530, all green.
Honest Medicare display + correct Expenses guidance
The engine adds Medicare premiums and IRMAA surcharges to expenses automatically once you reach Medicare age (CMS bills the beneficiary, so it's a real cash outflow). Three places didn't reflect that consistently:
- Net Annual Cash Flow breakdown on the Retirement tab: showed a "Medicare Premium" row separately from "Living Expenses", but Living Expenses already silently included Medicare. The cash-flow total was correct (Medicare subtracted exactly once via the expense field) but the visual breakdown looked like double-counting. Living Expenses now shows the non-Medicare portion only, so the rows you see are honest about what's actually being deducted where.
- Annual Expenses field help text: said "Include routine Medicare-era health costs here". Following that instruction created an actual double-count in the engine, since Medicare gets added on top regardless. Help now says: do not include Medicare premiums — the engine computes those automatically based on your projected MAGI and IRMAA tier.
- Retirement Expense Phases card: lived on the Healthcare tab but the phase multiplier applies to all spending (food, travel, hobbies), not just healthcare. Moved to the Expenses tab next to Post-Retirement Expenses where it conceptually belongs.
Engine math is unchanged. The retirement expenses field continues to mean "your non-medical retirement spending today, in today's dollars" — which is what most users were intending to enter anyway. If you previously included an estimate of Medicare premiums in your annual expense figure (per the old guidance), your projection was overstating costs by roughly that amount each year past 65; you should now subtract it out for an accurate model.
Today's $ toggle now applies to Scenarios, Monte Carlo, and Medicare charts
Three charts were ignoring the dollar toggle and showing only Future $ values regardless of the user's selection: the Scenarios comparison chart, the Monte Carlo fan chart and statistics (Median Final, 10th/90th percentile), and the Medicare Costs by Age chart on the Medicare input tab. The status bars above the Scenarios chart already deflated correctly — only the chart itself was wrong — so users saw a numeric mismatch between the stat row and the chart. Monte Carlo was the most confusing: nothing updated when toggling unless the user re-ran the simulation.
Root cause: each chart's data construction fed buildChart raw nominal values from the projection without applying the per-year deflate() helper. Now they follow the dashboard's net-worth-chart convention: deflate each year individually before passing to the chart. Same pattern as the v6.18 fix to the projection table totals row.
Audit-discovered: the same bug existed in 11 additional charts — Bear Market stress test, Healthcare Inflation stress test, Relocation comparison, three Survivor Center charts (NW/SS/Tax), four Roth Conversion Impact Analysis charts (Advantage, Pre-Tax/Roth balance comparisons, Annual Conversions), and three Roth Conversion Optimizer charts (Cumulative Tax, Conversion Advantage, Account Composition). All 14 chart sites are now fixed.
4 new regression tests in test-ui-paths.js covering the chart-data deflation convention. The deploy gate's per-year-deflation pattern grep continues to enforce consistency across the codebase.
Projection Table totals row now uses per-year deflation
The year-by-year Projection Table's totals row was computing each currency column total by summing nominal values across all years, then deflating that single total once at the midpoint year. That works for uniformly-distributed streams but is wrong for anything concentrated early or late in retirement. Roth conversions cluster in early retirement — per-year deflation barely shrinks them, midpoint deflation over-deflates by ~10 years' worth, understating the total. RMDs and late-life healthcare cluster late — opposite direction, overstating. Now matches the dashboard's Active Strategies badge convention: deflate each year individually, then sum.
If you were comparing the dashboard's "Roth Conv" badge in Today's $ against the projection table's "Roth Conv" totals row, you'd see different numbers (one user reported $1.1M vs $764K for the same plan). Future $ totals were unaffected because no deflation is applied in nominal mode. After this release, the badge and the table agree.
Same fix applies to every other currency column in the totals row — Tax, RMD, Withdrawals, IRMAA, Medicare, ACA, Charity, Capital Gains, Cash Interest. All now match the dashboard's per-year deflation convention. 4 new regression tests in test-ui-paths.js.
Behavioral note: anyone running side-by-side Today's $ comparisons between the dashboard and the table will now see consistent numbers. Anyone who only used the table totals will see slightly different numbers depending on the stream's distribution — the new numbers are correct, the old ones were biased.
Final coercion sweep: 0% honored for employer match, SS trust fund, cash events, Roth %
Closing chapter on the ||-vs-?? bug pattern. v6.17.4 fixed the dollar-toggle. v6.17.5 swept the next 23 sites. This release fixes the last 4 field families I knew about: employer match override (custom percent and cap), SS Trust Fund reduction (the headline scenario where users model "what if Congress doesn't act"), cash event net percent (sale, inheritance, business-sale modeling), and Roth conversion percentage-of-balance.
The most user-impactful fix here is SS Trust Fund: setting reduction percent to 0% (meaning "Congress acts, full benefits paid") was being silently coerced to 20%. Anyone running side-by-side comparisons of the no-action vs. action scenarios was getting the wrong baseline.
Pattern category is now retired across the codebase. The deploy-gate regression tests and post-deploy curl checks lock the behavior. Any future || regression at any of the 30+ sites we've fixed since v6.17.4 will fail the gate.
Sweep: 0% honored for every numeric assumption
Continuation of v6.17.4. The audit there flagged ~15 additional sites with the same X || N coercion pattern across the codebase. After review, every one of them was a real bug — in this codebase, every numeric user input has a meaningful 0 case. This release converts all of them to ?? so explicit 0 is honored.
Field families fixed: nominal return (4 sites — Strategy Report, PDF export, Survivor Center, Plan Health), healthcare inflation chains (Pre-Medicare and Medicare), LTC inflation, survivor expense reduction, expense phase multipliers (later/late retirement), and Guyton-Klinger guardrails (lower, upper, adjustment).
Behavioral note: if you had any plan with one of these fields explicitly set to 0% (e.g., a "stable healthcare costs" stress scenario, or a "guardrails do nothing" experiment), your projection and Today's $ display will now actually reflect the 0% you typed. Pre-fix, those plans were silently running at the field's default rate.
11 new regression tests in test-ui-paths.js covering every fixed field family. The bug pattern is now closed across the codebase: a future X || N regression at any of these sites would fail the deploy gate.
Fix: Inflation 0% now honored by Today's $ toggle
Setting Assumptions → Inflation to 0% had no effect on the dollar-toggle: the top-line rate display kept reading 3% (or whatever the previous value was), and the inline rate input on the toggle accepted edits but didn't stick after the next render. The pension display in Today's $ also continued to degrade over time as if inflation were still 3%. Two lines in the dollar-toggle and main render functions used JavaScript's || operator to fall back when the inflation field was missing — but 0 || 3 === 3 in JavaScript, so an explicit user-entered 0 was silently coerced to the default. Both lines now use ?? (nullish coalescing), which only triggers the fallback for null or undefined — not for an intentional 0.
This is the same coercion pattern that affected SS COLA before v6.16 (where setting SS COLA = 0% silently ran 2%). When that fix shipped, I patched six engine sites but didn't audit the rest of the codebase. This release runs a comprehensive audit and closes the pattern across the dollar-toggle. New regression tests in test-ui-paths.js lock the behavior so a future || regression at either site would fail the deploy gate.
Behavioral note: any saved plan with inflation: 0 will now actually project at 0% inflation. Pre-fix, those plans were silently running at 3% deflation in the Today's $ display (Future $ was unaffected). If you had a plan where you'd set 0% to test a "real-dollar" scenario, your Today's $ numbers will now match Future $ values exactly, which is the correct behavior.
Cash Interest income now visible on dashboard and projection
Interest from cash, HYS, money market, CD, and short-term Treasury holdings — the cashInterest field the engine has always produced — was missing from the dashboard’s Inflows section and the year-by-year Projection Table. The engine routed it correctly through every tax pipeline (NIIT, ordinary income, MAGI, Social Security provisional), but a user with $200K in a money-market account at 2% yield wouldn’t see the $4,000/year of interest anywhere unless they manually checked the chart-overlay “Cash Interest Income” box. Now it appears as a row on the Retirement-tab and Working-tab Income sections, and as a Cash Int column in the Projection Table (auto-hides at zero). Net Annual Cash Flow bar on the Retirement tab includes it in the inflows side.
No engine math change. Existing validation tests cover the underlying calculation and tax routing — this release surfaces the number to UI.
Fix: phantom $6K “Other Income” for empty-portfolio plans
Long-running issue where the projection’s OTHER INC column showed a flat $6,000/year on plans that had no income inputs and no portfolio — particularly visible to users who were testing the app with a zeroed-out scenario. Cause: the legacy additionalIncome field defaulted to $6,000 in fresh plans, the web UI was replaced by Income Streams in v4.x and never exposed an input for it, and the engine’s backward-compatibility shim was virtualizing the legacy field even on plans that had already been migrated to streams (i.e., had incomeStreams: []). The combination produced a stale $6K floor that no UI control could clear.
Three-layer fix. The seed default is $0, so new plans never reproduce the state. State migration zeros stale additionalIncome on any plan that already has an incomeStreams array (legitimate pre-v4.x plans, where incomeStreams is genuinely undefined, are untouched). The engine’s legacy virtualization shim now requires incomeStreams === undefined to fire, so the phantom can’t return through any load path even if a saved plan slips past migration.
Three new validation tests cover the stuck state, legacy passthrough, and stream precedence. Reported by users running zero-input scenarios in v6.16.x; an earlier attempt today shipped a partial fix that didn’t address the engine-side back-fill.
Fix: Annual Benefit summary card now reflects current benefit when already collecting
If you had “I’m already collecting Social Security” toggled on, the green “Annual Benefit” summary card under each SS card was sourcing its number from the legacy SSA-statement / income-based path and ignoring your entered current monthly benefit. On the spouse side this showed as $0 when no legacy fields were filled in; on the primary side it showed slightly off (off by whatever drift was in the leftover manual entry). Now both cards read directly from the entered current benefit when already-collecting is on, and the card label drops “at Claim Age X” since it doesn’t apply.
The reduction-percentage and Earnings Test warnings that sit beneath the summary card are also suppressed in already-collecting mode — both are forward-looking warnings about claiming decisions, irrelevant once you’ve already claimed.
No engine change. The projection itself was already correct (v6.16 wired the engine path); this fix only addresses the input-tab summary display.
Multiple pensions per person
You can now model more than one pension per person on the Pension tab. Use the “+ Add Pension” button to add a second (or third, or more) pension for yourself or your spouse — useful for households where one person has benefits from multiple former employers, or military retirement plus a civilian pension. Each entry has its own start age, COLA, survivor option, and taxable percentage. The engine sums all enabled entries each year.
The single-pension input cards from prior versions are still there as the first entry; they auto-migrated when you opened the app under v6.16.x. Saved plans load unchanged.
Manual updated. Engine math is unchanged from v6.16.x — the underlying array structure was already in place; this release exposes it in the UI.
Pension data structure refactor (internal)
The engine and state now store pensions as an array (pensions[]) instead of two scalar params (pension and spousePension). Saved plans auto-migrate on load. No user-visible change — the input UI still shows the same Your Pension and Spouse Pension cards. This is preparation work for a future update that will let you model multiple pensions per spouse (military + civilian, multiple former employers, etc.).
5 new validation tests cover the migration shim, two-pension-per-spouse summation, staggered start ages, and mixed-owner pairs. All existing pension tests pass unchanged on the new array-backed engine.
Manual update for “Already collecting” SS mode
Documentation pass following v6.16. The Social Security sections of manual.html and the in-app iOS manual now describe the third entry mode (“Already collecting”) alongside the existing income-based estimate and SSA-statement-at-FRA modes, and call out that the entered amount is gross of Medicare Part B premium deduction in all three modes. No engine or UI logic changes.
“Already collecting” mode for Social Security
You can now tell RetIQ that you (or your spouse) are already collecting Social Security and enter your current monthly benefit directly, rather than back-solving for the FRA amount. The new toggle sits on the SS card — check it, enter what you actually receive each month, and the engine uses that figure as your starting SS income with COLA accruing forward from your current age. Independent toggle for primary and spouse, so households where only one person has claimed are handled cleanly.
For households with a non-working or low-earning spouse, RetIQ still needs an approximate PIA to compute the spousal floor and survivor benefits. The new ssReverseAdjustPIA helper recovers that PIA by reversing the SSA early/late adjustment formula (POMS RS 00615.301 and RS 00615.304) using the age you started collecting. The recovered figure is in current dollars rather than original-FRA dollars — past COLAs are baked in — which means survivor and spousal calculations are slightly approximate for households that have been collecting for many years. The error is small in practice; precision back-out of historical COLAs is a future enhancement.
Help text for the existing FRA-amount field also clarifies that the entered value is the gross benefit, before any Medicare Part B premium deduction. RetIQ models Medicare costs separately on the expense side, so the gross figure (Box 5 of your SSA-1099) is what the engine needs.
Behavior change for plans with COLA = 0%. Six SS COLA sites in the engine were silently coercing an explicit 0% COLA to 2% (because 0 || 2 === 2 in JavaScript). All six now use ?? 2, so 0% means 0%. If you had a saved plan with SS COLA set to 0, your projection's Social Security income line will now actually stay flat instead of growing 2%/year. The fix is correct; the prior behavior was a latent bug.
27 new tests in test-already-collecting-ss.js covering reverse-PIA round-trips, primary already-collecting integration, spousal floor with recovered PIA, spouse-only-collecting cases, both-spouses-collecting cases, and a backwards-compatibility check against the existing spousal-SS suite. 5 additional unit tests in test-validation.js for the new helper. All four suites green: test-validation.js, test-spousal-ss.js, test-self-employed.js, test-already-collecting-ss.js.
Authority: 42 U.S.C. §402(q) (early-claiming reduction); 42 U.S.C. §402(w) (delayed retirement credits); SSA POMS RS 00615.301, RS 00615.304. Medicare gross/net basis: 42 U.S.C. §1395s; SSA POMS GN 02410.180; IRS Pub. 915 (gross benefit on SSA-1099 Box 5).
Two bug fixes: phantom Other Income and stale brokerage dividend tracking
Two engine fixes reported by a customer.
1. Phantom $6k Other Income. A legacy additionalIncome field in the seed plan default was carrying forward into newly-created plans even after the income-streams replacement shipped in v4.x. The migration that was supposed to convert the legacy field into a real, editable income stream was gated on incomeStreams === undefined — so plans that already had an empty incomeStreams: [] array (the v4.x default) skipped the migration entirely, and the engine's backward-compat block kept injecting a phantom $6k/yr ordinary-income stream every projection year. Affected anyone whose plan had been initialized between v4.x and v6.15.3 with the seed default. Fix: decouple the income-streams init from the legacy migration so both run independently, zero the legacy field idempotently after migration, and zero the seed default. Existing plans self-heal on app load.
2. Brokerage dividend yield computed off the static input balance. The per-account dividend yield loop was reading acct.balance — the year-0 input — on every projection year. Result: dividend income stayed flat forever even as the brokerage compounded or was drawn down. Customer described it precisely: “even though my brokerage account grows in the projection, the income included in Other Income is flat.” Fix: each brokerage account holds a constant share of the pooled balance (share = acct.balance / totalStartingBrokerage, computed once); per-year dividend = share × taxableInv × yield ÷ 100. Pool growth and pool withdrawals now propagate to dividend income correctly. Single-account plans collapse to share = 1 and behave intuitively. Empty-pool guard prevents division-by-zero when no brokerage accounts are present.
3 new validation tests in test-validation.js lock the year-over-year behavior: untouched brokerage grows dividend income, drawn-down brokerage shrinks it, no brokerage accounts produces zero with no NaN. 7 new tests in test-ui-paths.js cover the migration stuck-state, both-populated-non-conflict, and idempotency cases.
Validation completeness + QBI threshold consolidation
Three small post-SE-module cleanups:
- Spousal SS tests now visible on the validation page.
test-spousal-ss.js now writes JSON output mirroring test-self-employed.js, and run-all-tests.js merges all three suite outputs (validation, spousal-SS, self-employed) into validation-results.json. The 30 spousal SS tests previously ran but didn’t surface on validation.html; they do now. The merge logic was also upgraded to concatenate tests when two suites share a category name (instead of overwriting), recovering 14 tests from the validation suite that the v6.14.1 SE merge had silently overwritten in the “Integration” bucket. - Solo 401(k) test categories now have proper formula blocks on validation.html.
validation-metadata.json gained categoryFormulas entries for Solo 401k and Solo 401k Integration with full IRC §401(c) / §402(g) / §415(c) / §404(a)(8) authority citations and Treas. Reg. §1.199A-3(b)(1)(vi) + Notice 2024-2 references for the QBI integration tests. - QBI thresholds consolidated into REGS layer. Pre-OBBBA values in
07-regulatory.js REGS were updated to post-OBBBA per Rev. Proc. 2025-32 §4.26 ($553,500 MFJ end, $276,750 Single end — the OBBBA §70105 $150K / $75K phase-in extension). calcQBIDeduction in 08-calculations.js now reads thresholds from REGS-sourced constants instead of shadowing them with inline duplicates. Engine math is byte-identical — this is constant-source consolidation, not a behavior change. All 24 QBI tests verified unchanged pre/post.
Total tests in merged validation-results.json: 616 (up from 586 at v6.15.2). Engine math unchanged.
Projection Table — Conversion Tax column
New Conv Tax column in the year-by-year Projection Table: federal income tax owed specifically on Roth conversions for that year (a subset of Federal Tax). Surfaced separately so you can see exactly what each conversion year costs in tax. Engine math is unchanged — conversion tax is computed as the delta between actual ordinary income tax with the conversion and the no-conversion baseline, and is paid from your designated tax source (cash, brokerage, or IRA withholding) outside the regular retirement-year tax cascade.
This closes a "where did my money go" gap reported by users running Roth conversions: conversion tax was paid from the designated source separately from the cascade, producing brokerage drain that didn't match the W/D column. The new column makes the conversion-year tax explicit. Auto-hides for users who don't run conversions (all-zero filter, same pattern as the existing TAD / TAD Tax columns).
The same field also added to the chart-overlay categories (so users can include Conversion Tax in the multi-line chart above the table) and to the CSV export. Engine field conversionTax has been in year output since v6.0; this surfaces it in the most-used view.
Dashboard "This Year's Plan" cleanup
Two clarity fixes on the dashboard "This Year's Plan" card, both in response to user feedback:
- Total Tax line previously appeared at the bottom of the "Taxes & Medicare" section but excluded Medicare Premium and IRMAA Surcharge (which are healthcare costs in the engine, not tax). The section now renders two subtotals: Total Tax (federal + state + FICA + SE tax) and Total Medicare (premium + IRMAA). Each subtotal honestly sums the rows above it.
- Net Annual Cash Flow bar on the Retirement tab previously counted portfolio withdrawals as inflows, which produced false-positive surplus readings for retirees drawing meaningfully from accounts. The bar now reflects external cash flow only (SS + pension + dividends + other income, less all outflows). When portfolio is being drawn, a separate Portfolio Withdrawal line surfaces the drain amount and the bar is amber to indicate "gap funded from accounts." This makes the dashboard honest about what portion of retirement spending is being funded by external income versus by drawing down savings.
Engine math is unchanged. The Working-tab cash flow definition is also unchanged.
Solo 401(k) Contributions for Self-Employed Users
Self-employed users can now model Solo 401(k) contributions: employee elective deferral (Traditional or Roth) and employer profit-share. The engine handles all the cross-cutting tax interactions: §402(g) aggregation across W-2 and Solo deferrals; §415(c) annual addition cap on combined employee + employer; §404(a)(8) 20% sole-prop employer limit on (net SE − half-SE-tax); age-based catch-up including the SECURE 2.0 §109 enhanced catch-up for ages 60–63; AGI reduction for traditional contributions; QBI reduction for traditional employee, traditional employer, and Roth employer per Treasury Regulation §1.199A-3(b)(1)(vi) and IRS Notice 2024-2 Q&A L9.
The Self-Employed card on the Income tab already had Solo 401(k) input controls (added in v6.0 as scaffolding); v6.15 wires the engine math behind them. Help text now flags the QBI interaction with Roth employer contributions.
Engine simplification: the §402(g) capacity calculation uses your W-2 401(k) deferral target from Contribution Routing. If your annual savings pool is insufficient to fund the full W-2 target, the engine slightly understates available Solo deferral capacity by the savings-pool shortfall. Rare for typical SE users; on the roadmap for a future precision update.
Roadmap: SEP-IRA, SIMPLE-IRA, defined benefit plans, after-tax / Mega Backdoor Roth contributions, S-corp employer contribution math (25% of W-2 wages), and per-state §199A conformity are Phase 2 enhancements. SECURE 2.0 §603 mandatory Roth catch-up will ship with S-corp support since it requires FICA-wage tracking that sole prop / SMLLC / partnership entities lack.
26 new validation tests in test-self-employed.js (83 total, was 57). 503 + 30 main suites unchanged.
SE module cleanup — cascade target, QBI baseline symmetry, validation page
Three small fixes to the self-employment module landing as a patch ahead of v6.15 Solo 401(k):
- The v6.8 tax-payment cascade target now includes SE tax for architectural correctness. Currently a no-op since SE tax only fires in working years and the cascade only runs in retirement, but the fix prevents a latent bug if a future feature allows post-retirement SE income.
- The per-baseline §199A QBI computation now applies the tax-loss-harvesting ordinary offset to all three projection scenarios uniformly (no-conversion, conversion-only, actual), eliminating a small asymmetry in conversion delta math for self-employed users actively running TLH near the SSTB threshold.
- The public validation page (/validation.html) now includes the 57 self-employment test results that previously ran in a separate file and weren’t surfaced.
New run-all-tests.js wrapper script runs all three test files (test-validation.js, test-spousal-ss.js, test-self-employed.js) and merges results into validation-results.json. Standalone test runners continue to work for development. build-validation.js now produces validation.html with 560 tests across 65 categories (was 503 / 58).
Section 199A QBI Deduction
Self-employed users now receive the §199A Qualified Business Income deduction automatically. The engine computes 20% × (net SE earnings − half-SE-tax deduction) per business, applies the SSTB phaseout for users above the income threshold, caps the combined deduction at 20% × (taxable income − net capital gain) at the household level, and applies the new $400 minimum deduction added by the One Big Beautiful Bill Act for taxpayers with at least $1,000 of QBI.
2026 thresholds per IRS Rev. Proc. 2025-32 §4.26: $403,500 MFJ ($553,500 phase-in completion) and $201,750 single ($276,750 completion). The OBBBA extended the phase-in range from $100,000 to $150,000 MFJ and from $50,000 to $75,000 single.
The deduction is computed per scenario across all three projection baselines (no-conversion, conversion-only, conversion-plus-TAD) so Roth Conversion Optimizer recommendations correctly capture conversion-induced QBI loss when conversion pushes a user across the SSTB threshold. The Tax-Aware Drawdown smartFill bracket-room calculation also accounts for QBI, ensuring SE users get accurate target-bracket recommendations.
State-level §199A conformity is on the v6.x backlog (most states conform but California, New Jersey, and Pennsylvania do not). W-2 wage / UBIA modeling for SE businesses with employees, QBI loss carryforward, and aggregation elections are also Phase 2 enhancements. Solo 401(k) contributions further reducing QBI per Treas. Reg. §1.199A-3 will land alongside the Solo 401(k) contribution math in v6.15. 13 new validation tests in test-self-employed.js (56 total, was 41); 503 + 30 main suite tests unchanged.
Self-Employment Tax
Net Self-Employment Earnings now flow through the engine. Positive earnings produce SE tax (IRC §1401: 12.4% OASDI on net × 0.9235 sharing the SS wage base with W-2 wages per §1402(b)(2), plus 2.9% Medicare with no cap). The half-of-SE-tax deduction (IRC §164(f)) reduces AGI. Negative net earnings — business losses — reduce AGI for the year with no SE tax owed.
SE tax is included in the total annual tax bill, and the v6.8 tax-payment cascade automatically draws it from the portfolio in retirement years. Three new fields surface in the projection year output: seTax, seNetEarnings, and seHalfDeduction. SE income propagates correctly through MAGI, IRMAA, ACA subsidies, SS taxation, and state tax (which uses the same federal AGI starting point most states piggyback on).
Solo 401(k) contributions and the QBI deduction (IRC §199A) are still on the roadmap (v6.14 and v6.15 respectively); the Self-Employed card on the Income tab indicates which features remain pending. 20 new validation tests in test-self-employed.js (41 total, was 21).
Monte Carlo per-year percentile envelopes & Roth/TAD recommendation baseline
Monte Carlo per-year percentile envelopes. The p10/median/p90 lines on the Monte Carlo chart are now true per-year percentile envelopes across all simulations, not three sample paths chosen by terminal net worth. Previously, the median path could appear above the p90 path at intermediate ages because the path that ended highest may have started below the median path. With per-year envelopes, p10 ≤ median ≤ p90 is guaranteed at every age. Final-year values are unchanged.
Roth vs TAD legacy recommendation now considers all four strategies. The Longevity Crossover chart already plotted No Strategy alongside Roth Only, TAD Only, and Roth + TAD, but the recommendation text only compared Roth vs TAD — so it could claim “Roth wins at all ages” even when No Strategy was higher than both. Now the recommendation identifies the winning strategy across all four at the youngest and oldest age in the range, and reports any crossover. This catches cases where No Strategy beats Roth or TAD because the conversion/drawdown tax cost outweighs the heir-bracket discount on pre-tax inheritance.
6 new validation tests for the Monte Carlo envelopes (locking p10 ≤ median ≤ p90 at every age plus 5 supporting invariants). Total validation tests: 503. Spousal-SS suite unchanged at 30/30.
Social Security display precision
FRA is now displayed in human-readable form (e.g., “66 yrs 4 mos” instead of “66.3”), eliminating the false-equivalence problem where a fractional FRA (66.333… for birth year 1956) and a user-entered claim age of 66.3 displayed identically. Sub-1% claim-age reductions now show with one decimal place (“reduced 0.3%”) instead of being rounded to the contradictory “reduced 0%.”
The loud red “Claiming before FRA permanently reduces benefit by X%” warning is suppressed when the reduction is below 1% — the inline label is sufficient for tiny reductions. SS Claim Age help text now shows the user’s actual FRA in human-readable form and clarifies that the input is interpreted as decimal years (66.5 = 66 yrs 6 mos, not 66 yrs 5 mos).
No engine or math changes — projections are identical to v6.10. All 497/497 validation and 30/30 spousal-SS tests remain green.
Inherited Roth IRA Back-Load Option
Inherited Roth IRA accounts now support an optional back-load distribution timing: zero distributions during years 1–9 of the 10-year window, full balance in year 10. This pattern is fully legal under IRS T.D. 10001 (July 19, 2024) — inherited Roth IRAs have no annual RMD requirement during the 10-year window, only the year-10 deadline. At positive return rates, back-loading captures more tax-free growth than the default even-spread. Lifetime tax is unchanged (Roth distributions are tax-free regardless of timing).
Restricted to inherited Roth accounts; inherited traditional IRAs continue to use even-spread because the “at least as rapidly” rule may apply when the decedent died on or after their RBD — a future enhancement could add a decedent-RBD toggle to unlock back-load on traditional inherited accounts.
The new toggle appears below the regime dropdown when an inherited Roth account is on the post-2019 regime (it’s hidden for pre-2020 stretch and EDB regimes, which use Single Life Expectancy math). 7 new validation tests lock the behavior. Total validation tests: 497.
Brokerage Dividend Yield
New optional field on brokerage accounts: Dividend Yield (% per year) and tax type (qualified or ordinary). Splits the existing return rate into a dividend portion (recognized as income annually) and an appreciation portion (unrealized until withdrawal). Qualified dividends taxed at LTCG preferential rates per IRC §1(h)(11); ordinary dividends taxed at marginal rates. Reinvested dividends step up cost basis dollar-for-dollar per IRS Pub 550. Total return rate is unchanged — this is purely a tax/accounting split. Useful when a brokerage account holds high-yield holdings whose dividend income materially affects MAGI, IRMAA, NIIT, or ACA eligibility.
Dividend income flows through the same tax pipeline that already handles qualified-dividend Income Streams: SS taxation (IRC §86), LTCG bracket stacking (IRC §1(h)(11)), NIIT (IRC §1411), MAGI, IRMAA, ACA, and state tax. Existing accounts with no dividend yield set are fully backward-compatible (the field defaults to 0 and no dividend income is generated).
10 new validation tests (6 direct feature tests, 4 regression tests locking the existing-correct qualified-dividend pipeline) lock the new behavior. Total validation tests: 490.
Tax Payment from Portfolio
The engine now correctly draws from your portfolio to pay retirement-year federal income tax, state income tax, capital gains tax, and Net Investment Income Tax. Previously these taxes were computed and shown in the projection but did not actually drain account balances, leaving projections optimistic. Conversion tax (if you have Roth conversions enabled) continues to be paid from the source you've designated on the Roth Conversion tab — that part hasn't changed.
Mechanically, the engine wraps the gap-fill withdrawal cascade in a fixed-point iteration. Each pass computes the gap, draws from your accounts in your configured withdrawal order, computes the resulting tax bill, and feeds that tax bill back into the next pass's gap. The iteration converges in 2–4 passes per retirement year for typical scenarios. Years where iteration converges slowly (usually right at bracket transitions, IRMAA tier boundaries, or RMD-onset years) get a small ⓘ indicator next to the Fed Tax column in the Projection table — see the manual for details.
What you'll notice: The same plan inputs will produce projections noticeably more conservative than v6.7.5. Terminal net worth comes in lower, withdrawal totals reflect the actual tax outflow, Monte Carlo success rates are a few points lower for tax-heavy plans. Your plan didn't get worse; the model got more accurate.
The Roth Conversion Optimizer's recommendations may shift more than other surfaces. Pre-v6.8, the no-conversion baseline benefited disproportionately from the bug because its larger future RMD-era tax bill went unmodeled. Under v6.8, with that tax bill correctly drained from the portfolio, conversions look more attractive than they did before — sometimes meaningfully so. If the Optimizer previously recommended against conversions for your plan, re-run it under v6.8. The new math may give a different answer; for some plans, the direction of the recommendation reverses.
v6.8 also implements the IRC §408A(d)(3)(F) 5-year conversion clock. Each Roth conversion now carries its own 5-year window for purposes of the 10% early-withdrawal penalty on conversion principal. If you withdraw converted principal from your Roth before age 59½ AND within 5 years of the conversion year, the engine applies the 10% penalty. This matters most for users planning a Roth conversion ladder — converting Traditional IRA to Roth in your 50s and accessing the converted principal during the 5-year window. The 5-Year Rule Tracker on the Roth Conversion tab shows which conversions have matured. Users with substantial direct Roth contributions and aggressive early withdrawal plans may see slightly overstated penalties — full §408A(d)(4) ordering is on the v6.9 backlog (see manual for details).
Recommendation if you've saved a plan in v6.7.5 or earlier: open it under v6.8 and re-run your Strategy Report and Roth Optimizer to get fresh recommendations against the corrected baseline. The projections will recompute automatically on open; the strategy comparisons regenerate when you open those tabs.
11 validation tests in a "Tax Payment from Portfolio" category and 7 tests in a "Roth Conversion 5-Year Rule" category lock the new behavior. Total test count: 696 across all suites (validation 480, spousal-ss 30, self-employed 21, ui-paths 48, joint-life 117).
Verification. v6.8's engine math was audited across 8 categories against external authorities (IRS, SSA, CMS, HHS, statutory law, and mathematical theory). All 8 audit items pass. The verification trail is in the repo at audit/v6.8/phase1/ — readable per-item findings with cited authorities, test cases, and mathematical reasoning for the iteration math.
Roth Optimizer ranks under blended returns + divergence warning
When users set per-account return rates that diverge across pre-tax and Roth (e.g., bond-heavy pre-tax at 5%, stock-heavy Roth at 9%), the Roth Optimizer’s candidate projections compounded the spread into a fictitious advantage for conversion that had nothing to do with taxes — converted dollars appeared to jump from a slow-growth bucket to a fast-growth bucket, and the “Maximize Net Worth” mode amplified the bias the most. Reported on Bogleheads.
The optimizer now ranks every candidate strategy using a blended return rate (the Nominal Investment Return from Assumptions) for all non-cash accounts. Cash accounts keep their actual rate because cash interest is taxed as ordinary income each year and changing its rate would distort MAGI/IRMAA scoring rather than just bucket growth. Important: only the optimizer’s candidate ranking is blended. Your main projection, Strategy Report, Monte Carlo, and applied optimizer results all continue to use your actual per-account returns — only the comparison inputs are normalized.
Independently, when pre-tax and Roth balance-weighted return rates differ by 2 percentage points or more (and both buckets hold $10,000 or more), the optimizer card now surfaces a warning explaining the bias risk for the main projection and how to remove it (set the same return rate on all accounts in the Accounts tab, or leave them blank to inherit the Nominal Investment Return). A second disclosure note above the strategies table explains that ranking uses blended returns and applied results use real returns.
Validation suite gained an Optimizer Blended Returns category covering the helper’s normalization, idempotency, immutability, the divergence threshold logic (boundary at exactly 2.0pp inclusive, balance gate at $10,000, missing-bucket handling, balance-weighted averaging across multiple accounts), and an end-to-end integration test confirming that blending materially changes projected end-state Roth balances.
Cash/HYS account stranded-balance bug fix
The default plan and two of three demo families seeded their Cash / HYS account with a legacy schema (type:'cash') that the projection engine’s bucket filters did not recognize. The balance appeared in the Inputs > Accounts “Total Portfolio” and the Dashboard “Current Net Worth” (which both summed all accounts blindly), but was silently excluded from the projection. Reported on Bogleheads.
The fix has four layers: a pure canonicalizeAccount helper in the engine module that rewrites the legacy schema to the canonical type:'taxable', subtype:'cash' form; a migration step in migrateParams that runs the helper on every load (idempotent — safe for plans already in canonical form); seed-data fixes in the default plan and demo families; and bucket-aware totals in the Inputs and Dashboard tabs that filter to recognized account types and surface a visible warning if any unrecognized account is detected. Existing saved plans are migrated automatically on next load.
Defensive: the new total-hardening guards against future schema drift — if a new account type is introduced and an old build evaluates a plan saved under the new schema, the warning fires instead of silently undercounting.
Validation suite gained a new Account Schema Canonicalization category covering the helper’s normalization, idempotency, pass-through for canonical types, and an end-to-end integration test confirming a legacy cash account placed via the helper lands in the engine’s cash bucket.
Break-Even Tax Rate display clarified
The Conversion Impact Analysis card’s Break-Even Tax Rate (BETR) display previously read “Convert if future rate > X%” with a tooltip describing it as the “future marginal tax rate”. That framing was misleading: BETR is not compared to your current marginal rate — it’s the average effective rate the no-conversion pretax pool would need at withdrawal for conversion to break even, measured against the projection’s implicit effective rate.
The distinction matters because for retirees with modest pretax balances, the projection’s effective rate on the pretax pool can be much lower than their marginal rate — standard deductions, senior additions, and the OBBB senior deduction shelter most of the pool from tax. A user reading “BETR 1.2%, my future marginal will be at least 12%, so convert” was getting the wrong answer in cases where the projection’s Final NW Δ was already showing the conversion losing money.
The card’s sub-label now reads Future effective rate threshold, and the tooltip explicitly disclaims the marginal-rate reading. The iOS manual’s BETR explanation got the same correction. The math is unchanged — only the labels and explanations are clearer. Final NW Δ remains the bottom-line answer when these metrics seem to disagree.
Documentation pass: v6.4–v6.7 alignment
Documentation update bringing the user manual, feature list, and LLM crawler files current with changes shipped over the past several batches.
Manual. Added a Phased Brackets paragraph under Roth Conversion Strategies covering the v6.7 multi-phase feature. Added an escrow-exclusion clarification to the Liabilities tab Monthly Payment description (matching the v6.4 in-app help text). Replaced specific pre-v6.6 dollar amounts in the Relocation Scenario example with descriptive language — the actual savings now depend on your move age, remaining retirement years, and home equity, and the engine computes them precisely from your inputs.
Features. Added Phased Brackets to the Roth Conversion Strategies card. Updated the projection chart cap from “up to 4” to “up to 6” matching the v6.4 bump.
LLM crawler files. Updated test counts in llms.txt and llms-full.txt to 417 (matching the validation page). Added Phased Brackets to the strategy list in llms-full.txt so AI assistants give accurate answers about the feature.
No engine math changes. All 633 tests passing.
Multi-phase hygiene + stale banner removal
Three small bug fixes from the v6.7 multi-phase Roth Conversion feature crossing module boundaries, plus removal of the long-stale “What's New in v5.0” dashboard banner.
Strategy Report alternatives now correctly test single-target. The dashboard's Strategy Report tests alternative strategies (e.g., “Smart Fill Roth 22%”) against your current plan. Previously, when you had Phased Brackets configured, those alternatives were inadvertently using your phased setup with overridden start/end ages — a mislabeled comparison. Fixed: alternatives now explicitly clear phases for an honest single-target comparison.
Roth Optimizer apply now clears phases. When you apply an optimizer result, your prior Phased Brackets setup is explicitly cleared (it was previously preserved invisibly, which could silently reactivate if you switched strategy back to Fill Bracket later).
Plan summary reflects phases. The Strategy Check-In card and AI Guide context now show “Roth Smart Fill (Phased)” or similar when phases are active, instead of falling back to the legacy single-target percentage.
“What's New in v5.0” banner removed. The dashboard banner introduced with v5.0 was hardcoded and hadn't been updated through nine subsequent version bumps. The full changelog page is the canonical source for what's new — the banner pattern was creating more confusion than it cleared up.
AI Guide reference updated. The BYOK AI feature reference now describes Phased Brackets so Claude/GPT/Gemini answers about the feature are accurate.
No engine math changes. All 633 tests passing.
Multi-phase Roth Conversion brackets
The Roth Conversion tab's Fill Tax Bracket and Smart Fill (IRMAA-Aware) strategies now support phased bracket targets — define different target brackets for different age ranges within your conversion window. Useful when you plan to move to a different state mid-conversion (the canonical example: California 12% bracket while in CA, then 24% in Washington with no state tax, optionally back to 12% if you return to CA later).
Toggle “Use Phased Brackets” on the Roth Conversion tab when Fill Bracket or Smart Fill is your strategy. Add as many phases as you need, each with its own age range and target bracket. First-match-wins if phases overlap; years not covered by any phase produce no conversion. The outer Start Age / End Age remain the master gate for the conversion window — phases subdivide within it.
Existing plans are unchanged. The engine falls back to your single targetBracket setting when no phases are defined, so saved plans continue to behave identically. The Roth Conversion Optimizer continues to test single-target candidate strategies.
6 new tests in a new Roth Multi-Phase category lock down the regression case (empty phases identical to absent phases), single-phase equivalence, two-phase ordering, gap-year zero-conversion, phase boundary inclusivity, and outer-window gating. Total now 417 tests in test-validation.js, 633 across all suites.
Relocation Scenario moveAge honored by engine
The Relocation Scenario now correctly applies the origin state tax rate before the move and the target state tax rate from the move year onward. Previously the scenario overwrote stateCode at the top of the projection, so the target state's rate was applied to every year — including pre-move years — producing inflated “tax savings” numbers when comparing against the baseline. The engine now resolves an effectiveStateCode per simulation year using the moveAge cutover, and both the pre-retirement and post-retirement state-tax call sites consume that resolved code. Behavioral change: pre-existing Relocation scenarios will show smaller state-tax-savings deltas than before — the new numbers are accurate, not a regression. Seven new tests added in a dedicated Relocation Scenario validation category covering no-relocation regression, pre-move year, post-move year, exact cutover boundary, move at currentAge, move beyond endAge, and pre-retirement move.
Dangling label fix
The Projection tab's category selector instruction now reads “Select up to 6 categories” — the cap was raised to 6 in v6.5 but the user-facing label still said 4. Same fix applied to the corresponding sentence in the manual. Cosmetic only; no behavior change.
UI polish — Effective Rate, more chart categories, larger legend text
Three small additions from user feedback. The Conversion Impact Analysis card on the Roth Conversion tab now shows an Effective Rate on Conversions stat alongside the existing Tax on Conversions — the blended average rate (total conversion tax ÷ total amount converted across all years). Compare it to the Marginal Rate Curve to see how much of the rate ladder a given strategy climbed.
The Projection tab chart can now overlay up to 6 categories simultaneously (previously 4). Useful for seeing how multiple income, expense, and balance series interact in the same view.
Chart legend text bumped from 10px to 12px across the app — Monte Carlo, Projection, Roth Conversion, Scenarios, and every other chart. More readable on small screens and at typical viewing distances.
Mortgage amortization rebuilt — monthly accrual
Mortgage and loan amortization is now computed monthly: each month’s interest accrues on the declining balance from the prior month, matching how real fixed-rate loans amortize. Previously the engine used a single annual interest accrual (balance × annualRate once per year), which slightly overstated early-year interest and pushed payoff out by a few months on most loans. The same calculation now drives both the on-card payoff display in the Liabilities tab and the Debt Payments series in the Projection chart, via a shared amortizeYear() helper in src/engine/09-engine.js.
Existing plans with mortgages will recompute slightly different numbers — typically lower lifetime interest and an earlier payoff age. The shift is small (months, not years) but visible on next open. Plans without mortgages or loans are unaffected.
The Monthly Payment field on the Liabilities tab now has a help line clarifying that it expects principal & interest only — exclude property tax, insurance, and other escrow items. Many lender statements lump these together, and entering the full PITI value would inflate apparent payments and distort the payoff timeline.
11 new tests in a new Debt Amortization category lock the helper against textbook amortization values: year-1 interest/principal/balance for a 30-year fixed, 30-year payoff timing, zero-rate edge case, zero-balance edge case, underwater-payment edge case, and engine integration verifying the projection wires through the same helper. Total now 404 tests in test-validation.js, 620 across all suites.
UI logic fixes — Earnings Test trigger and routing breakdown
Two refinements from user feedback. (1) The Social Security Earnings Test advisory in the SS tab now only appears when the user will actually have earned income overlapping the claim-to-FRA window — claim age strictly before retirement age. Previously the warning fired for anyone claiming pre-FRA, even when they would already be retired and have no wages, which was misleading. The engine itself was always correct; only the advisory text was over-eager. Same fix applied to the spouse advisory. (2) The Household Savings Summary in the Accounts tab now breaks the routed amount down by Traditional vs Roth, so the summary reflects the user’s actual Type selection on each contribution row instead of just showing a combined “401(k) + IRA” total.
Label & string corrections
Five small fixes from user feedback. (1) The Accounts tab now reads contribution limits from the regulatory module instead of a stale hardcoded label, so the IRS Notice 2025-67 figures ($24,500 401(k), $7,500 IRA) match what the engine actually applies. (2) The “Break-even vs 62” column in the SS Claiming table now has a tooltip explaining what the age means. (3) “TAD” is now spelled out as “Tax-Aware Drawdown” on the Roth Conversion tab where the acronym first surfaces. (4) The QCD eligibility age now renders as 70½ rather than “701/2”. (5) The Projection tab chart category labeled “Liabilities” is renamed to “Debt Payments” — the value is annual debt service, not outstanding balance, and the old label was misleading.
Relocation Scenario Fix
Relocation Scenario fix. Clicking “Compare Relocation” on the Scenarios tab threw a TypeError and the scenario did not render. The scenario dispatch guard in src/27-ui-scenarios.js excluded the bear and hcInflation string scenarios but not relocation. Replaced the deny-list with a positive typeof === 'number' check. Reported by an app user.
OBBB SALT Cap Alignment & v6 Polish
OBBB SALT Cap (Year-Aware with MAGI Phase-Down)
The SALT deduction cap is no longer hardcoded at $10K. A new saltCapFor(year, magi) helper in src/engine/07-regulatory.js implements OBBB Act P.L. 119-21 amending IRC §164(b)(6): $40,000 base cap for 2025-2029 with 1% annual growth, MAGI phase-down reducing the cap by 30% of excess above $500,000 (threshold also grows 1%/yr), floor of $10,000, and reversion to $10,000 TCJA baseline in 2030. Applied at three engine call sites: main deduction flow, Tax-Aware Drawdown scenario, and Smart Fill Roth conversion bracket-room calculation. The Smart Fill site had been silently applying the old $10K cap — a latent bug that conservatively under-sized Roth conversions for users in high-tax states. Now fixed.
Dual-Owner RMD Workflows
Two new Tax Strategy workflow cards building on v6.0’s per-owner RMD tracking. Coordinate Dual-Owner RMDs covers account ownership assignment, identifying the earlier RMD start year, and aligning Roth conversion windows to the earlier-start spouse. Apply the Joint Life RMD Election covers the four eligibility conditions (spouse enabled, age entered, gap strictly greater than 10 years, sole beneficiary), enabling the election, and stress-testing survivor scenarios. Existing Find and Fill Your Tax Valley and Optimize Your Roth Conversion Strategy workflows gained dual-owner awareness sentences pointing users to the Staged RMD timeline insight in the Strategy Report Card.
Guide+ Refresh
Feature-knowledge entries updated throughout v6.0 work: FICA bullet in Tax Engine, new RMDs section (per-owner tracking, Staged RMD timeline, Joint Life election, spousal rollover), W-2 Detail opt-in, Self-Employed Income Model foundation. Per-owner and Joint Life RMD router templates added for the Guide. Counts refreshed: 14 workflows (was 8), 18 templates (was 13), 423 validation tests. Version banner and Anthropic model string updated.
Rev. Proc. 2025-32 Citation Refresh
Federal Tax bracket citations updated from Rev. Proc. 2024-40 §2.01 (2025 tax year) to Rev. Proc. 2025-32 §4.01 (2026 tax year) in validation-metadata.json and the VALIDATION_DATA test entries. IRS source URL updated from rp-24-40.pdf to rp-25-32.pdf. Top-of-page source grid card year label now reads “(2026).” Projection footer model-notes corrected from “2025 tax brackets” to “2026 tax brackets (OBBB Act; IRS Rev. Proc. 2025-32).” Standard Deduction citations intentionally retained at Rev. Proc. 2024-40 pending verification of the corresponding section in the new procedure.
Projection Table Readability
The “Itemizing?” and “Bunch Year?” columns now render as Yes/No instead of 1/0 in the HTML data table. Totals row shows an em-dash for boolean columns instead of “Total.” Both columns also added to the CSV export as numeric 1/0 for pandas/Excel analysis. The Yes/No rendering became especially useful after the SALT cap update, which makes the engine legitimately flip between itemized (2025-2029) and standard (2030+) for high-SALT users.
Documentation Updates
manual.html and features.html SALT-related prose updated to reflect OBBB cap mechanics. src/24-ui-inputs.js SALT field help text and the Itemized Deduction Comparison blurb updated. src/29c-ai-guide.js Itemized vs Standard Deduction feature knowledge updated.
Validation
6 new tests in a new SALT Cap (OBBB) category covering the 2025 base cap ($40,000), 2026 growth ($40,400), 2030 reversion, phase-down at MAGI $550,000 (cap $25,000), phase-down floor at MAGI $700,000 ($10,000), and threshold growth verification. Total now 423 automated tests, 44 categories.
Per-Owner RMD Tracking & Self-Employed Income Foundation
Engine
- Per-owner pre-tax RMD tracking. Each spouse's 401(k) and IRA now computes its RMDs against that spouse's own age instead of pooling all pre-tax balances at the primary's RMD age. If your spouse reaches age 73 before you, their RMDs now fire at the right year on the dashboard and in the projection. To use: open the Accounts tab in Full Control mode, and you'll see a new Owner dropdown next to each account. Mark spouse-owned accounts as “Spouse.” Single-owner plans are unaffected. Authority: IRC §401(a)(9), IRS Pub 590-B Ch. 1, SECURE 2.0 Act §107.
- Spousal rollover on death. When an account owner dies, their pre-tax balance merges into the surviving spouse's IRA in the year of death, and RMDs from that year forward use the survivor's own age. This was previously pooled-and-primary; it's now correct per-owner.
- Dashboard RMD card shows two ages and a per-owner split when both spouses have pre-tax accounts. Strategy Report includes a new “Staged RMD timeline” insight banner on dual-owner plans explaining why Roth conversions before the earlier spouse's RMD age carry the most value.
- 13 new dual-owner RMD tests added to the engine validation suite.
Engine Foundation
- Income model extended with optional W-2 detail: gross wages, Section 125 cafeteria-plan deductions, pre-tax HSA, traditional 401(k), and Roth 401(k) — matching how Boxes 1, 3, and 5 actually work on a real W-2. The legacy single-scalar income field still works unchanged; the breakdown is opt-in.
- FICA calculation engine added. Computes OASDI 6.2% to the Social Security wage base, Medicare 1.45%, and Additional Medicare 0.9% over threshold — per person, per year, with correct wage-base sharing when W-2 and self-employed income coexist.
- Self-employed income data model added: entity type (sole proprietor, partnership, S-corp), specified service trade or business flag, and net self-employment earnings. Engine-level foundation for Solo 401(k), QBI deduction, and self-employment tax calculations — full user-facing features to follow in upcoming releases.
- Phase-based income now supports per-phase W-2 breakdown and self-employed details, so the same person can model a career transition from W-2 employment to consulting with correct tax treatment in each phase.
Joint Life RMDs for spouses more than 10 years younger
Feature
When a spouse is more than 10 years younger than the IRA owner and is the sole beneficiary of the owner’s pre-tax accounts, the IRS allows RMDs to be calculated using the Joint Life and Last Survivor Expectancy table (IRS Pub 590-B Table II) instead of the Uniform Lifetime table (Table III). The Joint Life divisors are larger, so the RMD is smaller — meaningfully so at wider age gaps. At a 24-year gap, the RMD drops roughly 31%. RetIQ previously used Uniform Lifetime in all cases, which overstated RMDs for couples with this age structure.
How to turn it on
A checkbox labeled “Spouse is sole beneficiary of my pre-tax accounts” now appears in the RMD summary card on the Accounts tab, but only when the plan has a spouse enabled and the spouse is more than 10 years younger. The checkbox is unchecked by default — it has to be affirmatively set because the IRS rule requires that the spouse be the sole beneficiary of the IRA, which is a separate legal election from having a spouse in the plan. Most beneficiary designations name multiple beneficiaries (e.g., spouse as primary and children as contingent) and do not qualify.
Engine Mechanics
The engine re-evaluates eligibility every projection year. If the spouse dies during the plan, RMDs automatically revert to Uniform Lifetime the following year. If the owner dies first and the spouse rolls the IRA into their own, Joint Life no longer applies (the now-sole owner has no qualifying beneficiary under the rule). Eligibility requires all four conditions simultaneously: both spouses alive, flag set, spouse’s age tracked, and age gap strictly greater than 10. Exactly a 10-year gap does not qualify — the IRS rule is “more than 10 years younger.”
The table covers owner ages 72 through 120 and spouse ages 20 through (owner − 11), a total of 3,234 divisor cells transcribed from IRS Pub 590-B (2025 revision, Jan 21 2026 print). Cells where the age gap is 10 or less are intentionally omitted — those cases fall through to Uniform Lifetime.
Backward compatibility
Plans saved before v5.8.0 load without the new flag set, so RMDs match the pre-change behavior until the user explicitly opts in via the checkbox. No migration needed.
Testing
Validation: 374 tests passing, +13 from v5.7.16. The 13 new tests live in a new category (“RMD Joint Life”) and cover the IRS published worked example (owner 75 / spouse 64 = 25.3 divisor), the 11-year gap boundary, the 24-year user-reported scenario, the 10-year gap non-qualification, the flag-off disable, missing-cell Uniform Lifetime fallback, and the eligibility helper’s edge cases (null spouse age, spouse older than owner, flag unset). A separate developer-test file test-joint-life.js runs 117 thorough backward-compatibility sweeps across the full Uniform Lifetime age range — run locally; not part of the public validation report.
Source: IRS Publication 590-B, Appendix B, Table II — Joint and Last Survivor Life Expectancy. Treasury Regulation §1.401(a)(9)-9(d). IRC §401(a)(9).
Mobile header width cap
Fixes
- Fixed a page-level horizontal scroll on narrow phones where the overflow menu button ("...") ended up past the right edge and only appeared after scrolling sideways. The global header's left cluster now has a width cap that keeps everything on-screen.
Mobile/tablet header polish
Fixes
- Two follow-ups on the global dollar toggle. On landscape phones and tablets the long explainer is now hidden (was previously only hidden below 640px), and on narrow portrait phones the overflow menu button no longer floats awkwardly in the middle — it now stays pinned to the top row.
Mobile header layout
Fixes
- The dollar toggle now drops to its own line on mobile instead of pushing the rest of the header off-screen. Hid the toggle's help text on mobile — the two buttons are self-explanatory, and the full explanation is still there on desktop.
Activate path for installed PWA
Fixes
- Fixed a gap where users who installed the app, exhausted the 7-day trial, and landed on the marketing page had no visible way back in. The nav now shows an Open App link in every context, and the trial-ended message acknowledges that some users already have a license key to activate.
Global dollar toggle
Changes
- The Today's $ / Future $ toggle moved to the main header and is now always visible. Removed the per-page instances on Dashboard and Projection. No functional change — same toggle, one spot.
Plan Health & Big Levers toggle-aware
Fixes
- Plan Health verdict and every Big Lever now respond to the Today's $ / Future $ toggle. Completes the toggle rollout that began in v5.7.2. No engine or projection math changes.
Dollar Toggle: Dashboard Stragglers
Fixes
- Today's $ toggle now applies to three remaining Dashboard lifetime totals: inherited IRA distributions on the Strategies strip, lifetime Employer Match in the Details tab, and per-policy Total Premiums on the Life Insurance card.
- Life Insurance Net Benefit (death benefit minus total premiums) is now consistently today-$ on both sides when the toggle is on, since the death benefit is already a today-$ face-value param.
- Strategy Check-In card and Big Levers (computePlanHealth) remain in future-$ for time-consistency with stored snapshots; Big Levers is tracked for v5.7.8.
Dollar Toggle: Inputs Panel (Comparison Blocks)
Fixes
- Today's $ toggle now applies to the dense comparison displays in the Inputs panel: Roth conversion Conversion Impact Analysis (including Final NW Δ and strategy insight narrative), Roth Optimizer strategy table (baseline + all 8 strategy rows and the recommended-strategy summary), Legacy → Inherited IRA 10-year distribution block (ending balances, after-tax legacy estimate, heir-bracket model), and Tax-Aware Drawdown Impact Analysis.
- Optimizer scoring, ranking, and breakeven computations remain in future-$ (toggle-invariant); only displayed values shift.
- Ratio-based indicators (BETR, legacy-composition percentages) are unchanged because uniform deflation cancels in numerator and denominator.
Dollar Toggle: Inputs Panel (Simple Sections)
Fixes
- Today's $ toggle now applies to the Inputs panel informational cards: Debt amortization summaries, Pre-Medicare Healthcare gap-year total, Long-Term Care projections (annual cost, insurance, gap, total cost, net-of-insurance), ACA bridge coverage stats, Legacy goal progress and surplus, and Medicare lifetime cost / IRMAA totals.
- LTC info-box labels now show "today's $" or "future $" depending on toggle state so the labels match the displayed values.
- Roth conversion comparison, Optimizer schedule, and Inherited IRA blocks tracked for the next release.
Dollar Toggle: Survivor Center
Fixes
- Today's $ toggle now applies to the Survivor Planning Center: Longevity Check stats (Final NW, Lifetime Taxes, IRMAA, RMDs, Medicare), pressure-point dollar amounts, Three Futures comparison, Survivor Impact Analysis stats and narrative, and Strategy Report Card alternatives all honor the toggle.
- Adopt Plan previews (Spouse Passes / You Pass) and the Adopted Plan stats row also deflate when the toggle is on.
- Life insurance death-benefit amounts continue to show the face value you configured — those are already today-$ parameters, not projected values.
Dollar Toggle: PDF Export & Scenarios
Fixes
- Today's $ toggle now applies to the Strategy Report PDF export: Peak NW, End NW, Lifetime Taxes, Lifetime SS Income, IRMAA, Peak RMD, Roth conversion total, Tax-Aware Drawdown total, and Monte Carlo end-of-plan percentiles all deflate to today's purchasing power when the toggle is on.
- Today's $ toggle now applies to the Scenarios tab: Base Final, Alt Final, Difference, IRMAA delta, Bear Market peak-to-trough, Healthcare Inflation gap-year totals, and Relocation state-tax savings all honor the toggle.
- Chart axes continue to show nominal future-$ — charting behavior unchanged in this release.
Dollar Toggle Persistence & Broader Deflation
Fixes
- Today's $ / Future $ toggle now persists across page refresh.
- Plan verdict card (Dashboard) and Strategy Report now honor the dollar toggle — end-of-plan net worth, lifetime taxes, IRMAA, SS income, and legacy calculations all deflate to today's purchasing power when the toggle is on.
- Fixes applied to: verdict headline, Strategy Report alternative-strategy pills and deltas, relocation state-tax-savings estimate, and inherited IRA lifetime distribution total.
Gemini Free-Tier Callout on Guide Tab
Improvements
- Added a callout on the Guide tab empty state recommending Google's Gemini API free tier for users new to BYOK AI. The callout appears only when no provider is configured and disappears once a key is set up. Includes a direct link to get a Gemini API key and a note that current rate limits can be verified in AI Studio.
- The callout is dated so the copy can be refreshed if Google adjusts their free-tier terms.
Employer Plan Roth Conversion Gate
Per-Account Conversion Gate
Many employer plans (401(k), 403(b), 457(b)) don’t permit in-plan Roth rollovers while you’re still employed — conversions from those accounts have to wait until you separate from service. RetIQ now models this with a per-account conversion gate. Each pre-tax account has a new dropdown under its row on the Accounts tab: Always (default, correct for IRAs and plans that permit in-service IRR), After primary retires, After spouse retires (when a spouse is enabled), or After specific age.
Engine Mechanics
Under the hood, the engine partitions your pre-tax balance into a convertible pool plus a list of gated tranches. Gated tranches grow at the same weighted pre-tax return as the rest of the pool and roll into the convertible pool automatically when their gate opens. Roth conversions and Tax-Aware Drawdown cap at the convertible portion; RMDs, QCDs, QLAC, and regular withdrawals reduce the full pool proportionally so gated balances shrink along with the rest. No migration needed — accounts with no gate set default to Always, preserving all existing plan behavior.
Discoverability
Gated balances surface in three places: the Roth Conversion Optimizer card shows a gated-balance summary, the Strategy Report Card shows a cyan callout explaining why conversion-based strategies may show reduced amounts, and the AI Guide answers “in-plan conversion” / “employer plan” questions with your specific gated total. The Tax Strategy workflow (“Optimize Your Roth Conversion Strategy”) includes a new tip pointing users to the Accounts tab before running the Optimizer.
Demo & Dev
Demo: the Lees example plan now marks the spouse’s 401(k) as gated until the spouse retires, showing how the Roth Optimizer respects the constraint.
Dev: added a localhost/127.0.0.1 hostname bypass for the license gate so local QA works without the dev.html bootstrap dance. Zero impact on production behavior — the bypass only activates when the hostname matches a local dev server.
Testing
Validation: 361 tests passing, +11 from v5.6.4. New tests in Category 17 (Roth Conversion Gate) cover: convertible-pool cap, pool exhaustion mid-window, gate unlock at retirement age, backward compatibility (accounts without the field), spouse-gated age conversion, spouse-disabled coercion to “always”, specific-age gate, pool-identity reconciliation, and RMD proportional reduction.
AI Settings Polish — Easier First-Time Setup
Improvements
- Added a short note in AI Settings clarifying that API access is billed separately from any ChatGPT, Claude, or Gemini consumer subscription you may already have. This is a frequent source of confusion — a ChatGPT Plus login does not work as an OpenAI API key.
- Each provider in the picker now shows its free-tier availability or rough per-question cost. Google Gemini and Groq both have free tiers generous enough to cover typical RetIQ use with no credit card required. DeepSeek is flagged as roughly ten times cheaper than Claude or GPT for pay-as-you-go users.
- Changed the default provider for new users from Anthropic to Google Gemini. Users who have already selected a provider see no change — only the first-time experience is affected.
AI Guide Quality Pass
Cloud AI Improvements
- Removed the “minimum three sentences” response rule. The AI Guide now matches answer length to the question — short for factual queries, thorough for complex ones. Shorter responses also mean lower API costs on your provider.
- Enriched the plan context sent to cloud AI. The model now receives peak net worth with the age it occurs, RMD start age and peak annual amount, which tab the user is currently viewing, filing status, the pre-Medicare ACA-sensitive window, and years-to-retirement / years-in-retirement counts. Previously the model saw only end-of-plan totals and had no awareness of the current view.
- Test Connection now verifies the full pipeline, not just API authentication. It asks the provider to echo a known plan fact (current age); a green checkmark confirms auth, system prompt assembly, plan context delivery, and response parsing all work end-to-end. Amber surfaces when auth works but plan context isn’t reaching the model — typically a provider that ignores system prompts or truncates long ones.
Guide Chat Reset & Layout Polish
Improvements
- Added a “↺ New chat” button to the Guide tab header. Clears the current conversation and returns to the starting view with prepared questions. Previously there was no way to reset a conversation without reloading the page.
- Reduced empty-state spacing in the Guide. When no conversation is in progress, the welcome card and input field now sit close together instead of being pushed to opposite ends of the viewport.
AI Settings Modal Fixes
Bug Fixes
- The Guide tab status indicator now refreshes correctly after closing the AI Settings modal. Previously, enabling cloud AI, saving a key, and closing Settings would leave the status showing “No AI configured” until the Guide tab was navigated away from and back.
- Fixed transparent AI Settings modal card. The modal now uses a distinct card background with a border and soft shadow so it reads as a clear foreground surface over the overlay.
Eligible Designated Beneficiary (EDB) Stretch Exceptions
EDB Regime Options
The inherited account regime dropdown now includes three additional options covering SECURE Act Eligible Designated Beneficiary exceptions to the 10-year rule: Disabled beneficiary (IRC §72(m)(7)), Chronically ill beneficiary (IRC §7702B(c)(2)), and Not more than 10 years younger than decedent. All three use the same IRS Pub 590-B Table I Single Life Expectancy stretch math as v5.5’s pre-2020 grandfathered regime.
Engine Refactor
The engine’s stretch-regime filter is now a set membership check rather than an equality test, so adding future stretch variants doesn’t require engine changes. Existing pre-2020 stretch and post-2019 10-year accounts are unaffected.
Not Modeled
Surviving spouse (uses spousal rollover into own IRA — add as Pre-Tax / Roth instead), minor children (stretch-to-10-year transition at age of majority), and successor beneficiary pass-through on a non-spouse beneficiary’s death. These edge cases warrant financial advisor guidance.
Testing
349 validation tests pass (was 348): 1 new test confirms EDB Disabled routes to the same Single Life Expectancy math as pre-2020 stretch.
Pre-2020 Stretch IRA Regime
Regime Selector
Inherited IRA and Inherited Roth accounts now support a per-account regime selector. Default is Post-2019 (SECURE Act 10-year), which is v5.4’s existing behavior. The new Pre-2020 stretch (grandfathered) option uses IRS Pub 590-B Table I (Single Life Expectancy) with the subtract-1 method for non-spouse beneficiaries who inherited before December 31, 2019 and are taking distributions over their own life expectancy.
Stretch Inputs
When pre-2020 stretch is selected, two new input fields appear: Age at first RMD (your age in the calendar year of your first required distribution) and Years elapsed (full years between your first RMD and today). The engine computes the forced annual distribution as balance ÷ (initial divisor − years elapsed) and decrements the divisor by 1.0 each subsequent year.
Tax & Cashflow Integration
Stretch distributions feed the same income counters as post-2019 distributions: traditional flows through ordinary income, SS taxation, MAGI, IRMAA, and NIIT correctly; Roth distributions are tax-free. Balances grow at the nominal return rate between distributions and contribute to net worth.
Backward Compatibility & Testing
Backward compatible by default — accounts without a regime field continue to use v5.4’s pooled post-2019 math exactly as before. 348 validation tests pass (up from 331): 10 new unit tests on the Single Life Expectancy helper + 7 integration tests covering migration safety, mixed-regime portfolios, and per-account tracking.
Deferred to Future Releases
Not yet modeled (planned for later): Eligible Designated Beneficiary exceptions (surviving spouse, minor children, disabled, chronically ill, and beneficiaries within 10 years of the decedent’s age), extra voluntary distributions above the forced minimum, and successor beneficiary pass-through on owner death.
Inherited IRA Account Types
SECURE Act 10-Year Distribution Engine
Two new account types: Inherited IRA and Inherited Roth IRA. Enter the year inherited to start the SECURE Act 10-year clock. The engine tracks inherited accounts as separate buckets with forced annual distributions spread evenly over the remaining window. Inherited traditional IRA distributions are taxed as ordinary income and flow through SS taxation, MAGI, IRMAA, and NIIT calculations. Inherited Roth distributions are tax-free. Both types are automatically excluded from Roth conversions, Tax-Aware Drawdown, and standard RMDs.
Spending & Withdrawal Integration
Inherited distribution cash offsets spending needs before voluntary withdrawals from other accounts. Excess distributions are reinvested into brokerage with full cost basis tracking. Inherited accounts are not part of the configurable withdrawal order — distributions are forced on the 10-year schedule.
Display & Dashboard
Inherited balances and distributions appear in the projection chart (3 new selectable categories), data table (3 new columns), and dashboard net worth stacked area. The Plan Summary shows an INHERITED badge with total distributions. Legacy composition includes any remaining inherited balance at end-of-plan. One-time expenses can now be withdrawn from inherited accounts.
Strategy Awareness
The Strategy Report Card shows a new insight when inherited accounts exist, explaining they are excluded from all Roth and Tax-Aware Drawdown alternatives with the distribution deadline and total. The Roth Conversion tab displays a pink callout noting inherited pre-tax is not eligible for conversion and showing the excluded balance. A new Dashboard lever card shows the inherited distribution timeline, estimated tax cost, and deadline.
Documentation & Testing
Manual updated with full Inherited IRA Accounts subsection covering 10-year distribution, Roth exclusion, RMD exclusion, tax treatment, spending priority, and spousal rollover note. Features and landing pages updated. New “Plan Around an Inherited IRA” guided workflow. 13 new automated tests (331 total) cover separate bucket tracking, distribution math, depletion timing, net worth identity, tax impact, Roth conversion exclusion, RMD exclusion, inherited Roth behavior, and non-interference with existing account types.
50-State Tax Sync, Relocation Analysis & Automated State Tax Updates
State Tax Data
Complete sync of all 50 states + DC to Tax Foundation 2026 data. 35 states updated: flat-rate corrections (NC, CO, GA, IN, KY, MS, UT, ID), bracket restructures (OH, MT, NE, OK, SC, AR, KS, ND), new high-income tiers (MD, NM, DC), Massachusetts 4% millionaire surtax added, and 13 states with inflation-adjusted thresholds and filing-status-specific brackets. New York’s bottom 5 rates lowered for 2026. All rates verified against the Tax Foundation’s authoritative spreadsheet.
Relocation Analysis
New Relocation Scenario card in the Scenarios tab. Model moving to a different state with an optional home sale (§121 exclusion applied automatically), mortgage payoff, expense adjustment, and full before/after comparison. The Strategy Report Card now surfaces “Relocate to Florida” automatically for users in income-tax states, showing estimated lifetime state tax savings.
Automated State Tax Updates
State tax rates now update from Cloudflare KV alongside federal regulatory data. Future rate changes are pushed to all users without an app update.
Validation
16 new state tax validation tests covering all updated states. 318 total tests passing.
Dashboard Redesign
Plan Overview
The separate Plan Summary paragraph, key metrics row, highest-impact lever cards, and Maximum Spending calculator are consolidated into a single tabbed card with three views: Snapshot (key metrics grid with active strategy badges), Focus Areas (highest-impact levers with max spending calculator), and Details (income, savings, and lifetime totals). Every number now appears exactly once — no redundancy between prose and metrics.
This Year’s Plan
Replaces two stacked collapsible accordion cards with a single card using a Working / Retirement tab toggle. New features: Account Transfers section for Roth conversions and Tax-Aware Drawdown (marked “does not affect totals”), standalone Healthcare line item, ⊕ info icons for contextual notes, dimmed zero-value rows (e.g., $0 state tax in Florida), and a Net Annual Cash Flow bar at the bottom showing surplus or drawdown rate.
Chart Tabs
The four dashboard charts — Net Worth, Income & Spending, Taxes & RMDs, and Cash Flows — now display one at a time in a tabbed container instead of a 2×2 grid. Each chart is full-width and taller for better readability on all screen sizes.
Strategy Report Card
Now uses a two-dimensional tab layout. Goal tabs run horizontally (Max Net Worth, Min Taxes, Min Tax+IRMAA, Max SS Income, Tax-Free Legacy). Strategy category tabs run vertically (SS Timing, Roth, Drawdown, Combined, Retirement Age, Tax Optimization, Asset Allocation). A green dot indicates which category contains the best alternative. Cross-tab insights link to the best overall strategy when it lives in a different category. Maximum 3–4 cards visible at any time.
Dashboard Inflation View & Debt Amortization
Dashboard — Today’s Dollars
The Today’s $ / Future $ toggle now appears on the Dashboard, not just the Projection tab. When enabled, all stat values (Peak Net Worth, End Net Worth, IRMAA, Peak RMD), the Plan Summary prose, and all four dashboard charts display in inflation-adjusted present-value dollars. Lifetime sums like total tax, total IRMAA, and total Roth conversions are deflated per-year before summing — giving you a properly weighted present-value total rather than a rough approximation.
Liabilities — Amortization Modeling
Debts can now track a remaining balance and interest rate. When a balance is entered, the engine computes the interest/principal split each year, tracks the declining balance, and automatically stops payments when the debt is paid off — no need to guess an end age. The Liabilities tab shows each debt as a card with payoff age, total interest paid, and a principal vs. interest breakdown. Debts without a balance continue working as fixed monthly payments for obligations like alimony. Two new Projection chart categories — Debt Interest and Debt Principal Paid — let you visualize the paydown schedule.
Roth Optimizer
The Roth Conversion Optimizer now tests conversion windows up to 40 years (previously 25). Early retirees with long runways benefit from a wider search that can find strategies spanning decades. Sampling increased from 20 to 30 windows for better coverage.
Savings Contribution Routing
New opt-in controls in the Accounts tab let you specify exactly where your pre-retirement savings go: 401(k) deferral (Traditional or Roth) and IRA contribution (Traditional or Roth), with the remainder flowing to brokerage. Previously, savings were auto-split 60/25/15 across Pre-Tax, Roth, and Brokerage. Routing amounts stay constant across income phases and savings growth. Employer match is always calculated against your 401(k) deferral and deposited to Traditional Pre-Tax, regardless of your 401(k) type. Available in Full mode only — Simple mode retains the automatic split.
AI Guide — Bring Your Own Key
AI Guide Tab
New Guide ✦ tab with an AI-powered assistant that knows your plan, your numbers, and every RetIQ feature. Ask questions like “Am I on track?”, “Should I explore Roth conversions?”, or “How do I prepare my spouse?” — and get answers personalized to your actual plan data.
Built-In Templates
13 pre-written answers cover the most common retirement planning questions with instant, accurate responses that cite your real numbers and walk you through the app step by step. No AI model needed for these — they work offline. Topics include Roth conversions, IRMAA, Social Security timing, stress testing, survivor planning, legacy, healthcare, spending, and Tax-Aware Drawdown.
Bring Your Own Key (BYOK)
For questions beyond the templates, connect your own API key from Anthropic (Claude), OpenAI (GPT), Google (Gemini), Perplexity, Meta (Llama), Groq, DeepSeek, or Mistral. Your key is stored locally in your browser. Plan data is sent to your chosen provider only when you ask a question — never stored, never logged by RetIQ. You pay the provider directly (typically a few cents per conversation).
Smart Suggestions
The Guide’s welcome screen analyzes your plan and shows personalized suggestions based on detected patterns: high pre-tax balance with no Roth strategy, significant IRMAA surcharges, single-life pension with a spouse, plan running short, or early retirement without healthcare. Tap any suggestion for an instant detailed answer.
Workflows Remain Available
The 8 Guided Workflows (Tax Valley, Roth Optimization, ACA Coordination, Stress Testing, Survivor Risk, Spouse Roadmap, Pension Survivor, Legacy) continue to work exactly as before. The AI Guide is an additional way to get help, not a replacement.
Security
API keys are stored in your browser’s localStorage on your device only. When you ask a question, your plan summary and the question are sent through RetIQ’s stateless Cloudflare Worker proxy to the selected provider. The proxy forwards the request and returns the answer — it never stores, logs, or inspects your key or data. Without cloud AI enabled, all computation stays 100% local.
Marginal Rate Curve — Tax Torpedo Visualization
New "Analyze Marginal Rates" chart on the Roth Conversions tab. Sweeps conversion amounts from $0 to your pre-tax balance and plots the true effective marginal tax rate at each level. Reveals the "tax torpedo" — where SS taxation stacking, capital gains bracket shifts, OBBB senior deduction phaseout, and IRMAA surcharges all compound on the same dollar. Your current conversion amount is shown as a reference line.
Strategy Check-In
Strategy Check-In Card
New Dashboard card that tracks whether your active strategy is still optimal as your portfolio changes. Click “Save Check-In” to snapshot your current metrics and strategy. When you later update account balances, the card compares your new projection against the snapshot and shows one of three states:
- On Track — balances haven’t changed meaningfully. Your strategy is still the best option.
- Worth Reviewing — balances shifted significantly (5%+) and a different strategy now leads by a meaningful margin. Shows what changed, the metric deltas, and which alternative now ranks higher.
- Milestone Alert — approaching a decision point regardless of balance changes: RMD start within 3 years, Medicare at 65, Roth conversion window closing, or SS claiming age approaching.
The card answers: “Given where my portfolio actually is today, should I change anything?” Update Snapshot to accept the new baseline, or click Review to jump to the Strategy Report Card.
Roth Chart Fix, Guided Workflows & Strategy Report Clarity
Roth Conversion Advantage Chart (Bug Fix)
Fixed the Conversion Advantage chart and breakeven age calculation, which were double-counting conversion taxes paid from cash or brokerage. Since v4.6 added explicit conversion tax deduction from accounts, the chart’s cumulative tax adjustment was subtracting those taxes twice — making conversions look permanently unprofitable. The chart now correctly excludes conversion taxes (already reflected in net worth) from its tax adjustment. Breakeven ages and the Conversion Advantage line are now accurate. Affects both the Impact Analysis and the Roth Optimizer charts.
Strategy Report Alternatives (Bug Fix)
Fixed Roth conversion alternatives in both the Dashboard and Survivor Strategy Report Cards. Alternatives were creating bare rothConversion objects that dropped the user’s IRA basis (Form 8606) and conversion tax source settings from v4.6. This overstated conversion tax cost for anyone with after-tax IRA contributions and mismodeled tax payment source. Alternatives now preserve all existing Roth settings while overriding only the strategy-specific parameters.
New Guided Workflows
Four new workflows added, bringing the total from 8 to 12:
- Plan a Career Wind-Down (Pre-Retirement): Model a pay cut, part-time transition, or sabbatical using Income Phases. New Pre-Retirement category.
- Use QCDs to Reduce RMDs (Tax Strategy): Set up Qualified Charitable Distributions to satisfy RMDs without adding to taxable income.
- Customize Your Withdrawal Order (Portfolio & Spending): Override the default account drawdown sequence, add age-based phases for ACA optimization. New Portfolio & Spending category.
- Optimize Your Cash Allocation (Portfolio & Spending): Detect excess cash drag and evaluate redeploying to brokerage using the Dashboard lever card and Strategy Report.
Deploy Cash to Brokerage (Survivor)
The Survivor Strategy Report Card now tests a “Deploy Cash to Brokerage” alternative, matching the Dashboard Strategy Report Card. Previously only available in the Dashboard.
Strategy Report Card — Category Tags & Apply Guidance
Each strategy alternative now shows a category tag (SS Timing, Roth Strategy, Tax-Aware Drawdown, Combined, etc.) so users can see at a glance what Apply will change. New info box explains how Apply works: different-category strategies layer, same-category strategies replace, and Combined strategies change multiple settings at once. Each alternative uses its own preset parameters, not the user’s manual input tab settings.
Conversion Impact Analysis — Scope Clarification
New note at the top of the Roth Conversion Impact Analysis clarifies that it compares the user’s exact manual settings against no conversions, while the Dashboard Strategy Report Card tests different preset strategies. If results differ, the strategies are different — not contradictory.
Documentation
New manual sections: “How Alternatives Are Tested” explains why Report Card results can differ from the Roth Conversions tab. “How Apply Works” documents the layering behavior with concrete examples and a recommended iterative workflow. Roth-related workflows updated with guidance on the Report Card vs. Impact Analysis relationship.
QLAC — Qualified Longevity Annuity Contract
QLAC Modeling
New engine feature for modeling a Qualified Longevity Annuity Contract purchased inside an IRA or 401(k). Enter purchase amount (SECURE 2.0 max $200,000), purchase age, payout start age (must begin by 85), and annual payout from your insurance company quote. The purchase moves money from pre-tax to an illiquid QLAC balance — not a taxable event. RMDs naturally decrease since the pre-tax balance is smaller. At payout age, guaranteed lifetime income starts, fully taxable as ordinary income. QLAC balance included in net worth. Strategy Report tests a $200K QLAC for plans with $300K+ in pre-tax accounts.
Validation
4 new QLAC tests. Total: 302 automated tests, 35 categories.
Tax Optimization Suite
0% Capital Gains Harvesting
New engine feature that automatically detects unused room in the 0% long-term capital gains bracket each year and steps up brokerage cost basis at zero tax. IRMAA-aware — caps the harvest at the next Medicare surcharge threshold. Toggle in the Accounts tab (requires cost basis to be set). Visible in the Projection Table and tested as a Strategy Report alternative.
Tax-Loss Harvesting
Enter your estimated annual harvestable losses and any carry-forward balance. The engine applies IRS rules each year: losses offset capital gains dollar-for-dollar, then up to $3,000/yr of ordinary income, with unlimited carry-forward. Projection Table shows the offset applied and running carry-forward. Strategy Report tests a $5K/yr TLH scenario.
Itemized vs Standard Deduction
When enabled, the engine compares standard and itemized deductions each year and picks the winner. Itemizable: SALT (capped $10K), medical expenses above 7.5% AGI, and non-QCD charitable giving (capped 60% AGI). Senior and OBBB additions apply only to standard. Inputs for SALT and medical in the Accounts tab; charitable giving flows in automatically from the Charity tab.
DAF / Charitable Bunching
Concentrate 2 or 3 years of charitable giving into a single Donor-Advised Fund contribution. Bunch years itemize; off years take the standard deduction. Total giving unchanged. Toggle and cycle selector in the Charity tab. Strategy Report tests bunching with itemized deductions enabled.
SmartFill Itemized Deduction Awareness
Roth Smart Fill and Tax-Aware Drawdown Smart Fill now account for itemized deductions when computing bracket room. If your itemized total exceeds the standard deduction, the engine sees the larger deduction and converts or draws down more to fully utilize the bracket space.
Tax Optimization Insight Cards
Three new Dashboard lever cards proactively surface tax optimization opportunities: 0% CG Harvesting (when unrealized gains exist with 0% bracket room available), Tax-Loss Harvesting (for brokerage accounts over $100K), and Itemized Deduction comparison (when SALT + charity may beat the standard deduction). Each shows estimated lifetime savings and links to the relevant settings.
Roth Conversion Timing Guidance
New in-app callout and manual section on the December conversion timing strategy: convert late in the year with IRS withholding to avoid estimated-tax penalties, then replenish via the 60-day indirect rollover. Covers the one-per-12-month rollover limit vs. unlimited direct trustee-to-trustee conversions.
Validation
16 new tests across 4 categories (CG Harvesting, TLH, Itemized Deductions, DAF Bunching). Total: 298 automated tests, 34 categories.
Cash Drag Detection & UX Polish
Cash Drag Lever Card
New Dashboard lever card flags excess cash earning below market rate. Triggers when cash exceeds $100K and 15% of portfolio with a meaningful return gap. Shows the dollar amount above a 1-year reserve and the compounded opportunity cost over your projection horizon.
Deploy Cash to Brokerage (Strategy Report)
The Strategy Report Card now tests a “Deploy Cash to Brokerage” alternative that models moving excess HYSA funds into your brokerage while keeping a 1-year expense reserve. Ranked alongside other strategies under a new Asset Allocation category.
5-Year Rule Tracker
The 5-Year Rule Tracker card on the Roth Conversions tab is now hidden when all conversions happen after age 59½, since every row would show immediate access. The card still appears whenever any conversion is before 60.
Workflow Updates
The Tax Valley and Roth Strategy workflows now reference BETR, IRA basis, and conversion tax source in their step descriptions and checkpoints.
BETR Framework & Roth Conversion Enhancements
Break-Even Tax Rate (BETR)
The Conversion Impact Analysis now displays a Break-Even Tax Rate — the future marginal tax rate at which converting and not converting produce equal after-tax outcomes. If your expected future rate is above the BETR, conversion is favorable. Derived from Vanguard’s BETR research framework.
IRA Basis (Form 8606)
New input: Nondeductible IRA Basis. If your traditional IRA contains after-tax contributions, the engine now applies the IRS pro-rata rule — only the pre-tax portion of each conversion is taxed. Basis depletes proportionally as you convert over multiple years. Previously, all conversions were treated as fully taxable.
Conversion Tax Source
New dropdown: Pay Conversion Tax From. Choose between Cash/Brokerage (recommended — full amount stays in Roth), Cash Only, Withhold from IRA (less lands in Roth), or Not Modeled (legacy behavior). The engine now explicitly deducts conversion taxes from the selected account, with brokerage cost basis tracked proportionally on liquidation.
Backdoor Roth Insight
A new Insights card alerts high-income users whose traditional IRA balance blocks efficient backdoor Roth contributions due to the pro-rata rule. Explains how converting the IRA clears the obstacle and shows the annual backdoor contribution potential.
Pre-Retirement Income Phases
Engine
Added income phase support to the projection engine. Each phase defines an age range with its own salary, savings amount, and growth rates. When no phases are defined, income works exactly as before — a single salary with uniform growth. When phases are defined, ages not covered by any phase fall back to base income rather than zeroing out.
Income Tab (Full Mode)
New “Pre-Retirement Income Phases” card in the Income tab. Click “Add Income Phase” to create your first phase, pre-populated from your current income, savings, and growth rate. Add a second phase for a career wind-down, part-time period, or sabbatical. Each phase shows income at start and end ages. Spouse phases are supported independently.
Use Case
Designed for people a few years from retirement who plan to take a lower salary, go part-time, or change careers before fully retiring. Previously, the only option was a single income with uniform growth — no way to model a pay cut at age 62 followed by retirement at 65.
Projection Visibility, Spouse Fix & QA Improvements
Projection Table & Charts
Added six new columns to both the projection chart and data table: Other Income, Qualified Dividends, Tax-Aware Drawdown, TAD Tax Cost, HSA Balance, and HSA Contributions. These were already computed by the engine but not visible to users. All auto-hide when values are zero.
Chart Selection Fix
Previously selected chart categories that no longer had data (e.g., after disabling a feature) could become invisible but still count toward the 4-category limit, blocking new selections. Stale keys are now filtered automatically on every render.
Spouse Toggle
Disabling and re-enabling the spouse checkbox now correctly preserves the spouse’s age. Previously, re-enabling left the age at zero, silently zeroing out spouse income, savings, and Social Security in the projection.
Withdrawal Order
Fixed the “Reset to recommended order” button in the Assumptions tab, which was broken due to an HTML escaping issue. The button now works correctly.
Scenarios
Retirement age scenarios (Retire at 40, 50, etc.) are now hidden when below or equal to your current age, since they would produce identical projections to the baseline.
Roth Optimizer: Wider Windows for Early Retirees
Roth Optimizer
The optimizer now tests conversion windows up to 25 years (previously capped at 15). Early retirees with long runways to RMDs can now see Fill 12% strategies tested over realistic time horizons, giving the optimizer a fairer comparison between aggressive short-window conversions and conservative long-window strategies.
Conversion & TAD Tax Payment
Engine
Roth conversion and Tax-Aware Drawdown taxes are now explicitly paid from non-retirement accounts (cash/HYS first, then brokerage) before year-end growth. Previously, the tax was computed and reported but not deducted from any account balance, slightly overstating net worth in conversion years.
Dashboard
The This Year card no longer double-counts conversion and drawdown taxes. Federal tax now excludes amounts already shown in the Roth Conversions and Tax-Aware Drawdown sections.
2026 Tax Year Update & Automated Regulatory Monitor
Regulatory Data
All embedded tax constants updated to 2026 figures. Sources: IRS Rev. Proc. 2025-32, IRS Notice 2025-67, CMS Nov 2025, HHS 2026 FPL, IRS Rev. Proc. 2025-19.
- Federal brackets MFJ and Single adjusted ~2.4% for inflation
- Standard deduction MFJ $31,500 → $32,200 · Single $15,750 → $16,100
- Senior additional deduction MFJ $1,600 → $1,650 · Single $2,000 → $2,050
- Capital gains 0% threshold MFJ $96,700 → $98,900
- Capital gains 15% threshold MFJ $583,750 → $613,700
- SS wage base $176,100 → $184,500
- 401k elective deferral $23,500 → $24,500
- 401k catch-up (age 50–59, 64+) $7,500 → $8,000
- IRA contribution limit $7,000 → $7,500
- HSA self-only $4,300 → $4,400 · Family $8,550 → $8,750
- §415(c) combined limit $70,000 → $72,000
- QCD annual limit $108,000 → $110,000
- Medicare Part B base premium $185.00 → $202.90/month
- IRMAA MFJ Tier 1 threshold $212,000 → $218,000 · all tiers updated
- HHS FPL household of 1: $15,650 → $15,960
- All 282 validation tests updated and passing
Automated Regulatory Monitor
Deployed a Cloudflare Worker that runs weekly. It fetches IRS, SSA, CMS, and HHS source pages, uses AI to extract updated figures, validates them against a strict schema, and pushes changes to Cloudflare KV. All three platforms receive updated tax data on next load with no app update required.
Guided Workflows
New Workflows tab (Full mode, Pro only) with 8 step-by-step walkthroughs for complex multi-tab analyses: tax valley optimization, Roth conversion strategy, ACA/Roth/withdrawal coordination, end-to-end stress testing, survivor risk analysis, spouse roadmap preparation, pension survivor benefit selection, and after-tax legacy optimization. Each workflow includes numbered steps, navigation cues, and checkpoint prompts.
Strategy Report Card — Reset to Original
After clicking Apply on any alternative strategy, a “Reset to Original” button appears. One click reverts all Apply experiments and restores your plan to where you started. The snapshot clears on page reload.
Scenario Dropdown & Early Retirement Ages
Scenario buttons replaced with a grouped dropdown menu (Retirement Age, Social Security, Expenses & Returns). Added Retire at 40 and Retire at 50 scenarios. Cleaner on mobile — renders as the native iOS/Android picker.
Input Validation
Return rates are now clamped to −5% – 25%, growth rates to 0% – 20%, inflation to 0% – 15%, and SS COLA to 0% – 10%. Prevents accidental entries (e.g., typing 76 instead of 7.6) from producing runaway projections.
Chart Overlays
Raised the simultaneous chart category limit from 3 to 4 in the Projection and Scenarios tabs.
Tax-Aware Drawdown, Dawn Theme & More
Tax-Aware Drawdown
Voluntary pre-tax withdrawal strategy that fills a target bracket before RMDs begin, reducing future RMD burden. IRMAA-aware, OBBB-aware, integrates with the Roth optimizer. Proceeds land in brokerage with full cost basis for stepped-up basis at death.
Dawn Theme
Third theme alongside dark and light — warm cream palette with a purple accent. Now the default on all platforms.
Max Tax-Free Legacy Goal
Fifth Strategy Report goal. Ranks strategies by after-tax heir value: Roth + taxable (stepped-up basis) + HSA, minus pre-tax discounted by the heir’s bracket under the SECURE Act 10-year rule. Shown when legacy planning is enabled.
Survivor Planning Center
Dedicated tab (visible when a spouse is configured) with three sub-tabs: Overview, Strategies, and Adopt Plan. Supports adopting the survivor’s roadmap in both directions.
Other
- Mortgage balance field on asset sale cash events — separates gross price from net deposit after payoff, with §121 exclusion modeling
- Cash and brokerage accounts fully separated with independent return rates and tax treatment
- Save/Load added to web mobile overflow menu
- App Store badges added to landing page
- Washington family example updated to demonstrate home sale with mortgage payoff
- Fixed ssCOLA falsy-zero bug
Modular Architecture, Regulatory Data System & Freemium Model
Modular Source Architecture
Rewrote the build system. The app is now assembled from 36 modular source files plus a pure-math engine with zero DOM dependencies, enabling per-platform builds for web, iOS, and macOS from a single codebase.
Regulatory Constants System
Centralized all tax, Medicare, Social Security, ACA, and contribution limit constants into a single REGS data structure that fetches updates from Cloudflare KV on load. No app update required to receive new tax year figures. Falls back to embedded defaults if offline.
Freemium Model
Launched a free Simple tier and $49.99 one-time in-app purchase for full unlock on iOS and macOS. Web remains $49 one-time via Stripe. The free tier includes data entry, basic projections, the dashboard, save/load, and the Johnson family example.
iOS & macOS Apps
RetIQ is now available on the iOS App Store and Mac App Store, alongside the existing web app. All three share the same calculation engine and save file format.
OBBB Act 2025
Added the One Big Beautiful Bill Act senior standard deduction ($6,000/person, phasing out at 6% above $75K single / $150K MFJ, effective 2025–2028). Updated all affected brackets and validation tests.
Life Insurance Modeling
Life Insurance
Term and permanent life insurance policies modeled with annual premiums and tax-free death benefits (IRC §101). Supports multiple policies per person and spousal policies. Death benefits deposit into the survivor’s brokerage account at the time of death and are reflected in legacy composition.
One-Time Cash Events & LTC Insurance Inflation
One-Time Cash Events
Model planned property sales, inheritances, or other lump-sum events at a specific age. Capital gains calculated automatically with IRC §121 primary home exclusion ($250K single / $500K MFJ). Proceeds can flow into the brokerage or cash account.
LTC Insurance Inflation Protection
Long-term care insurance benefits now compound over time. Choose from None, 2%, 3%, or 5% compound inflation protection. The engine compounds the insurance benefit alongside projected care costs so projections reflect realistic coverage value at the age it’s actually needed.
Essentials & Full Control Modes
Two modes, one engine. Essentials presents a streamlined view for straightforward retirement planning — fewer tabs, fewer fields, the same math underneath. Full Control reveals all tabs and every advanced feature. Toggle anytime without affecting your data or calculations.
Monte Carlo Model Selection & Roth Optimizer Improvements
Monte Carlo
Added model selection: Historical (U.S. market distributions 1926–present), Normal (parametric), and Conservative (lower expected return). Each affects the return and volatility assumptions across 2,000 simulated paths.
Roth Optimizer
Added IRMAA-aware Smart Fill — fills the target bracket while capping conversions before crossing an IRMAA threshold. Added custom schedule mode with a per-year editable table and a “Generate Optimal” button that finds the best conversion amount for each year in the window.
Pension, Legacy Goals, Liabilities, LTC & Charitable Giving
Pension
Expanded pension modeling: survivor benefit options (single-life, joint & 50/75/100%), configurable taxable percentage, COLA, and start age. Survivor benefit flows into the surviving spouse’s income correctly.
Legacy & Estate Goals
Legacy composition showing after-tax heir value breakdown across account types. Target legacy amount with a gap indicator. Charitable bequest modeling.
Liabilities
Debt schedules for mortgages, alimony, student loans, and other long-term obligations. Each has an annual amount and end age, subtracted from cash flow in the years it applies.
Long-Term Care
Dedicated LTC tab with annual care cost, start age, duration, and LTC insurance benefit offset. 2025 national cost benchmarks embedded as defaults.
Charitable Giving
Annual giving with start/end age, one-time gifts, and Qualified Charitable Distribution from pre-tax accounts. QCD reduces MAGI dollar-for-dollar up to the annual limit, offsetting RMD income.
ACA Subsidy Engine
Full Affordable Care Act premium tax credit calculation based on projected MAGI and household size. Supports both the enhanced subsidy table (ARPA/IRA, no income cliff through 2025) and the original table (400% FPL cliff) for post-2025 planning. Subsidy reduces out-of-pocket healthcare cost in the projection year by year.
Healthcare Source Selection & Pre-Medicare Gap
Six pre-Medicare healthcare source options: ACA Marketplace, COBRA, Spouse’s employer plan, VA/Medicaid, Retiree plan, and self-pay. Each has a different default cost and medical inflation rate. The engine models the full gap between early retirement and Medicare eligibility at 65.
Social Security Earnings Test
The SSA retirement earnings test for early claimers. Benefits withheld at $1 for every $2 earned above the annual exempt amount (under FRA all year), or $1 for every $3 (in the year of FRA). Withheld benefits are recredited as a permanent benefit increase after FRA. Exempt amounts indexed annually by the Average Wage Index.
This Year Summary Card
Dashboard card showing the current year’s projected cash flows: income sources, withdrawals, conversions, taxes owed, and net. When retirement is within 5 years, a second card previews the retirement year’s prorated income and new tax picture.
4-Account System, SSDI & Validation Suite
4-Account Modeling
Separated Cash/HYS and Brokerage into independent accounts with configurable return rates, tax treatment, and withdrawal order. Cash interest treated as ordinary income; brokerage withdrawals trigger capital gains using a 50% cost basis estimate with 0/15/20% tiered rates based on income.
SSDI
Social Security Disability Income modeled for both spouses, with conversion to retirement benefits at FRA and correct survivor rules.
Validation Suite
Automated validation suite covering federal tax, SS PIA, IRMAA, ACA subsidies, RMDs, and more — each test citing its authoritative source (IRS, SSA, CMS). Viewable at retirementiq.app/validation.html.
Tooltips & Plain Language
Contextual help icons throughout input forms with plain-English explanations of retirement finance terminology.