Calculation catalog › Required minimum distributions

RMD required annual

Required minimum distribution dollars taken during the projection year.

Field: requiredAmount Unit: US dollars Basis: nominal dollars Computed by: Engine Status: Complete chain

Appears in: csv (rmd); report (year ledger RMD); results-table (RMD column); scenarios-page (Annual "RMD" and lifetime "RMDs"); cash-flow-drilldown (requiredMinimumDistribution source line)

Calculation records

  • RMD joint-life divisor Data record, justified by derivation

    Purpose: Use the Joint and Last Survivor table when a sole-beneficiary spouse is more than ten years younger.

    Statement: rmd/jointLifeTable.ts#jointLifeTableDivisor and rmd/rmd.ts#requiredMinimumDistribution use the Joint and Last Survivor table of 26 CFR 1.401(a)(9)-9(d) when the sole-beneficiary spouse is more than ten years younger, dividing the prior-year-end balance by the owner-age / spouse-age table entry. The qualifying-spouse exception replaces the Uniform Lifetime divisor with the larger of the two, so the RMD falls. Units: nominal USD. Rounding: none; the published figure is a binary float compared to cents. The table ships delta-packed (each owner-age row as its spouse-age-0 divisor in tenths, then one letter per later spouse age for the tenths the divisor falls) and is decoded once at module load. The encoding is lossless: rmd/jointLifeTable.test.ts compares the decoded table with the literal extract kept in rmd/jointLifeTable.literal.test-support.ts, every cell and the lookup on 67,081 owner and spouse age pairs, by Object.is.

    Formula: divisor = ownerAge - spouseAge > 10 ? max(uniform[ownerAge], jointLife[ownerAge][spouseAge]) : uniform[ownerAge]; rmd = priorYearEndBalance / divisor

    • ownerAge: Owner age attained in the distribution year (unit: years) (domain: integer)
    • spouseAge: Sole-beneficiary spouse age attained in the distribution year (unit: years) (domain: integer)
    • priorYearEndBalance: Traditional-account balance at the prior December 31 (unit: usd) (domain: positive; a nonpositive balance returns 0)

    Timing: one account-year

    Rounding: none

    Limits:

    • The gap test is strictly more than ten years: an exactly ten-year gap keeps the Uniform Lifetime divisor
    • The engine takes the larger of the two divisors, so a joint-life entry smaller than the uniform one could never raise the RMD; at the asserted ages the joint-life entry is the larger
    • The spouse must be the sole beneficiary; this record does not decide that fact, it prices the divisor once the caller asserts it

    Provenance: derived by codex, implemented by claude.

    Independent review: cursor

    Gates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass

    Worksheet: rmd-joint-life-divisor.md Mutation receipt: rmd-joint-life-divisor.mutation.md

    Evidence tests: rmd.evidence.test.ts

    Implemented in: jointLifeTable.ts; rmd.ts

    Is the number of: rmd-required-annual

  • RMD uniform lifetime divisor Data record, justified by derivation

    Purpose: Divide the prior December 31 balance by the Uniform Lifetime Table entry for the age attained.

    Statement: rmd/rmd.ts#requiredMinimumDistribution computes an owner RMD for the age-attained year as the prior December 31 traditional-account balance divided by the Uniform Lifetime Table divisor in the 2026 tax parameters, when no qualifying more-than-ten-years-younger sole-spouse beneficiary applies. Nothing is required before the owner attains the cohort applicable age. Units: nominal USD. Rounding: none.

    Formula: rmd = priorYearEndBalance / uniformLifetimeTable[ageAttained], and 0 when ageAttained < applicableAge

    • priorYearEndBalance: Traditional-account balance at the prior December 31 (unit: usd) (domain: positive; a nonpositive balance returns 0)
    • ageAttained: Owner age attained in the distribution year (unit: years) (domain: integer)
    • uniformLifetimeTable: year2026.rmd.uniformLifetimeTable, the tax parameters’ reproduction of IRS Pub. 590-B (unit: years) (domain: positive entries)

    Timing: one account-year

    Rounding: none

    Limits:

    • The balance is the PRIOR December 31 figure; using the current year-end balance publishes a different RMD from the same table
    • Inherited-account rules and the first-year April 1 deferral are separate phases: the RMD is taken in the age-attained year
    • A qualifying sole-beneficiary spouse more than ten years younger replaces this divisor, which is the sibling rmd-joint-life-divisor record
    • In the year a surviving spouse's treat-as-own election takes effect, each elected IRA's owner RMD is its own prior December 31 balance divided by this divisor, calculated separately for each IRA: Treas. Reg. 1.408-8(c)(3) determines that year's requirement under section 401(a)(9)(A) with the spouse as IRA owner, 1.408-8(b)(2) substitutes the IRA's balance as of the preceding December 31 for the 1.401(a)(9)-5(b) account balance, and 1.408-8(e)(1)(i) requires the minimum to be calculated separately for each IRA. A lone IRA's positive j(4) reference balance is that prior December 31 balance. Otherwise the balance is the IRA's opening balance plus the distributions accepted as taken from it earlier in the year: the projection never debits an accepted distribution, so the plan's balance is entered after it. The reference stands in only for an IRA alone in its payee/decedent/type pool; when the pool holds two or more IRAs, which the plan checks give identical election facts, the one reference cannot be each IRA's own balance. A 29,600 IRA pooled with a 100,000 one under a 100,000 reference owes 1,203.25 (29,600 / 24.6); until 2026-10-07 the engine charged it the reference's 4,065.04 (100,000 / 24.6). The requirements still aggregate into the owner's one owned-IRA section 4974 obligation. Pinned in simulate.spousalElectionYearOwnerRmd.test.ts
    • A distribution taken in the election year counts once toward the owner's total, whichever IRA it came from, because 1.408-8(e)(1)(i) lets the separately calculated requirements be totaled and distributed from any one or more of the IRAs. A completed current-year history row is credited to the IRA it names, and what that IRA does not need to the rest of the pool. The j(4) pre-election distribution is one figure in the pool's shared facts and names no IRA, so it is counted once for the pool: added back to the first IRA's balance and credited there first. The total requirement does not depend on which IRA carries it, since the IRAs share one owner and one divisor. With 99,000 and 29,600 IRAs, a 100,000 reference and 1,000 distributed before the election, the prior December 31 balances are 100,000 and 29,600, the requirements 4,065.04 and 1,203.25 (5,268.29), the 1,000 is credited once, 4,268.29 is forced, and the year distributes 5,268.29 with no shortfall. Until 2026-10-07 the engine credited the 1,000 to each IRA on the live balances, forced 3,227.64 and left 1,040.65 unmet while reporting no shortfall. Pinned in simulate.spousalElectionYearOwnerRmd.test.ts
    • Known limits, election year: the opening balance plus the accepted distributions omits any gain or loss between the prior December 31 and the date the balance was entered, which only a lone IRA's reference balance carries; when any IRA of a pool has a completed current-year history row, the pool's j(4) pre-election figure is not counted, which can overstate the forced distribution but never counts a dollar twice; and an election-year IRA whose live balance cannot cover its unpaid amount is not made up from another of the owner's IRAs, so the section 4974 shortfall can be overstated where another IRA could have paid it

    Provenance: derived by codex, implemented by claude.

    Independent review: grok

    Gates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass

    Worksheet: rmd-uniform-lifetime-divisor.md Mutation receipt: rmd-uniform-lifetime-divisor.mutation.md

    Evidence tests: rmd.evidence.test.ts

    Implemented in: rmd.ts; beneficiarySpousalElectionGateAdapter.ts; annualOwnedAccountDrawsPhase.ts

    Is the number of: rmd-required-annual

Records that feed this number

  • RMD applicable age and attain year Data record, justified by derivation

    Purpose: Place a 1951-1958 owner in the settled age-73 cohort and derive the year that age is attained.

    Statement: rmd/applicableAge.ts#applicableAgeAttainYears assigns an owner born in 1955 the settled applicable age 73, attained in 2028, with an IRA required beginning date of April 1 in calendar 2029; params/index.ts#rmdStartAgeForBirthYear carries the same cohort age for the annual RMD gate. For a whole-year applicable age the attain year is birth year plus age and the RBD year is one more than that. Units: calendar years. Rounding: none; integer years.

    Formula: applicableAge = 73 for births 1951..1958; attainYear = birthYear + applicableAge; rbdYear = attainYear + 1

    • birthYear: Owner year of birth (unit: year) (domain: integer)
    • applicableAge: Statutory applicable age for the birth cohort (unit: years) (domain: integer 72, 73 or 75, or the 70.5 tier)

    Timing: once per owner

    Rounding: none

    Limits:

    • Scoped to the settled 1951-1958 cohort: the 1959 cohort is contested between 73 and 75 and returns two attain years, and the date-sensitive 70.5 cohort needs a birth month
    • The RBD calendar year is asserted through deriveRbdComparison rather than as a date string: the module derives the year internally and publishes a before/on-or-after comparison, not an April 1 value

    Provenance: derived by codex, implemented by claude.

    Independent review: cursor

    Gates (6 of 6 pass): fixture registers a test: pass; pins resolve: pass; families exist: pass; worksheet exists: pass; mutation receipt exists: pass; provenance independent: pass

    Worksheet: rmd-applicable-age-attain-year.md Mutation receipt: rmd-applicable-age-attain-year.mutation.md

    Evidence tests: applicableAge.evidence.test.ts

    Implemented in: applicableAge.ts; index.ts

    Feeds: rmd-required-annual

Engine source: engine/src/projection/internal/types/result.ts (YearResult.rmd)

The evidence links on this page (each record's worksheet, mutation receipt, evidence tests and implementation, and the source links) are pinned to engine commit 2624dbdba9fd, committed 2026-10-11. The live calculation index and output-family census links point at the repository's main branch, so you can check this snapshot against them.