Help · What's new

What's new

From RangefinderInvest's built-in help · newest release line first · the site ships version 0.53.0

0.53: Every account is its own place

Navigation and account history were rebuilt from the ground up. Nothing you track changed; where you go to see it did.

Every account now opens its own workspace. Clicking an account, on the sidebar or anywhere its name appears, replaces the account list with a header of plain facts and four tabs: Transactions, Positions, Performance, and Account details. A transactions account gets the new register: one continuous, chronological list of every deposit, trade, and transfer with a Cash balance column and an always-on Share balance column beside it, sortable by Date, Activity, Security, Shares, Price or Amount (the two balance columns show only in Date order), scoped to a single security when you need it, with one Add transaction form that covers cash too, and one Reconcile sheet. A snapshot account keeps its Statements tab instead, unchanged. Holdings is now the aggregate view across every account and group; a row's "held in" link takes you straight to that account's own Positions, where a sold-out position is gone rather than flagged and a ticker links straight into Securities & prices.

Search in the register stays put unless you change security. Typing a search while looking at one security no longer goes blank, with nothing on screen to say why, just because you arrived at a different one: only a scope change to another security clears it now, and an empty result names every filter holding it back, security, search, date range, activity, with a Clear filters button that resets the first three and leaves the security scope for its own chip to clear.

The register no longer resets itself when nothing you did changed. A price update, a saved transaction, an import, an undo, or a reconcile used to collapse a register you'd widened back to its first 250 rows and quietly drop a bulk selection, with Delete N selected disappearing while no row had actually changed. Now only changing the Security scope, the sort, or a filter does that; a background refresh keeps your place and your ticked rows, dropping only a row that was deleted or moved out of view.

Income & Realized Gains now covers both, per holding, over a period you choose. The by-holding table gains a Realized gain column beside Income, and a Total, over Year to date, 1 year (the default), 3 years or All; every column sorts. A security you sold out of completely stays listed for whichever period its sale falls in, so a closed position's gain is findable again. Yield on Value is retired: it misread any position that changed size during the year, and a stock's own stated yield already lives on its stats strip. On a taxable account, both tables split Realized gain into Short-term and Long-term, matched to your oldest lots first; a dagger marks a figure whose shares came from an opening position or an in-kind transfer, where the true holding period isn't recorded.

Performance now shows the same chart as the Overview, scoped to one account. Value, TWR %, TWR %/yr, the date range with Custom, and the same benchmark overlay, from the same engines, minus Update and Rebuild, which stay on the Overview because they act on the whole portfolio. Underneath, a return table replaces the two tiles it used to show: 1M · 3M · YTD · 1Y · 3Y ann. · 5Y ann. · Since inception · Annualized, with 3Y and 5Y left blank until the account's own history reaches that far back.

The sidebar names your accounts, in your own order. Drag a row, or use Move up / Move down, to arrange the list the way you think about it; the order is remembered. Resize the sidebar itself, or collapse Portfolio, Research, and Planning to the sections you use.

The portfolio menu says, correctly, what's open. The old topbar status pill used to read "Local portfolio" even while a sample was loaded. It's gone; the sidebar's identity button now reads "Local portfolio" or "Sample: {name}" for real, and carries backups, restore, sample portfolios, and data location, the way the old pill's menu did, plus Back to my portfolio while a sample is open.

The app's version now lives at the foot of the sidebar, under Assistant, Settings and Help: one quiet line reading Version x.y.z that opens About, the same page the native menu and the command palette already reached.

Allocation models, Backtest, and Optimize share one workspace. A model picker and Allocation / Backtest / Optimize funds tabs sit above all three pages, so switching between them keeps the model you're looking at; a multi-model comparison and Apply's safeguards are unchanged.

Household profile is a page now, not only an overlay. Find it under Planning; the familiar quick-edit slide-over still opens from a Set-in-Profile link and returns you to where you were. Either way it's the same one draft: navigating away with unsaved changes, or switching accounts or databases mid-edit, is always asked about once, never lost silently.

A native Go menu, on both this app and CrucibleTrade. Back and Forward (⌘[ and ⌘], also topbar buttons) retrace your own path, leave-guards included; ⌘1 through ⌘9 jump straight to nine fixed destinations. See Back, Forward, and the Go menu for the full list and why they're deliberately inert while you're typing in a field. Check for Updates joins the same menu next to About.

A few Settings sections moved next to what they configure, each with a bookmarkable address that finds the new location: Scoring rules into the Screener's own drawer, the comparison-ticker list into an editor opened from either chart it feeds, and Withdraw options onto the Rebalance Planner page, where the strategy you pick and the defaults you save now stay visibly distinct. Appearance stays in Settings.

Six pages read differently, at the same address. Dashboard is now Overview, Rebalancing is Rebalance Planner, Target Models is Allocation models, Ticker Metadata is Securities & prices, and Projection is Retirement plan; Fixed Income is unchanged. Every old bookmark, pasted link, and search term for the old name still lands where it used to.

A reconcile settles a difference without rewriting your cost basis. Accepting one now stores a reconciliation adjustment as its own recorded fact, not something worked out later from a note, so settling a shortfall on one fund and a same-size surplus on another can't be mistaken for a fund reorganisation that would carry cost basis between them. The register shows it too: such a row reads Reconciliation, under Opening positions & adjustments, whether it settled cash or a share count, rather than as a deposit, withdrawal, or transfer.

Underneath all of it, switching your own portfolio, a sample, or a backup mid-edit is now something the app actively protects against: a save, or a price update already in flight, can no longer land in the database you just left, or the one you just opened for someone else's numbers. Asked for mid-download, the switch waits out the current batch of prices, saying so ("Finishing the price update…") on the same door you asked it from.

0.52: Pay down the mortgage

A plan with a mortgage, existing or planned, can now carry a schedule of extra principal payments and an early payoff, and the projection carries the note itself, path by path, so that money reduces the debt only by what your portfolio actually funded.

If your plan carries a mortgage, it will project different numbers than it did before. The feature rests on four corrections to how a mortgage was projected, and where a figure moved, it moved because the old one was wrong. They are listed at the end, separately from the feature.

0.52.2: the home searches now answer for your own plan. Two corrections, both to numbers Most house I can afford and the other home goal seekers report.

Working years. The searches charged rent, ownership costs and the mortgage payment to the portfolio from today, while the ordinary projection starts those costs at your first spending phase, on the assumption that salary covers them before then. If you have not retired yet, the searches were therefore simulating a different plan from the one you would get by applying their answer: they reported less house, lower success and a smaller portfolio at the buy year than your own plan shows, and could call a target not feasible that the plan actually meets. Every home search now uses your plan's own first spending age. Plans already drawing from the portfolio are unchanged.

The month you buy. A purchase switched from rent to ownership costs on the year boundary, so a December purchase was charged twelve months of ownership and no rent at all. The buy year is now split at the purchase month: rent up to it, ownership after it. A December purchase costs eleven months of rent and one of ownership; January and undated purchases are unchanged. Buying in the current year, the split covers the months still ahead: if it is June and you buy in December, the plan funds five more months of rent and then one month of ownership. Because rent is usually the dearer of the two, the buy year used to look cheaper than the year you actually live, which slightly overstated what you could afford; if your ownership costs are higher than your rent, the correction runs the other way. No year but the buy year is affected. The same month already moved the down payment and the mortgage's first installment.

The two pull in opposite directions for a household that has not retired and buys later in the year: the first raises the affordable price, the second trims it. Both move it toward what your own plan will do.

0.52.1: clearer home-affordability inputs. Goal-seek insurance, HOA and maintenance are entered in dollars per year and stay fixed across house prices; property tax still scales with price. The shorter explanation of Most house I can afford describes what the search compares. Chart down payment (%) replaces “Curve down %”: it changes only the gold line, defaults to 20% when blank, and never restricts the search's five down-payment options. Because insurance and maintenance previously scaled with price, the new fixed annual estimates can change affordability results.

Extra principal payments and an early payoff. In the Housing panel, an existing mortgage or a planned purchase takes dated extra-principal payments (a year, a month, an amount in today's dollars or in the dollars of the payment year, and the accounts they draw from), and the payoff can name its month. Each row says what the plan will do with it: funded in full, capped at what is left of the loan with the excess skipped, or not simulated (before the loan starts, after it ends, or beyond the plan's horizon). A row is never silently dropped. The panel reads the loan end with and without the schedule, the interest saved over the loan's life and inside the plan, the remaining balance by year in both dollar bases, and, on a rate buydown, the interest you paid beside what the subsidy covered. How the payments are modeled explains the two dollar bases, the funded-only rule, and what each placement verdict means.

The simulation carries the note. Each simulated path keeps its own mortgage balance and amortizes it monthly. A payment the portfolio could not fund is a named shortfall against that payment, not a forgiven debt. The scheduled installments are always deemed paid, with any gap booked against your other spending, so the loan never falls into arrears the model does not simulate. The Detail tab gains a mortgage column group and two diagnostics that say how much of your spending the portfolio really funded beside the installments; see reading the results. The Lifetime spending chart now draws its recurring bands from the one simulated year at the median total, so they add up to that total. For a plan without a mortgage the bands are unchanged.

Compare how to pay for the home. Explore gains a three-way comparison on one shared seed: for a purchase, all cash, financed to term, and as entered; for a home you own, pay off now, keep the loan, and as entered. Each row reports success, the reduction below your entered expenses, lifetime tax and Medicare, ending portfolio, the mortgage debt still owed at plan end, and net liquid assets at plan end, the portfolio minus that debt, formed on every path before the median is taken. "Pay off now" is a real instant: the statement balance, no interest, nothing owed for the month you are in. Two portfolio-only labels are renamed so the new figure is not confused with them: "Net worth at longevity" is now Portfolio at plan end, and "Projected net worth" is Projected portfolio.

The goal seekers carry your extra payments. When your live plan runs a mortgage, the home searches score every candidate with the payments you entered, as fixed amounts in the basis you entered, behind a box you can untick. Apply writes exactly what a row was scored with, its payments included or cleared as the row's own label says. Before this release a search scored candidates without your payments and Apply kept them, so the success rate you clicked was not the one the plan then showed. The home-purchase optimizer says which rows each kind of result keeps.

The AI door reports the note. A projection run through the assistant returns the planned and simulated loan end, the interest saved, the debt and the net liquid assets at the horizon, and each payment's funded share, and it echoes the schedule it ran. It can run your plan beside a twin with the schedule stripped, inside one path budget split in two, so the two rows are compared with each other and not with a separate full-resolution run.

Plans that cannot be simulated say so. A planned purchase with no price used to run as a free house; it is refused by name now, on the page, in the check-in card and through the AI. A saved plan whose payment rows or months were malformed used to crash the page or the AI tool; every such shape is a named refusal.

The four corrections.

  • Monthly amortization. The mortgage is amortized monthly, the way a lender does it, instead of once a year. A typical payment falls by about 1% ($36,757 to $36,407 a year on a $480,000 note at 6.5% over 30 years), and an early payoff rises a little, because the lower payment repays principal more slowly and the payoff now includes that month's interest.
  • The elapsed part of this year. An existing mortgage, or a home bought this year, was understated every year after this one by the fraction of this year already gone: a plan run in mid-September at 2.5% inflation charged 1.71% too little, $617 on a $36,000 payment and $6,855 on a $400,000 payoff.
  • Each path's own inflation. The payment followed the inflation you assumed rather than the inflation each simulated path produced: on a path running at 10% the plan charged $39,447 a year against a contract fixed at $36,757. A fixed-rate note is now the fixed hedge it really is, the same nominal payment on every path, worth more or less in today's dollars as that path's prices move.
  • A first death does not change the contract. The survivor's spending is scaled down as before, but the mortgage payment is not: at a 75% survivor factor the plan used to charge $27,568 a year from the year of the first death, where the contract says $36,407.

A plan carrying a mortgage costs about 1.85 times as much to simulate per path as the same plan without one; the assistant's tool says so and suggests fewer paths where latency matters more than resolution.

0.51: The numbers, checked

An independent audit went through the projection engine and every panel that reads it, one number at a time, and raised 28 findings. All 28 are addressed in this release. A blind sweep of the panels found nine more, and a final review of the finished work found five more still. Each one has a test that failed before the fix and passes after it, and each was re-checked afterwards against the audit's own probes.

Your plan will project different numbers than it did before. Where a figure moved, it moved because the old one was wrong. The rest of this note is what moved and why.

0.51.1: Housing in goal seekers. Home searches now protect rent, ownership costs and mortgage payments from spending cuts, as the ordinary projection already does. The same costs count toward VPW and fixed-percentage essential floors. Earlier searches could report too much affordable house by allowing cuts to housing bills. Down payments and early payoffs remain separate one-time costs; a fixed schedule without guardrails is unchanged.

The home-search help also explains the sandbox's separate inputs and the remaining differences from an ordinary projection.

The senior deduction. The 2025 to 2028 bonus deduction for filers 65 and over is $6,000 for each qualifying person, reduced by 6% of income over $75,000 ($150,000 filing jointly). The $6,000 is reduced first, and then counted once per qualifying spouse. The old calculation reduced the couple's combined $12,000 instead, so a couple kept part of the deduction well past the income where it should reach zero: at $250,000 of joint income it still deducted $6,000 where none is allowed. The amount and both thresholds are also fixed dollar figures that do not rise with inflation, which the projection now models.

A plan that cannot be run now says so. Impossible assumptions used to produce a number anyway. In one case a plan reported 100% success without ever being simulated: asking for a no-looping historical run longer than the 98-year record leaves no usable window, and a run with nothing in it read as nothing having failed. The projection now refuses the plan and names the assumption at fault, panel by panel, instead of showing a confident figure built on nothing.

Survivor years now look like survivor years. After a death the projection already taxed the household as a single filer, which is the widow's penalty. But income, expenses and the required-distribution tax column were still shown on the household's filing status, so the panels hid the effect in the years that exist to show it.

A required distribution follows the person who owns the account. Money contributed for someone with no account of their own was deposited into the first account on the list, which could be an older spouse's. That put it on their distribution schedule, up to fourteen years early.

Money that arrives partway through the first year is now measured over that part of the year, both in the wait grid's market range and when a figure is shown in future dollars.

Both sides of the income picture count the same money. The lifetime income chart stacks a year's income by source and traces what it all went to as a dashed line. It is one year of your money, so the two sides have to reconcile, and in three ways they did not. Spending your HSA settled was in the line but in no band, so if you draw $12,000 a year of qualified medical you read as $12,000 a year short, every year, in a fully funded plan; the panel's average monthly income in retirement was $1,000/mo light with it. A one-time withdrawal arrived as income and never as an expense, so a $500,000 house read as a $500,000 surplus, under a caption promising the surplus is reinvested. And the Work band paid both salaries until the older of you retired, where your plan stops a spouse's at their own retirement, and paid wages at all in plans that model no saving.

The withdrawal-rate check grades the draw that repeats. It measures your plan against the worst case an ongoing withdrawal survives, and a house bought for cash is not an ongoing withdrawal. Folding the purchase into that year's draw read a plan living on 4.0% as 54%, and turned the year red for doing exactly what the plan said. One-time spending is now set aside on both sides of the division, the same way your spending rule already sets it aside before reading your balance. It is not hidden: in the year of a purchase the check says how much was set aside and what your portfolio really paid out, and the year-by-year table has a one-time column beside the rate.

The Medicare estimate names the age it is for. If you are already past 65 you were shown this year's premium labelled "at 65". Those are not the same number, because IRMAA bills against your tax return from two years earlier. Both places that quote it now name the age they mean. Nothing changed if you are still approaching 65.

The spending check-in says which percentage it means. A share-of-the-portfolio rule was described by a single figure, your whole household budget divided by your portfolio, under a sentence calling it the rule's own share. If you had typed 4% you were told 7.4%; Bogleheads VPW read 8.4% against a published table cell of 5.0%. The difference is your Social Security, which your portfolio does not pay. The card now names both quantities, and only repeats itself when they differ: the share the rule takes, and the withdrawal rate your portfolio actually gives up. In a year a "spend at most" cap holds your budget down, it says the rule would have taken its share and gives both monthly figures, rather than naming a percentage nothing was taken at.

The spending chart shows what each cost actually did. The Lifetime spending projection stacks your spending by category, and its yearly total has always matched the plan. Its split did not: a rule that trimmed spending was drawn as trimming all of it, so rent your plan pays in full appeared cut. On a $60,000 budget with $30,000 of rent, a plan at the Balanced guardrail's floor drew the rent as $26,000, a 13.3% cut it never took, and understated the cut to everything else by the same $4,000. Only the flexible part of Recurring is ever trimmed, so that is now the only band that moves. Housing, Medical and Medicare stand at their own figures, and the stack still totals the same spending as before.

A required distribution is priced with the Social Security it drags into tax. How much of your benefit is taxable depends on your income including the distribution, so a forced withdrawal can make a benefit taxable that was not taxable without it. That is the tax torpedo, and warning you about it is much of why the required-distribution table exists. The Est. tax column used to work out your benefit's taxability first and add the distribution on top of the answer. If you are single with $24,000 of Social Security and no other income, a $30,000 distribution was shown as $1,420 of tax where the real figure is $2,056, because it pulls $11,300 of the benefit into tax with it. The same column was also missing the 2025 to 2028 deduction for filers 65 and over that the projection itself applies, which is now counted here too, on both sides of the distribution: a large enough distribution phases that deduction out as it goes.

The income picture counts the tax as well. You pay a tax bill by selling something, so it comes out of your savings like anything else. The Savings drawdown band left those withdrawals out while the dashed line across it included the tax, so any plan with federal tax on read short by its own tax bill, every year. A $1,000,000 IRA spending $60,000 showed $60,000 of income against a $65,020 line, in a year that ended exactly $65,020 lighter and fully funded. This was the fourth thing missing from that one picture; the other three are above.

The withdrawal-rate check measures one outcome at a time. Its figures are the middle of many simulated futures, and it used to take the middle figure for each account separately and add them up. Your futures disagree about which account pays for a given year, so in the year of a large purchase that could report an ongoing rate of 0.0% for a year in which every future drew its ordinary spending. Each future is now measured whole before the middle one is taken.

A bad advisor fee no longer blanks the page. Fee %/yr accepts anything, so meaning 1.00% and typing 100 put every return below -100% a year. That is not a plan anyone can simulate, and refusing it is right, but the refusal took your own plan with it: the Summary said your plan could not be simulated and removed its charts, while the cards beside it went on showing that same plan's ending wealth. The comparison line now refuses on its own, and says why beside the fee box.

Also fixed: one bad candidate year no longer speaks for a whole affordability grid, a one-time withdrawal settles in the order you scheduled it, funded spending is never drawn below zero, the AI door reports a percentage as a percentage, and a spending rule you record now survives being saved and replayed instead of coming back as an all-bond plan.

One finding is addressed only in part, on purpose. Converting a projection to future dollars now uses the right elapsed time, but doing that conversion for each simulated path rather than on the summary bands is a larger change that is still open and planned separately.

0.50: What you get to spend

0.50.1 fixes two things about that chart. Its scale was drawn from zero to well above the highest line, so on many plans the whole band sat squashed in the lower third of the picture; it now fits the numbers actually on it, and the shape you are meant to read is the shape you see. And the values under it no longer shuffle onto different lines as you move along the chart, which used to nudge the paragraph below them. A plan that runs out of money entirely still gets a chart starting at zero, because a line reaching zero is a real reading.

A plan you only ever simulate is a plan nobody follows. This release is about the number at the end of it: what your rule says you get to spend, in dollars a month, and what it says about the balances you actually have today.

The Spending strategy panel explained four rules in the engine's vocabulary before it showed a single dollar figure, and the one leading dollar figure it did show read $0 for anyone not yet retired. It now asks one question, draws the shape each answer gives your spending, leads with the money, and keeps the machinery behind a disclosure. And the rule you pick is no longer only simulated: a yearly spending check-in on your Overview runs it against your real balances and remembers what you decided.

Your portfolio file is unchanged. Nothing is upgraded and nothing is asked of you when this version opens it.

Three things will move your numbers. If your plan uses My expenses, cut back in bad years, its trigger now reads your withdrawal rather than your whole spending, so a plan with Social Security or a pension will project fewer cuts; and if that plan has years in it where it spends nothing, it will read differently for a second reason. See "The cut-back rule reads your withdrawal" and "The rule stopped deciding in years it cannot act" below; both corrections are in your favour to know about. And every plan opened after 1 January now runs this calendar year as the part of it still ahead, rather than as a whole year from today's balances. See "This year is the months still ahead" below.

Your yearly spending check-in

Name the saved plan you are actually living under, in Retirement plan's Scenario menu, and the card on your Overview runs that plan's rule against your real balances once a year.

It keeps two things apart that are easy to confuse:

  • Recorded budget is what this year's spending is. It changes only when you record a review.
  • Current signal is what today's balances imply. It moves when the market moves.

They agree on the day you record and drift after it, and that is not a fault: a rule that re-cut your budget every time the market dipped would be a rule you could not live on. Recording is what changes your budget.

Before you retire the card states your plan's own first year, labelled as the plan rather than as a forecast. Under Spend a share of my portfolio it says plainly that your first year depends on a balance nobody has yet, rather than inventing a figure.

Your recorded budget carries into the projection. A household living at 81% of its plan no longer sees the chart restart at 100% every time it is re-run, and the Spending strategy panel says where its own numbers begin.

Three things worth knowing before you start. Miss a year or three and you get one late review, taken from your last recorded state, rather than every skipped cut applied at once. Editing the rule's thresholds keeps your recorded budget: moving a threshold never hands back spending the rule already trimmed. And Restart this rule is the only action that puts you back at the plan as typed.

The panel asks one question

Each year in retirement, what do I spend? Three answers, not four choices, naming what you typed in: My expenses, as entered · My expenses, cut back in bad years · A share of my portfolio. They stopped saying "plan" because the screen never showed you one: the Expenses section holds Recurring, Housing, Health coverage and One-time expenses, so "my spending plan" pointed at something you had to invent. The fixed-percentage rule is a setting inside the third answer rather than a button of its own. No saved plan needed migrating, and nothing stored changed: an existing plan opens on the choice that reproduces the run it already had, and every previous label still finds it in Help's search.

A picture of what each one does. Under the picker, a band chart of planned spending against the expenses you entered: flat under the first answer, flat with dips under the second, following your balance under the third. It is drawn before the Medicare premium, which is charged on top of every rule alike, so an answer that adjusts nothing draws a flat line exactly on your entered expenses instead of one lifted above them by a health cost.

And a line for what the bad outcome actually got. Everything else the chart draws is a planned amount: the bands keep asking for your entered expenses after the portfolio has run out, which made the answer that fails look steadier than the answer that holds. The line marked 1 in 10, as funded is what the tenth-percentile outcome had to live on once the shortfall is taken off, and it levels out at whatever guaranteed income you have. On a plan that never runs short it lies on the band and you will not see it. Its end value and the median's are printed at the right edge.

The three answers are cards you can compare. Each carries that same picture in miniature and its own chance all obligations are funded, so you can see what the other two would do without switching to them and back. The two you have not picked are run at a fraction of the paths, after the main projection and without holding the page up; the tiles below always describe the answer you picked.

Every figure is monthly, with the annual figure beside it, because a month is the unit a household budgets in. The projection itself is still calculated annually, and the panel says so once.

The presets are named for what they protect. "Conservative" cut sooner and deeper, because what it protects is the portfolio, while a conservative person expects their spending protected. They read Cuts sooner, deeper · Balanced · Cuts later, less now, each with the monthly floor it implies for your own budget. Only the labels moved.

"Does this rule ever actually fire for me?" Under either adaptive answer the panel says so in a sentence: the share of outcomes in which spending is ever reduced, and the age the first reduction typically lands, counted only among the outcomes that reduced. A median taken over every outcome would name an age nothing happened at, and a share too small to print says so rather than rounding itself to 0%.

What the rule is allowed to take off. Beside the flexible-portion field, most this rule can reduce: your flexible portion stopped at its floor under the cut-back rule, or the whole flexible portion under a share rule, which has no floor of its own. That is what the rule permits; the tile above is what the simulation did. The field also names its own denominator now, and sits in Explore's comparison for a household on the first answer, where it is the assumption the cut-back row is priced from.

The rule stopped deciding in years it cannot act

The guardrail ran its test every simulated year, including the years before you retire. In those years your plan draws nothing, so the rule read a zero withdrawal as enormous headroom and raised your budget. Every year. Until it hit its ceiling.

A household five years from retirement therefore started retirement about 20% above the plan it had typed in, under a rule labelled "trimmed in bad years".

The rule now checks whether it has anything to trim before it decides anything, which also catches a deliberate $0 spending year inside retirement. If your plan uses this rule and has non-spending years in it, its projected figures will have moved. A plan already in retirement, and any plan not using the guardrail, is unaffected.

The panel also now asks its question out loud, instead of naming a "plan" it had never established.

The cut-back rule reads your withdrawal, not your spending

My expenses, cut back in bad years decides by a withdrawal rate, and that rate used to divide your whole budget by the portfolio. Social Security and pensions were counted against you: a household whose portfolio supplied 3.9% of its balance read 6.7%, cut on day one, and stayed cut for thirty years, while A share of my portfolio, which has always put income beneath the draw, spent $14,000 a year more at a higher success rate.

The rate is now what the portfolio actually supplies: this year's budget less guaranteed income, over the balance. That is the rule's own definition and the same money the projection then draws. If your cut-back plan has Social Security or a pension, it will project fewer cuts than before, and possibly none; a plan without guaranteed income reads exactly as it did. The check-in shows the same rate and names it.

The cut-back rule's rates can rise with age

A withdrawal rate that is dangerous at 65 is ordinary at 82: 5.9% with eighteen years left is well inside what the withdrawal-rate check calls safe, yet a fixed 5.5% cut rate trimmed the median path in its late seventies while A share of my portfolio, which amortizes, kept spending to 93. A new Rates rise with age setting under Adjust the rule scales the cut and raise rates as the years left shrink, on the check's own curve; the rates you enter describe your first spending year. It is on for a new plan. A saved plan keeps its fixed rates until you tick the box, so nothing moves without you, and the check-in shows the rates in force at your age.

Money already spoken for is set aside first

A one-time expense your plan commits this year (a house bought for cash, a car) is now set aside before either adaptive rule reads your balance. Spend a share of my portfolio used to prescribe a share of money that was leaving for the house the same year, so the first year read about twice the size of every year after it; the guardrail's rate had the same money as a cushion under it. If your plan has a one-time expense in a year it also runs one of those rules, its projected figures will have moved. The check-in says how much was set aside when it happens. A fixed plan, and any year without a one-time expense, is unaffected.

The spending tiles say on hover what they measure: the first is household spending with guaranteed income counted toward it, so the withdrawal behind it is smaller; the second is a downside estimate rather than a limit.

This year is the months still ahead

The projection runs one year at a time from the balances you have today, and until now it ran the whole of the current year from them: a plan opened in September drew twelve months of spending from a balance that had already paid eight of them, and grew that balance for twelve months with four left. So a plan read a little worse every month for no change in your household, and snapped back on 1 January.

It now simulates this year as the part still ahead, and Assumptions says so beside the horizon: the 4 months still ahead in 2026. Recurring spending, guaranteed income, savings, Medicare, required minimum distributions and this year's growth are taken for the fraction of the year remaining. A one-time expense, a windfall, a Roth conversion or a home purchase dated this year happens once and in full. The tax year stays whole: brackets, the Social Security worksheet, the ACA cliff and the IRMAA lookback see the year's income at its full-year rate, so a large IRA withdrawal in December is taxed at the rate it will actually face rather than as if it were the year's only income. Every spending rule decides on annual figures, so a short first year never reads as a low withdrawal rate.

Every figure the page shows for this year is still a whole-year figure. The year-by-year table, the charts, the withdrawal-rate check and the RMD table read this year at its annual rate, and this year's tax as the bill for the whole tax year. Only the cash that actually moves is the remaining share, which is why the balance changes by less than a full year's flows, and why lifetime totals count only that share of this year.

On one real household with a $1.07M cash purchase ahead, the change lifted success by one to three points and moved the spending a 90% target allows by about $2,500 a year, mostly because the months already paid for no longer come out of the money that funds the house. If you opened your plan on any day but 1 January, its figures will have moved.

A one-time expense can say which month

Without a month, a one-time expense left on 1 January of its year and gave up the whole year's growth on that money: about 3% of a large purchase dated October. Each row in One-time expenses, and the Housing panel's purchase, now has a Month. Dated, the lump is drawn at that month from what each account in the draw order has grown to by then, and an account it empties ends the year at zero rather than below it. The tax, the draw order and the cut-back rule's set-aside treat it as the same lump either way, because the tax year is whole. Blank still means the start of the year, so nothing changes until you pick one.

A row dated a month that has already passed this year is still counted, drawn now, and so is a home purchase dated that way: the plan never assumes a lump was paid just because its month went by, since a purchase that slipped a month would otherwise vanish and your success rate would jump. The panel marks the row month has passed. Delete it once the money has actually left, because your balances already reflect it; move its month if it has not happened yet.

A ceiling for the share-of-portfolio rules

A share of my portfolio used to spend whatever the rule prescribed. With $83,000 of entered expenses and a strong market that meant a household modelled spending $116,000 a year and paying the IRA tax on the difference, a household nobody is. Both balance rules now take Spend at most: your entered expenses plus an offset, in percent or dollars a year, with the monthly figure it implies beside the field. Whatever the rule would have allowed above the cap is not withdrawn; it stays invested, untaxed. Below the cap the rule governs as before, so a bad decade still cuts. A plan saved before this existed loads with no cap and its numbers do not move; a new plan starts at 0, never more than your expenses. The check-in applies the same cap.

When your plan gets past the risky years

Every plan is most exposed in its first retirement years, and the fan chart could only show it by widening. Under the fan, one sentence and one line now say it in your plan's own numbers: for each age, the share of outcomes that reach it still solvent and holding at least the typical balance, and go on to fund everything. Reach 72 with at least the typical balance and 97% of those outcomes fund everything. Today: 93%.

It is a conditional and never a promise, and it is not next year's re-run: it is today's statement of how confidence should evolve if the years go typically. Nothing forces it to only rise, and a late cost can dip it. Explore's spending-strategy comparison gains the same statistic as a column, read at one age for every rule, which is where the adaptive rules' steadier early years sit beside the reduction that bought them. Under the Historical replay lens the pool is too thin to read to a point, and it says so instead of quoting a number.

And your own place on that curve. Name a plan as the one you follow and the app freezes the balance track it expected: what a typical outcome held at each age. Your spending check-in then says where you stand against it ("At 72 this plan expected a typical $2.0M; you have $2.1M"), and names the age the track was drawn at. It is frozen deliberately: a track redrawn today starts from the balance you have today, so it could only tell you that you are exactly where you are. Following the plan again is what redraws it.

The card places you and names no percentage. The chance your plan funds everything is a live number, and it stays on Retirement plan where it is worked out from the plan as it stands now.

Nothing about your plan changed. It is one more reading of the run you already had. See confidence by age.

Two facts, two names

The lean-year tile is gone. One tile reported two different things and showed whichever was lower: how much the rule chose to take off in a bad year, and how much your portfolio could not pay. Once enough outcomes run short the first disappears behind the second, and under an answer that never adjusts there is no first at all. On one real household it read the same $3,877/mo under both the fixed answer and the cut-back one, which was that household's Social Security: a lean-year figure for a strategy that has no lean year.

In its place, two lines that never blend. Reduction below entered expenses is the largest one-year cut the rule itself chose, at the level one outcome in ten reaches. It is absent entirely under My expenses, as entered, which makes none. A separate sentence says in how many outcomes some expenses went unfunded, and when the first shortfall typically lands. Not "the money runs out": an outcome counts the first year it cannot pay any one of five obligations, so a plan can fail on a tax bill with every year's groceries paid. The funded lean-year figure keeps its name in Explore's Details, now with how far below the amount the rule planned it landed.

Both dollar figures carry their denominator. Reduction below entered expenses states the same amount as a share of your Recurring expenses, which is the slice both adaptive answers actually move. "Is that a lot?" was the question those figures used to leave to you.

No spending figure is $0 before you retire. Every spending statistic is measured over your retirement years only. A working year in which the plan spends nothing is not a lean year; a deliberate $0 year inside retirement still is.

Prescribed and funded are reported separately. What a rule asked for and what your portfolio delivered are different numbers in a bad run, and the unfunded part is split by what went unfunded: recurring spending, a one-time purchase, tax, an HSA penalty, a lost health subsidy. A car you could not buy no longer makes your grocery figure look worse.

Spending a share of your portfolio no longer claims the money cannot run out. Your essential spending is paid even when the rule's own percentage falls below it, and taxes come out on top, so the portfolio can still be exhausted. That is the intended trade rather than a defect. The label simply no longer denies it.

0.49: Planning for the people who are actually there

A plan is about particular people, and this release is about the app knowing who they are. Guided setup now asks for the facts the projection cannot work without: every person's birth year and month, and a price source that can actually fetch. It no longer lets you walk past them into wrong numbers. Retirement plan refuses to run on a household it cannot age. Health coverage before 65 is modeled per person instead of per household, which moves real money for couples in both directions. And the guided wizard and your Household profile stop giving two different answers about the same three facts.

Your portfolio file is unchanged. Nothing is upgraded and nothing is asked of you when this version opens it.

0.49.3: Help got a careful edit

Every built-in Help topic has had a sentence-by-sentence line edit. Titles, headings, lists, notes, and release history now use more natural punctuation throughout. The meaning has not changed: calculations, technical claims, links, search terms, and task instructions remain intact. A source check now keeps future Help updates aligned with the same rule.

Nothing about your portfolio or the way the app works changed in this patch.

0.49.2: backups know which database they belong to

The Files page's Backups list mixed every database's snapshots together with no label. Retention has always been per database. Exploring a sample portfolio never rotates out your real portfolio's backups. The list didn't say so, and a keep-count next to a longer, unlabeled list looked broken. The active database's backups now lead the list; other databases' snapshots sit behind a collapsed section, grouped and still restorable or deletable individually. The Files page's other multi-part sections (the database path, the sample-portfolio grid, Start Fresh) also got a layout fix. They had been sharing a row with their buttons instead of stacking.

0.49.1: the demo households finished their profiles

The sample portfolios that ship with the app were advertising an unfinished profile. This release counts a spouse's birth month as a Household profile refinement, and none of the built-in demo households had one, so every demo couple opened with its completeness ring stuck short of full, on exactly the screens meant to show the app in good order. The generated households now state a spouse's birth month outright.

Nothing in the app behaves differently, and a household you created yourself was never affected. This changed only the demo data bundled with the app.

Setup asks for what the plan needs

Every person needs a birth year and a birth month. A spouse without a birth year used to sail straight through setup, and the cost was invisible: their tax-deferred balance landed in a group the app read as roughly 2,000 years old, so required distributions forced nearly the whole balance out as taxable income in the first projected year, and survivorship silently switched itself off. Both setup routes now require every person present.

The Price data step resolves to a configuration that can actually fetch. Choose Yahoo, or enter a Tiingo key inline. Continue stays disabled until the resolved choice is proved. A Tiingo key is tested against the live service before you can move on, because a saved key can be revoked and being non-blank is not evidence that it works. Skip for now writes nothing at all, and says so. Before this, finishing setup on an unusable price source produced no error anywhere: your funds simply never got prices.

Leaving early leaves a reminder. The Finish setting up checklist opens with a Tell us about you row, and it now survives an exit with no accounts on file, including from the Stress-test my retirement route, which never recorded one. An established portfolio is still never nagged.

Retirement plan blocks with a setup gate instead of reporting a number it cannot stand behind. When a birth year is missing the page names whose and offers to fix it. The calculation behind it, including the one the AI assistant uses, stops with a message naming the account rather than answering with wrong figures.

The example preview is one household

"Preview with an example" now substitutes a whole household, not a coat of paint. It only ever replaced the age, the balances and the spending. Every other fact a Household profile supplies still came from your real household and was placed on a 35-year-old's clock: Social Security amount and claim age, filing status, state rate, taxable gain, housing, pre-65 health, pensions, survivorship. So the same button reported 66.9% success to the empty-profile tester it was built for and 100.0% to a 58-year-old already collecting. That was a success rate assembled from two households, which describes neither.

The example is now one person defined in one place: a 35-year-old single filer with $150,000 saved across three account types, putting away $18,000 a year to 65 and spending $48,000 a year after. The plan is calibrated so its own withdrawal rate reads comfortably inside the green band, because a sample plan its own gauge flags teaches the wrong thing on arrival. Its Social Security benefit is worked out from the published bend points rather than written down as a number that could quietly go stale.

Knobs you type on the Retirement plan page itself, including windfalls, one-time withdrawals, the benefit-cut stress, and return and allocation assumptions, stay live and land on the example's clock. Anything the example cannot express is switched off rather than run on borrowed numbers, and every readout on the page states what the run actually used.

Health coverage, per person

The pre-65 premium and subsidy divide between you. The household's stated figures now split into equal per-person shares, each ending on that person's own 65th birthday and prorated by their own birth month. Before this, the whole pre-65 health cost was gated on the primary's age, which was wrong in both directions: the younger spouse's premium vanished at the older one's 65; with the older spouse listed second, the household paid a full couple premium past that person's 65 while also being charged their Medicare premium. The sharpest way to see it: in an otherwise identical plan, the same couple cost $120,000 or $168,000 depending only on which of them the Household profile called "primary."

The subsidy cliff is still tested on the whole household's income, because that is how the ACA actually works, and the survivor carries their own share on their own clock. The even split is a simplification worth stating: a real family premium is the age-rated sum of its members', and the figure being divided is one blended number you typed.

A single filer's last marketplace year is billed on one clock. The premium used to stop dead on the 65th birthday while the lost-subsidy risk was prorated across the year. Anyone born February to December was therefore modeled as paying none of their final year's premium while still risking part of that year's subsidy. Both now share one enrolled fraction.

When a spouse starts Medicare is read from your Household profile, not from a planning knob. Enrolment keyed off the scenario's spouse-age slider, a savings what-if, while the 65-and-over deduction and the marketplace transition read the Household profile. The same person could leave the marketplace on one clock and start Medicare on another. Identity reads identity now; a spouse modeled as 50 for a contribution what-if still contributes on that clock. A saved scenario whose spouse-age knob was edited away from your Household profile will see its spouse-Medicare timing move. That is the correction. Scenarios you never edited are unaffected.

Filing jointly with nobody on file no longer prices a person who may not exist. It used to invent a second Part B, Part D and IRMAA premium from a guessed "your age minus two." There is nothing to enrol now, and the app asks you to add the person in your Household profile.

The wizard and the Household profile agree

One fieldset, one verdict. Guided setup's About you step and Household profile → Household ask for the same three facts about the same people, and until now they had two of everything, including two different answers about the same input. The wizard refused to continue on a birth year it could not store; the Household profile accepted the save, wrote nothing, closed the panel, and left the Retirement plan gated with nothing on screen to say why the year you had just typed was gone. They are one fieldset and one rule now, which reports a field filled in wrong and stays quiet about a field left blank. What they still ask for differs on purpose: the wizard wants a birth month while you are already answering birth questions, and the Household profile treats it as suggested.

Re-entering the About step no longer overwrites your filing status. The step guessed at it from whether a spouse was present and saved that guess every time. The retirement route sends an incomplete profile back through it. It reads your stored household now. The one case it still overrides is married filing jointly with nobody on file to be joint with, which is a default nobody has answered rather than an answer.

Finishing an account inside guided setup shows one success screen. "Account created" was followed one click later by "Account set up" saying the same thing under its own green banner. That screen is the question it always was: Add another account? It has its two choices in the footer like every other step, and the two differently-worded buttons that both ended setup are now one.

A % no longer sits alone on the line below its input, in six places across the Household profile, under Taxes, Income, and Housing & health.

0.48: The numbers, checked against their sources

0.48.1: a smaller download. Every build on the release machine had been leaving its compiled main-process bundle behind under a new name, and the macOS installer packed all of them. Around 110 MB of the disk image was code no version of the app can load. The build clears that directory now, so 0.48.1 is about a third smaller. Nothing else differs from 0.48.0: same application, same data, same behaviour. Windows and Linux installers were never affected.

This release is about numbers being right rather than about anything new to look at. Every published tax and Medicare figure the planner works from was refreshed to 2026 and read off its primary source. A run of defects on the money path, including a sale taxed by the wrong rules, a stock split your holdings never picked up, a portfolio the backtest sold to cash, a mortgage payoff counted in the wrong dollars, were found and fixed. Two import defects that silently doubled things were reproduced against real broker exports and closed.

Opening this version upgrades your portfolio file if it was last opened on the 0.47 line. It is immediate, measured at 12 milliseconds on a 1.1 GB file holding 11.6 million price rows, and it happens once, the first time this version opens the file. Nothing is asked of you.

The 2026 figures

Every year-pinned number is now 2026, and each one names the document it came from. Federal brackets and the standard deduction ($16,100 single / $32,200 married filing jointly), the 65-and-over bonus deduction, the IRMAA income floors, Medicare Part B at $202.90, the 401(k) limit at $24,500 with an $8,000 age-50 catch-up, HSA limits at $4,400 and $8,750, the Social Security wage base at $184,500 and the benefit bend points. Two of them were wrong rather than merely a year old: the Part D premium was an unsourceable $46.50 that matches no published figure, and the topmost IRMAA tier used "greater than" where the rule says "greater than or equal to", so an income landing exactly on the threshold was placed a tier too low. Expect your Retirement plan to move: across the bundled samples, median lifetime tax falls and median spending rises, while the modeled success rate slips a few tenths of a point for households closest to Medicare. That last change reflects Part B at $202.90 against the old $185.00.

Contribution limits are now evaluated at each age the plan reaches, not once at your age today. Someone aged 61 kept the ages 60–63 catch-up at 64 and beyond; someone aged 53 never gained the age-55 HSA catch-up.

The money path

A sale inside a tax-sheltered account was taxed as though it were in a brokerage account. Rebalance Planner and the withdrawal orders estimated capital-gains tax from the lots of any account whose type they did not recognise as sheltered, and flagged wash sales and harvesting opportunities inside IRAs, Roths and HSAs where neither idea exists. The account's wrapper decides now. Where the tax genuinely cannot be known, as with a position whose lots are only partly imported, the estimate is blank rather than quoting the tax on the covered fraction as a firm number. And an HSA is the last account a withdrawal draws from, not the first: it used to sort ahead of taxable and tax-deferred money.

A stock split after your last statement showed a fraction of the position you hold. For an account tracked by statement rather than by transactions, stated share counts were priced without applying any split since. A 10:1 split after the last snapshot showed a tenth of the position in Holdings, in your allocation, in Rebalance Planner's drift and in the projection's starting balance, while the value chart beside them showed it correctly, because it used the other of two code paths. There is one path now.

Rebalance Planner ordered the difference twice for a fund named twice in one slice. Each line produced its own order, and each order covered the account's whole holding of that fund: $60,000 of a fund a slice listed twice came back as two "Reduce $42,000" orders: $84,000 of sales against $60,000 of stock. That total doubled again in the summary and the tax estimate. One fund is one row, one order and one stored line now, and models already carrying a doubled fund are repaired when the file upgrades.

A statement account's return was overstated whenever money went in. The time-weighted return assumed a deposit earned nothing for the whole period it landed in, while the value it grew into was still counted at the end. A book that doubled through a +10% market therefore read as +20%. A statement gives a period total and no dates, so a period's flow is now weighted at its midpoint. Separately, an account whose value reached zero with no matching withdrawal was skipped as if nothing had happened; that is a real −100%, and it is reported.

An early mortgage payoff was too large, by a growing amount. The recurring principal and interest were converted into today's dollars and the payoff balance was not, so one loan was carried in two different bases. The payoff was overstated by inflation compounded across the years between writing the note and clearing it, about 34% at 3% over ten years. The payoff-year explorer and the one-time expenses panel showed that same overstated figure under captions reading "today's dollars"; both now show what the projection actually draws.

A rebalance date the backtest could not price sold the whole portfolio to cash. If no fund in the model had a quote that day, every position was cleared and could not be refilled. A gap in our price data became a liquidation, and a single-fund comparison could score at −100%. The rebalance is skipped now, and the previous allocation rides through.

Two imports that doubled things

Re-downloading a broker export imported the same trades a second time. A broker that leaves the settlement date blank makes this app derive the trade date from the cash movement that funded it, then fills that column in months later, when settlement posts. The two exports describe one purchase with two different dates, and nothing matched them: on a real pair of Fidelity exports covering the same period, eleven Treasury-bill purchases imported twice, doubling both the shares and the cost basis. A derived date is recorded as derived now, and a row carrying one matches a firm date a few days away, while trades genuinely made days apart still import as two trades. Rows imported by earlier versions carry no such mark and are not guessed at; re-importing the export that created them teaches the app which ones they were.

Undoing an import could delete rows a later import also reported and take a holding off the page entirely. Only the run that first created a row was recorded, so undoing an earlier overlapping export removed rows a later, still-applied export also covered; and because a holding disappears once its shares net to zero, deleting an opening purchase while a later sale survived did not shrink the position, it removed the fund from Holdings. An import now records what it re-reported as well as what it created, and undo removes only what nothing else stands behind. Import history says when a run shares rows with another, and Undo names what it will actually delete. Imports made before this version carry no such record; their undo behaves as it did, and the app tells you so rather than guessing.

An import also lists every line the file did not turn into a transaction, by reason and line number. Two of those drops used to be completely silent, and one mattered: a Fidelity export re-saved from a spreadsheet quotes its header, which the parser did not recognise, so the file imported as zero rows and reported no problem at all. A recognised broker file with no usable header is refused in words now.

Research and prices

Allocation models' Backtest tab says when a holding it priced is not really priced, and Optimize shows when each candidate was last priced. A fund whose record simply stops used to be carried at its last close forever. Units you already hold are still valued there, but fifteen days after the last real close the fund stops attracting new money at a rebalance, and it is named. A fund whose quotes ran out is no longer shortlisted at all. A dead fund used to look like a winner under "Limit downside", because a flat stretch of stale price contains no drawdown and no volatility.

A Screener calendar year the fund's record does not reach is blank instead of wrong. A fund whose prices stopped in June still reported a full-year return for that year, using its January-to-June move against an index's whole year, and a flat 0.00% for every year after. Four more figures behind the scores were computed from data that was not there: the optimizer's consistency measure compared a half year against a full one, the "history" factor read the length of the risk window rather than the length of the fund's record, the concentration measure penalised patterns that are ordinary for the number of years being measured, and a candidate could be scored on fewer measures than the fund it was challenging.

The Screener's scoring settings now belong to the portfolio, not to the computer. About twenty-five knobs lived in this machine's browser storage, which meant a backup did not carry them, a restore on a new laptop scored with factory defaults, and a bundled sample was scored with your personal weights. Anything you had tuned is carried across the first time your own portfolio opens.

A split or a price you entered by hand can no longer be taken back by a download. A manual split used to replace whatever row held that date, irrecoverably destroying a provider's or a detected split. A blocked date is now reported by name instead of the dialog closing over a list that did not fully save. A price you typed with a statement survives a price-history rebuild from this version forward. The mark that protects it is new, so a price typed by an earlier version does not carry one and a rebuild can still replace it. Rebuilding one ticker from Tiingo is a single atomic replacement, so an interrupted rebuild cannot leave a fund with no prices at all. Cleaning up unused tickers keeps the price history of positions you closed, which the value and return charts still read.

Everywhere else

The last thing you clicked is the thing the app keeps. A settings toggle switched off before its switch-on finished saving compared itself against a value that had not moved yet, decided there was nothing to do, and left the earlier state in the database. Settings writes are queued per setting now, and a refused write rolls the screen back instead of leaving it ahead of what was stored.

Settings fields say when an entry cannot be used, instead of quietly doing nothing. Clearing Equity drawdown band, Reserve floor or Assumed inflation used to save a real zero, which left the Rebalance Planner banner permanently claiming equities were down. Project to age is bounded to an age above yours and no higher than 120: a mistyped horizon used to be saved and then freeze the Planning page on every visit. And a saved plan whose stored settings are damaged now opens on defaults rather than dropping the page to its error screen.

A dialog left open on one page no longer hangs over the page you moved to, the Holdings ledger no longer goes stale after an import or undo done elsewhere, and removing a spending phase, one-time withdrawal or conversion phase no longer moves your cursor into the row below it.

A matured bill or CD is its own state on Fixed Income, labelled with a Reconcile action instead of "Hold to maturity." The same is true for one whose maturity date cannot be read, which used to come back as "matures today" and count toward your near-term reserve. A ladder's income card leads with what the ladder settles into rather than with its ramp-up year.

The Overview built the same reading of your portfolio three times and now builds it once, which on a large book is seconds off every visit. Backups no longer overwrite each other, no longer write a near-identical copy every time the app is reopened from the dock, and no longer prune to a guessed retention count when the settings file cannot be read; the check that decides whether a file is an existing portfolio stopped reading "I could not open that" as "there is nothing there".

0.47: Every model at a glance, one model in full

A target model is the shape your accounts rebalance toward, and the page that holds them asked you to scroll a library to find one and then click twice more to reach a ticker inside it. The 0.47 line rebuilds it end to end: every model you own on one comparable table, and one model at a time built full width.

0.47.1: a percentage reads as a percentage. A model built from your holdings rounds each slice to a tenth of a percent, and the arithmetic that did it stored values like 4.1000000000000005 where it meant 4.1. The editor printed every digit. Derived models now record the number the rounding meant, and percentage fields show the value instead of the way a computer happens to store it. Anything saved by an earlier version displays correctly and is tidied the next time you save that model. The difference was never large enough to move a target, an order, or a model's completeness.

Allocation models now opens on a table of every model you own. Each row draws its allocation on the same 0–100% track, so shapes compare straight down the column, beside its stock/bond split, its allocation status and total, the version in force, the accounts pointing at it and its rebalance schedule. Sort by model, status or use. Search finds a model by its name, by any ticker inside it, or by any account assigned to it. Filter chips count All / In use / Available / Needs review, and under All nothing is hidden. The groups the old list stacked models under became those counted filters: what were Household models and Ready library now read In use and Available. The library table that used to sit below the editor is gone, and so is the inert 1 → 2 → 3 strip that never advanced.

Open a row and that model is built full width, with its funds inside the slice they fill. Open a slice and you are already editing it. There is no third column, no separate fund pane, no clicking twice to reach a ticker. Every percentage is editable where you read it, collapsed or expanded: a slice's share of the model in its row, and each fund's share of that slice on its own line, with what that comes to across the whole model computed beside it. A slice filled by one fund is simply locked at 100%. The Simple / Advanced toggle is gone with the column it was hiding. Every control the Advanced face had is now just there. (Setting up a new account is unchanged: its guided model step still leads with the simple version.)

The allocation is drawn as a ring, and it never rounds itself up. A model that only adds up to 92% shows the missing 8% as a grey gap instead of stretching its wedges to look finished. It needs no legend beside it. The slice list below names every wedge, in the same order, with the same percentage.

One header says what matters and stops there. Who the model is, which version your edits land in, and what it looks like sit side by side across a single band: the name with a Valid · 100% chip or an amber Review · 97% chip that moves as you edit rather than describing what was last saved, two quiet lines naming who follows the model and how often it rebalances, the version control, and the allocation ring. Then the slices, straight away. Where the page names accounts it now links to Accounts, where a target or reference assignment is actually changed, instead of leaving you to go find them.

A model's versions are one pull-down, not a disclosure you had to know to open. The control says which version your edits save into and what it is: ✓ Effective today, Scheduled with a 2026-09-30 start, or Historical and read-only. Open it and the whole history is there, newest first, scheduled versions above the one in force and a History divider above the past ones; a quarterly cadence builds up twenty-odd versions in two years and they all fit. Rename, redate and delete sit in a beside the control, acting on the version shown. Add version starts from your most recent one by default and says what that carries before you commit (10 slices · 10 funds carried over), because a version records what changed. And when the version you are editing is not the one your accounts follow, the page says so and names the one they do.

A past version now opens read-only. Its weights are what backtests replay from that date, so the page no longer warns you about editing it and then lets you: the percentages and tickers are simply shut, while everything stays legible to read. One action, Correct this version, unlocks that one version when a recorded number really is wrong. It says plainly that saving will rewrite backtest history. Scheduled versions open editable; they haven't happened yet.

Edits are one decision. Change as many slices and funds as you like; the bar at the foot of the page counts what differs and Save model changes commits all of it at once, so your model is never briefly stuck at 92% halfway through. Discard puts everything back. Leaving for another page and returning finds your work still there; switching to a different model or version asks first. An unfinished model saves, too. Slices that don't add up to 100% yet, or a slice with no funds in it, no longer stop you. The model simply reads Review until you finish it.

Everything rare moved into a details card beside the slice: its name, the category the Screener matches funds against, its classification, each fund's reference symbol, its notes and its type. Everything about a slice except its percentages, in other words. Those stay in the list. The list slides over to make room rather than being covered, so an open card never hides the running total it is being judged against, and a quiet line under a slice's funds says what the card holds.

"Backtest reference" is now "Reference symbol." The field's first job is to say what a slice is modeled on, such as the advisor-only fund you hold a public equivalent of. Standing in for it in a backtest is what that fact then gets used for. Naming it after the use hid the fact. Searching help for the old name still finds the topic.

A slice can carry notes. If you have been keeping models a while, some of yours are already in there. The field has existed in the database for a long time and nothing has ever shown it, so notes saved by older versions of the app have been sitting unread. Open a slice's details card and they are there, editable, alongside everything else about it. Nothing in the app computes from a note.

You can also say what kind of thing a slice is. Every slice is one of three: Fund-based, the ordinary kind, whose named funds become rebalancing trades by ticker; a T-bill/CD ladder, which counts every Treasury and CD you hold and keeps working as rungs mature and roll; or Self-directed, a target size filled by your own picks, tracked in aggregate so nothing tells you to trim a winner to top up a laggard. The last two already existed. A model derived from an account holding individual stocks has always produced one, but nothing in the editor could create, change or undo them. Now the details card asks, in three lines that each say what the kind means, and says what changing it costs.

The Screener asks the comparison question first: All funds, or Funds for a slice. Model, slice and universe appear only in slice mode, which opens on a real slice, so the universe choices are never a greyed-out decoration. The universes now say what they contain: Saved funds · currently fill this slice, Same category · alternatives that fit, and All funds · no restriction. The shortlist also states whether Classic score across the whole universe or Peer score within one category ordered it, with Scoring rules one click away for whichever score is doing the ranking.

The app is easier to get around, and says where you are. While a sample is open the topbar chip reads Sample: {name} in gold, with Back to my portfolio and Switch sample… in its menu. Until now it said "Local portfolio" the whole time a demo household's numbers were on screen. The command palette (⌘K) carries the actions the shell has no room for: load any bundled sample by name, Back to my portfolio, Back up now, Retirement plan scenarios… and Check for updates. Files & backups can be linked to by section, so Sample portfolios and Backups are one click from a menu, a command or a pasted link. A "Just exploring?" prompt on the Overview offers the samples to anyone who has not added an account yet. And every sample's card is now checked against the database it opens. The models it names, the age and balance it quotes and the features it advertises are verified against the shipped sample, so a card and its household cannot drift apart.

"Sample scenarios" are now "Sample portfolios." A scenario goes back to meaning one saved set of retirement assumptions inside whatever portfolio is open; a sample portfolio is a whole demo household. Old searches for the former name still find the topic, and Retirement plan's control now reads Scenario: {name}, so a loaded plan's name is not mistaken for a heading.

Retirement plan's three return models are named for what they answer, not for their distributions: Forward · Baseline, Forward · Fat tails and Historical replay. The names appear in the plan strip, the model cards, the Assumptions legend, the affordability table and the settings line under it. The Tail df (Student-t) control keeps its technical name, help still finds the methodology under the old names, and no projected number changed.

Fixed. Allocation models' Backtest tab's list cut off the part of a model's name that identified it. Names in a family share a long prefix and differ only at the tail, so a sample's list read as several checkboxes beside one name; they wrap to two lines now. The Screener's universe labels no longer spill across their neighbours or clip at the panel edge on smaller windows. And the Screener could be left in Funds for a slice with nothing to show after the last target model was deleted from another page; it now falls back to All funds and restores your choice when a model comes back.

0.46: Decisions first, details when you need them

The 0.46 line puts decisions and recovery paths ahead of setup detail while keeping the app's local-data and read-only boundaries explicit.

0.46.4: explore one coherent household at a time. Files & backups now offers four editable life-stage samples: Early career, Mid career, Near retirement, and In retirement, plus a separate Federal employee · TSP specialty sample after onboarding. Each opens a working copy, so exploring models, scenarios, contributions, withdrawals, and rebalancing never replaces your own portfolio. The retirement sample includes a 15-rung Treasury ladder inside its rollover IRA; the federal sample uses periodic snapshots and clearly labels its generated history.

The first-launch and browser-preview portfolio is now the age-63/61 near-retirement household. Its accounts, target and reference models, saved no-conversion and bracket-fill scenarios, comparison-fund research, and tax-lot history tell one consistent story across Overview, Retirement plan, Screener, and Optimize. Generated dates share one fixed boundary, so model timing, research windows, withdrawal reserves, and tax-lot age do not change merely because you open the sample later.

Reserved TSP:* funds are locked to the official TSP price-history lane. Securities & prices explains that routing and cannot redirect those symbols to Yahoo Finance, Tiingo, or local $1 history, even if an older database contains stale source settings.

0.46.3: account setup starts with facts you can verify. Add account is now a consistent three-step flow: identify the account, choose its starting data, then review everything before it is created. You can add the real institution name from the statement without claiming the app has a connection or importer for it. Brokerage accounts can be registered Joint when both Household profile people exist; retirement, HSA, and 529 accounts remain individually owned.

The cash question now asks for the current core cash vehicle on the latest statement, not one the account used years ago. Choose a known vehicle, add another money-market fund inline, select a regular cash balance, or say you are not sure yet. If an import detects a former vehicle and change date, it presents that history for review rather than changing the account silently. Once confirmed, every dated vehicle remains part of one core-cash pool, so the transition is not mistaken for new money or a trade and later activity on the former vehicle still reconciles.

Starting data is explicit too: import complete history, enter an opening statement, use periodic snapshots, or create the account with no data yet. Complete history may start at exactly $0; a deliberate zero now counts as real opening information. Review is the only save point, so an error cannot leave behind half an account, and target-model guidance waits until the new account exists.

0.46.1–0.46.2: charts can show the per-year rate. The chart above the tearsheet gained a third y-axis mode beside $ and %: %/yr draws the annualized return at every date rather than only at the end, so a model that won on one early stretch shows its lead decaying toward the pack instead of looking permanent. Its final point is the CAGR the table reports. A partial year is never annualized. Three months of +8% is not +36%/yr, so that curve starts a year into the window. The toggle disables itself, with its reason, on any shorter window. The drawdown track underneath is unchanged: it still measures real declines from the true window start. The vs benchmark picker also gained an Edit link that opens whichever list feeds your current pick: your models on Allocation models, or the comparison-ticker list (now its own shared editor, reachable from either chart's "vs" menu).

In 0.46.2 the Overview's Portfolio Value chart gained the same option: TWR %/yr sits beside Value and TWR %, drawing your time-weighted return as the per-year rate it compounded at, ending on the figure the Performance card reports. It follows the same one-year rule and the benchmark overlay annualizes with it.

The app now leads with the job. The permanent rail groups work under Today, Portfolio, Research, and Plan, while system destinations live in a visible Utilities menu. Global search, truthful status, Help, and price maintenance share a compact top bar. Public links, back/forward behavior, and saved page addresses are unchanged.

Rebalance Planner starts with the orders. Add, Reduce, Close, and cash-deployment rows lead; Holds stay one click away. A compact summary names turnover, closures, cash, and whether tax evidence is complete. Account identity and the actual order stay readable at the minimum window width, and every row has a keyboard-reachable review path. Missing account flags, model assignment, executable allocation, holdings or price data now produce one honest recovery route instead of a blank table, a false amount error or an on-target claim. A problem in one account no longer hides trustworthy orders, summaries or Biggest Moves for the others, and the visible-orders export names what was excluded. The withdrawal funding-orders export carries the same exclusion record. Overview accounts outside the calculation now say not rebalanced, while setup-needed reasons remain available without a mouse. Uninvested cash down to the cent now has one consistent Deploy state instead of a no-order message or a rounded-down $0 action. The action-first filter keeps following live rows until you intentionally change it, then preserves your selection for the session.

Research reads as a connected decision. Allocation models separates the version you are editing from the version effective today. Optimize moves through objective, candidate rules, then run/verify/apply, and Apply stays locked until the exact proposal has comparison evidence. Its reviewed swaps now save together or none do. The Screener leads with a model-and-slice shortlist; advanced filters and columns remain available without crowding the default path. Optimize and the Backtest tab now send incomplete allocations directly to Allocation models instead of stopping at a dead end. Optimize failures stay visible outside Advanced, move into view, and preserve the proposal for retry. Existing Screener layouts migrate to the new ranking view with Classic score visible while keeping compatible sort and column choices.

Attention and administration are quieter. The Overview groups only checks it can prove from stored data. Dismissing a possible split now hides only that exact database-and-evidence candidate for 180 days; changed evidence or another database's candidate still appears, and no portfolio path is saved in the local dismissal. Settings, Household profile, Help, and About now expose clearer ownership, recovery, and trust paths. Shared tables, menus, tabs, and dialogs have explicit keyboard/focus behavior, and the refreshed light and dark tokens preserve readable contrast.

Empty history now has an honest next step. Value-chart language covers Tiingo, Yahoo, and local/manual history without assuming a provider. The Ticker Metadata history drawer can rebuild one eligible ticker, or route to that ticker's exact setup, consent, or License prerequisite without bypassing it.

The trial boundary is enforced where writes happen. An expired commercial trial can still view, report, export, recover data, manage the license, and turn connections off. Portfolio, planning, import, model, and price mutations are blocked in Electron main even if a renderer control is bypassed.

Local recovery no longer mistakes uncertainty for a reset or an expired trial. If the app's configuration file is malformed or temporarily unreadable, unrelated settings and background update work refuse to replace it with defaults. Portfolio data remains readable while protected changes stay paused, and the License panel offers a retry without saying the trial ended. A retained legacy disclaimer row also cannot accept a newer version of the legal text on your behalf; changed terms are shown again when consent really needs renewing.

The bundled demo now has one honest clock. Browser-preview generation and versioned screenshot captures evaluate accrued fixed income and quote age at the sample's declared as-of date, so rebuilding on another day does not change the generated portfolio or create a growing stale-price warning. Capture captions keep the real demo date visible; sample database values were not moved forward to look current.

Overview performance was measured before the RC freeze. On a 1.11 GB portfolio database, the suspected repeated opening-review ledger reads totaled about 2 ms against roughly 2.2 seconds of database reconstruction, so the release does not add a speculative cache or new invalidation behavior where the measurement did not justify it.

0.45: The stocks you own, taken seriously

This app is built around funds, and it showed. A single company arrived classified as far as a fund concept could carry it and then stopped: where a fund names its category, a stock showed nothing or, worse, showed Unknown forever. The odd part is that the answer was already arriving. Every profile fetch pulls a company's sector, its industry, and the handful of figures a stock is actually judged on, and this app read the two it could use for placement and dropped the rest on the floor.

The 0.45 line picks them up. Nothing here costs an extra download.

Sector and industry, kept. A stock now carries the thing a fund's category carries: what it is. Sector is a column on Securities & prices with the industry on the hover, a pair of fields in the ticker editor when the feed's answer needs correcting, and a filter on the Screener beside Subcategory, which until now was an empty dropdown for anyone screening single names. Screener views you saved before this release still apply; they simply carry no sector filter.

The figures, in the row. Expanding an individual stock on Holdings now shows market cap, P/E, dividend yield and rate, beta, the 52-week range and the next earnings date, above its transactions. Read them as a snapshot, not a ticker tape: they are what the last profile fetch returned, stamped with that date and labelled underneath. This app holds one download at a time on purpose and is not about to start making a request per stock per screen. Where the feed had no answer you get a blank rather than a zero, because for a P/E those are not the same claim.

A Stock Monitor on the Overview. One panel for the individual names in the accounts you're looking at: the day's move, how far each sits below its 52-week high, what share of your equity it is, and three flags: a position over your concentration threshold, a close within 5% of the 52-week low, earnings inside 60 days. The threshold is yours to set, on the panel, and it stays set. Concentration is measured against your equity rather than the whole portfolio, since "8% of my stocks" is the question a concentration flag exists to answer. The panel is computed entirely from closes already on your machine, so it costs nothing to open. That is also why the day's move reads the same all weekend. A portfolio of nothing but funds never sees it.

"Unknown" is gone. A stock imported from a broker CSV was stamped with that placeholder category, and because a single company has no fund category, no amount of re-fetching ever cleared it. An AAPL row read Stock · Equity · U.S. · Unknown indefinitely. Upgrading corrects those rows once. A category you typed yourself is left exactly as you typed it.

An AI you connect can see sectors too. get_accounts_and_holdings now reports sector and industry beside category, and says which to read for which kind of holding: a fund has one, a stock the other, and a blank on either side is normal rather than missing data. The stats above are deliberately not exposed: they are a snapshot whose staleness a caller can't see, and an assistant quoting a fortnight-old P/E as today's would be worse than one that never had it.

Also in this line. The model-lens help claimed holdings were placed by sector. They never were. Placement reads market cap and country, and that sentence now says what the code does.

0.45.1: a fund that got filed as a stock

The feed sometimes answers for a newly listed ETF as though it were a company: no category, no expense ratio, type "equity". One of those answers was enough to store SPYM, a $161B S&P 500 fund, as a Stock, which then put it in the Stock Monitor above as if you held a single name. Setting Security type back to ETF by hand didn't survive either, because Type was the one field a fetch rewrote outright while everything else was merged.

A category or an expense ratio now outranks that answer because a company has neither. The app reads them from the fetch or from what it already recorded, since a bad answer drops the category too. Anything already mis-filed is repaired by its next fetch. The trade-off is worth stating: a stock carrying a category you typed yourself now reads as a fund, so clear its Category if you mean stock.

0.44: Backtests for your AI, and a second way in

The 0.43 line settled which AI answers. The 0.44 line is about what it can do once it does, starting with the thing it most obviously couldn't.

It can test a model, not just suggest one. Ask your assistant to compare a draft allocation against the one it would replace, or against the models you already keep, and it replays them over the price history this app has already downloaded, using the same engine Allocation models' Backtest tab runs. Up to four at once, on purpose: run together they share one window, so the comparison is measured over the years all of them actually cover instead of flattering whichever had the kindest decade. It downloads nothing; it reads what you already have. It is honest about the gaps. A saved model holding a fund with no price history says so, and a proposed one naming such a fund is refused rather than quietly counted as cash, which would have rigged the very comparison you asked for.

Answers are formatted. Sections, bullets, bold on the number that matters, and a real table when the assistant is comparing figures, which is most of what this pane is for. Before, a comparison arrived as asterisks and pipe characters. The pane renders light formatting only: a model that reaches for something more elaborate, like a list inside a list, gets flattened rather than mangled.

It can tell you which switch to flip. With projections switched off, the assistant used to say it "doesn't have access." That was true, useless, and indistinguishable from a broken app. It is now told which row in Settings → AI assistant turns that tool back on, and told to point at it rather than estimate the answer by hand. Whether it takes the advice is the model's to get right; what changed is that it is no longer guessing in the dark.

Model names can be picked, not typed. Every model field now fetches the list from the source itself: the models your LM Studio has loaded, the current Claude and DeepSeek line-ups, whatever your own server offers. Typing a name the app has never heard of still works. Claude also gains the priced Opus/Sonnet/Haiku picker in Settings that DeepSeek already had.

And a running total of what it has cost. Under the per-conversation line, a second line adds up every turn this copy of the app has run, across every source, surviving Clear and a restart. Each turn is priced at the model that actually answered. It is kept beside the app's own settings, not in your portfolio file, so it never rides a backup.

A second way to connect a client

Most AI clients launch the connector themselves. A few can only be pointed at a web address, so there is now a switch for that, off unless you turn it on. It serves the same tools at an address on this computer, behind an access token the app generates for you to paste into the client, with Regenerate if you ever think the token has been seen. The panel now says which door each connected client came in by.

Under it sits a second switch, also off, that opens that address to other devices on your network, such as the desktop in the other room, a laptop, or a phone. It carries what it costs, in plain words: the connection is unencrypted, so anyone on the network path can read your portfolio and the token, and it opens on every network the computer is attached to rather than only the one you had in mind. The panel lists the addresses it finds and warns if one of them is reachable from the internet. If you want the app from somewhere else, an SSH tunnel does the same job encrypted, and AI assistant access shows the one line that sets it up.

One more thing about that switch: it lives in your portfolio file, so restoring a backup taken while it was on used to re-open the port with nobody clicking. Now the app asks every time a portfolio arrives from a backup, a sample, or another machine, and Turn it off is the answer sitting under your fingers.

Also in this line. The About page's privacy sentence now names its one exception instead of promising more than the app can keep once you switch an AI feature on. And the file holding your license and price-data keys is written whole rather than in place, so a crash mid-write can't leave it truncated.

0.43: Four AI sources, by name

The 0.42 line gave this app an assistant. The 0.43 line is about which AI answers it and about not having to know a base URL to say so.

The sources have names now. Settings → AI assistant offers four: Claude, DeepSeek, LM Studio, and Other server for anything else that speaks the same protocol. Before, the choice was between "Anthropic API" and "Custom endpoint", which meant knowing which address DeepSeek answers at and which LM Studio setting reaches a second machine. Each source now asks for what it actually needs and nothing else.

DeepSeek. A key from platform.deepseek.com and a choice of two models: Flash, fast and very cheap, or Pro, which reasons longer on harder questions. No address to enter. Both are priced in the app, so a DeepSeek answer carries the same per-turn cost line a Claude answer does; a sweep that costs cents on Claude usually costs a fraction of one here.

LM Studio, on this computer or the one down the hall. Locally, the address is already filled in: start the server in LM Studio's Developer tab, name the loaded model, and you're done. On another machine, such as the desktop with the real GPU, switch on Serve on Local Network in that copy of LM Studio and enter the address it shows you. There is no key to invent, because LM Studio's server doesn't use one.

As many as you like, at the same time. Claude, DeepSeek and a machine on your network each keep their own settings and their own encrypted key, so setting one up never disturbs another. Settings names which ones are ready, and once two are, the Assistant page grows a switcher in its header. One click asks the same question of a different model. Switching starts a fresh conversation, because the services don't speak a common format mid-thread.

And the panel tells the truth about your network. Pointing the assistant at another machine in your own house is a normal thing to do, and it now reads as one: what it reads goes to that machine over your network, not out to the internet. Previously every address that wasn't this computer got the same warning, which told people doing it right that they were doing something wrong. On this computer it still says what it always did: nothing leaves at all. An address out on the internet still says exactly where your data would go.

Nothing about permissions changed. Reading is on whenever an assistant is; projections and model proposals are each still their own switch, they still govern both doors, and nothing is saved to your portfolio without your approval in the app.

0.43.1: a full review pass, and one bug worth knowing about

The most consequential fix: under VPW or % of balance, the projection could treat a still-working plan as already retired. Those two strategies read your remaining balance directly, and the age they started reading it from was your current age rather than your planned retirement age. A 50-year-old aiming to retire at 65 could see the engine prescribe retirement-scale withdrawals through fifteen years that should have been building the portfolio, not spending it. A sample $1M plan under VPW read roughly $1.48M at 64 where the corrected math reaches $2.60M. The same gate now applies everywhere that family of numbers is read: the strategy-comparison table, a future home purchase's ongoing costs, and the sustainable-withdrawal-rate reading, which also now counts the tax bill due on every withdrawal rather than only the withdrawal itself. If you run a balance-driven strategy on a plan that hasn't retired yet, it's worth opening Retirement plan again. The numbers you saw before this release may have understated what your plan actually supports.

The rest of the pass was a full code review, not a single feature: it closed data- integrity gaps (deleting a ticker could, in three specific situations, silently break a snapshot-tracked account, a matured CD, or a sweep fund's cash tracking), stability gaps (a dead price sidecar could crash the app; a stalled price server could hang a fetch with no timeout), a cost-basis ordering bug on same-day buy/sell pairs, several pages that could get stuck at "loading…" after a rejected request with no way to retry, and a round of smaller interface fixes. The full list is in CHANGELOG.md.

0.42: An AI that can read your plan, and propose to it

The 0.42 line opens this app to an AI, one that answers from your numbers instead of generalities, and that can hand you a target model without ever being able to save one behind your back.

Your questions, answered against your own plan. The projection engine has always been able to answer "what if I retire at 65?", but only for one scenario at a time, typed in by hand. Now an assistant can sweep it: six retirement ages, both Social Security claiming dates, a return assumption moved up and down, each run seeded so the comparisons are honest, and the differences explained in terms of your accounts. The same goes for what you hold: drift against your models, a rebalance preview, or an expense-ratio comparison, all asked in a sentence.

Two ways in, and you choose the door. Settings → AI assistant turns on a private local socket that an AI client you already run, such as Claude Desktop, Claude Code, LM Studio, or Codex, can connect to. That connection opens no network port of its own and exposes nothing to your network, and the switch is off until you turn it on. If you'd rather not configure anything outside the app, the Assistant page is the same thing with a chat pane around it: bring an Anthropic API key, or point it at a model running on your own machine through LM Studio or Ollama, in which case your portfolio never leaves your computer at all.

Connecting an outside client takes one paste. The panel prints the exact configuration for each of the four, and the connector it points at ships inside the app. There is nothing to install or keep updated, and it works the same on macOS, Windows, and Linux.

Windows note since 0.46.0: the shipped runtime does not provide a proved creator-only named-pipe boundary, so Windows no longer starts or advertises that connector. A Windows external client can use the access-token-protected web address, still behind its off-by-default switches. The macOS/Linux connector remains as described above; see AI assistant access for the current platform details.

The AI proposes; you dispose. An assistant can draft a target model, and that is the only thing it can write. The draft arrives as a card inside the app, validated to 100% and showing every ticker and weight, and nothing is saved until you press Save as model. There is no tool to delete anything, none to edit your holdings, and, as has always been true here, nothing in this app can place a trade.

You can see what it did. Every tool call an assistant makes is listed in the Settings panel as it happens, tagged with what it was allowed to do: read, compute, or propose. The three switches that grant those permissions are the whole of what a connected assistant can reach.

And the account wizard got a pass for the rough edges. Every step now says which one it is. A fund with no ticker is entered from a button beside Add ticker rather than a question above the grid, its form asks for the share count with everything else. A row missing one used to grey out Continue with nothing on screen to say why. A fund entered before is picked from a list instead of retyped, which no longer files it under a second symbol. Both that form and a target mix's slices can now name a real fund category, the thing the Screener and the exact-fit test actually read. The TSP fund picker appears only for TSP accounts, and a refused Continue or Save names what it's waiting on.

0.42.2: what one new account was doing to a finished portfolio. Adding an account could blank the Portfolio Value chart: the household chart began where every account had data, so an account added today set the start for all of them and left a single point with no line to draw. A new account now counts as nothing before it existed, and the years either side of it stay put. The setup checklist names the account it's about, in its heading and in every open step, instead of leaving four instructions with no address on them. Deleting an account now takes it off the checklist, so the bar retires itself rather than outliving what it was set up for. Opening the Assistant page no longer asks for your keychain password; it was checking whether a key could be stored in order to draw the page, and now asks only when you actually save one.

0.41: Spending that follows the portfolio, priced honestly

The 0.41 line lets your plan answer a question it previously assumed: what rule decides how much you spend each year.

Your spending can follow your plan, or follow your portfolio. Until now the projection spent exactly what your plan said, every year, through anything the market did. That describes a retiree nobody has ever met. Expenses → Spending strategy gained two alternatives beside it. VPW is the Bogleheads Variable Percentage Withdrawal: each year it spends what your remaining balance would support if spread evenly over the years to a terminal age (100 by default), at your own stock/bond mix. The percentage rises as you age, because there are fewer years left to cover, which is why spending holds up far better than a flat rule. % of balance is the simplest version of the same idea, included because it is the honest floor of the genre.

The percentages match the published Bogleheads table to the digit: 5.0% at 65 for a 60/40 portfolio and 6.9% at 80. Where your plan already describes an allocation, the mix comes from it age by age, so a glide that de-risks lowers the withdrawal percentage on its own. Social Security and pensions sit underneath the rule as guaranteed income rather than inside it, and spending never drops below the essentials you have marked fixed.

Every one of these rules is very hard to run out of money with. That is the part to be suspicious of. A rule that hands you a share of what is left can never hand you nothing. The failure doesn't disappear; it moves into your spending. So nothing here reports a success rate on its own. Explore → Compare spending strategies runs your household under every rule on the same seed and the same market years, and puts both halves in the same row: the chance of success and the depletion age, next to the leanest year you would actually be living on, how many years spending ran below plan, and what was left unspent at the end.

On the sample household's saved plan, VPW turns a 13% plan into a 100% plan. It does so by paying \$46,097 in the worst year of a bad decade, against a plan that called for \$88,000. Both numbers are on screen, together. Which of them matters more is a question about your life, not your spreadsheet.

The spending guardrail was under-counting its own cuts. Its honesty report compared each year's spending, including the Medicare premium the app works out for you, against your planned spending, which doesn't. With Medicare modeled, a real trim could vanish behind the premium added on top: a 10% cut to a \$40,000 flexible budget read as no cut at all beside a \$5,000 premium. The report now compares like with like, so its cut years and their depth are the real ones. Plans without Medicare modeled are unaffected. Only one rule ever drives your spending. Two reacting to the same signal would double up, and you could no longer tell which one moved your spending.

0.41.1: the withdrawal-rate check stops grading a rule it can't grade. The safe ceiling on the Withdrawal rate by age chart is the highest fixed real draw that survived history. That's a sensible bar for a plan that spends the same amount every year, and the wrong bar for VPW, whose percentage is meant to climb as the years left shrink, so a perfectly healthy VPW plan read as permanently reckless, its line above the ceiling from the first year to the last. With a balance-driven strategy active the ceiling and the green/amber/red grade both come off, and the chart says why. The rate curve stays: it still describes what you're drawing. Under the standard spending plan, nothing changes.

A comparison row no longer reads as a contradiction. "97.6% · runs out at 93" raised the obvious question: which is it? That age was only ever the median among the paths that did fail, so the row now names them: 97.6% · 2.4% fail, typically at 93.

The year-by-year table reads like a statement instead of a wall. Its columns now run in the order a year actually happens, under headings that say so. First comes what you hold at the start, with Value beside the bucket balances it sums. Then come what goes out, what funded it, and what moved into accounts. Columns with no activity anywhere in your plan are hidden and listed underneath, so a household with no Roth or no HSA stops scrolling past thirty rows of $0 (hidden means all-zero, not unmodeled; a column returns the moment your plan uses it). The Age column stays pinned while the rest scrolls sideways.

0.41.2: the year-by-year Spend column showed the plan you typed, not what your plan actually spent. It read the spending schedule straight off your inputs. Under the standard spending plan those are the same number, so it was right by coincidence. A spending policy exists precisely to move spending away from the schedule. Under VPW the column was simply the wrong number: it sat flat for decades while every balance beside it fell, which is the opposite of what VPW does. Under the guardrail it hid the cuts for the same reason.

Spend is now what the plan actually spent, from the engine, with Medicare beside it rather than inside it. When a policy has moved spending off the schedule a Plan column appears next to it, so you can read the gap year by year. That gap is the strategy working. Under a plain spending plan the column stays hidden, since it would only repeat Spend. The terminal age is blank because no year is simulated at it.

0.41.3: one picker for how much you spend. The guardrail used to be a separate panel with its own checkbox, sitting beside the strategy picker as if it were a modifier you bolted on. It isn't. It is the second rung of one ladder, from spending that never reacts to spending that is entirely whatever the balance says. It now sits in that ladder, as one of four options in Expenses → Spending strategy: Fixed plan · Guardrail · VPW · % of balance. Picking one rules out the others, so there is no longer a combination of controls to reason about. ("Spending plan" is now called Fixed plan, which is what the rest of the app already called it.)

Your settings are untouched. A plan that had the guardrail switched on opens on Guardrail with the same knobs; one that didn't opens on Fixed plan. Every saved scenario loads exactly as it ran, and switching rules to look around never loses the posture you configured.

The flexible share of your spending moved out where you can see it. That one field, which says how much of your everyday budget you could actually cut, was buried inside the guardrail's panel, which meant VPW and % of balance quietly used it without ever showing it to you. It is the same number from both directions: the slice the guardrail trims, and the essential floor a balance rule can never take you below. It now sits under the picker for all three rules that need it.

Explore → Compare spending strategies gained a fourth row, so the guardrail is priced beside the others on the same seed and with your own knobs, whichever rule you currently have picked. That table's Fixed plan row is also genuinely fixed now: with the guardrail switched on it had been quietly running with it, which made the baseline every other row was compared against the wrong one.

0.41.4: account setup that ends where it should, matching your broker. Setting up an account from a CSV import had every mechanical piece and no recipe, and the visible symptom was importing a file and staring at negative shares. The wizard's import path now asks one question: track this account from when?, usually the 1st of a month. It derives everything else: enter holdings and cash from the statement dated the day before (the entry locks to that date, and each position can carry its cost basis straight off the statement, so gains match your broker's from day one), then export transactions from the start date onward. Rows on or before the statement date are skipped on import, so the two sources can never double-count. The full recipe is in the guide.

The import dialog now finishes the job: it names the exact date to export from, flags a file that starts months after your opening date before you import it, detects missing opening cash the same way it already detected missing positions (the pre-filled figure is the minimum your ledger proves; correct it against the statement), and hands you to Compare with broker at the end. And if negative shares do appear on Holdings, they now come with a banner saying what they mean and where the fix is, instead of unexplained red numbers.

0.41.5: your model's history was always the feature; now you can see it. A target model isn't one allocation, it's a series of dated versions, and Allocation models' Backtest tab has always replayed them in order. You could just never watch it happen: every bundled model carried a single version, so the version markers and change tooltips already built into the chart had nothing to mark. The sample 60/40 now carries the history its own note always claimed: 70/30 from 2020, de-risked to 60/40 in January 2024. The switch lands mid-chart and you can see what changing an allocation actually did to the curve.

Extend back now starts at Max. Off sounded careful and behaved like a wall. A model's first version dates from when you recorded the allocation, not when you started holding it, so a model built this morning drew a one-day chart. The setting that fixed it was three levels deep. Now the stretch before your first recorded version is drawn as a dashed line running up to the version marker, so the "this part is extrapolated" disclosure lives in the curve where you're already looking. When a window is genuinely too short to plot, you get a plain statement of why and a one-click fix instead of an empty chart.

How the app works is a new topic for a loop the app never narrated: what you own and which parts of the app read it. It opens the Help centre and anchors the Retirement plan page's empty state.

A self-directed slice can be turned off again and can no longer swallow the funds beside it. Marking a slice self-directed tells the rebalancer to size it as one lump and leave your individual picks alone, which is exactly what some people want for a satellite sleeve. But only one path could ever set that flag, nothing could clear it, and the slice editor would happily let you add funds to a slice whose funds rebalancing then ignored. A 25% "My picks" slice could list five tickers in Allocation models while Rebalance Planner showed a single unnamed row mentioning none of them. There's now a toggle in the slice editor, and the contradiction is gone for good: a self-directed slice can't hold funds at all, the form says so and names anything a save would drop, and the slice list reads Your own holdings, the same words the Rebalance Planner table already used.

A salary typed with a comma modeled as no salary at all. Every money field on the Retirement plan page read "103,001" as unparseable and quietly used zero. As a result, a typed salary meant no contributions in the engine, a flat Work band in the income chart, and nothing on screen to say anything was wrong. Pensions, annuities and passive income had the same hole. Commas, dollar signs and stray spaces are now accepted everywhere the rest of the app already accepted them. On the household this was found in, it's the difference between an 81.0% and an 82.5% plan. The projection had been modeling an unemployed year.

A VPW terminal age inside your plan's horizon zeroed every statistic, and nothing said why. Set the terminal age to 95 with your plan running to 95 and all three success numbers read 0%. The engine is right, and the reason is worth knowing: VPW amortizes your portfolio to zero at the terminal age, so the final year draws 100% of the balance. The taxes and Medicare that come due after that draw have nothing left to come from, which marks every path as failed no matter what markets did. The panel now warns as soon as the terminal age reaches your plan's horizon, names both ages, and tells you to set it higher. It stays a warning rather than silently correcting the number: the projection keeps modeling exactly what you typed.

0.41.6: a first user's notes

Everything in this update came from one person's list after a week with the app, which is the most useful thing anyone has sent.

The model wizard's Review button did nothing on nine of the fifteen ready-made Schwab mixes. Pick a published mix, look over its slices, click Review. Nothing happened, with nothing on screen to say why; the only way to assign a model was the account settings form. The button was refusing the click rather than dropping it, and three things hid that. The ready-made mixes work out each fund's share of its slice by rounding, which can leave a slice's funds totalling 100.01% instead of 100%; the check behind the button rejected exactly that hundredth; and a disabled button looked exactly like a live one, sitting beside a hint asking for a total of 100% next to a total already reading 100.00%. The check now tolerates rounding, the ready-made mixes land exactly on 100%, a button you can't press looks like one, and where a mix really is unfinished the hint names the slice at fault and offers to open it.

The backtest's metrics explain themselves. The Strengths and Trade-offs cards hand you a verdict in words nobody is born knowing, such as Best Sortino or Lowest Ulcer Index, and used to explain none of them. Hover any bullet for its definition, or open Reading the backtest metrics from the panel: which number answers which question, and why two of them disagreeing is usually the finding rather than a contradiction. Seven entries sit behind it: CAGR, volatility, max drawdown, Sharpe, Sortino, Calmar and the Ulcer Index. Each is findable by name from ⌘K.

Two smaller things on the same page. Long model names were cut off in the list with no way to read them, and because every ready-made name starts with the same family, the part that got cut was the ratio telling them apart. Hovering a row now shows the whole name. And a blank chart used to blame the timeframe when the real problem was that a model's funds had never been priced: funds are registered when a model is, but prices are downloaded separately, so the app now names the funds it has no prices for instead of pointing at a date control that was never the cause.

Copies of a model are no longer joined to the original. One report said "cloned models seem to be linked; if you change a parameter in the cloned one it changes the original." It turned out to be two separate bugs wearing the same description, and both quietly rewrote a model you weren't looking at.

On Allocation models, duplicating always made a real, independent copy; the trouble was the editor beside it. The slice editor is attached to one model's rows, and Duplicate selects the new copy without closing it, so the list and heading switched to the copy while the open form stayed attached to the model you copied from, and saving rewrote that one. The same happened on any switch: clicking another model, or another dated version, with a slice still open. The editor now closes whenever you change model or version, so what you save is the thing on screen. If you duplicated a model and edited the copy before this release, it is worth checking the original. The change may have landed there.

In account setup, the mix picker invites you to start from a ready-made mix and change it. The change went into that published mix, and into every other account already running it. Now your first change makes your own copy, named for the account you are setting up: the ready-made mix stays as published, other accounts keep the target they had, and the editor tells you the copy was made. Pick a mix and change nothing and no copy appears, so several accounts can still share one mix on purpose.

0.40: Cash that counts, and crashes that stay put

The 0.40 line fixes a model slice that could never be satisfied, stops one broken page taking the window with it, and makes the destructive actions say what they actually do.

A model can hold cash, and the cash row finally reads it. A slice written with the reserved $CASH ticker reported $0 held forever, while the same dollars sat in the account inflating the pie. As a result, Rebalance Planner kept telling you to buy cash the account already had, counted twice against Deploy, on a slice that could never close. It reached the 15 Schwab models the empty starter seeds and any model imported from CSV. The Deploy row and the cash row are one thing now: state a cash target in your model and the row targets it; state none and nothing changes, with uninvested cash still always flagged.

One page hitting an error no longer takes the window with it. Each page now has its own named error card with a retry, so the sidebar, the banners and the other pages stay usable while one is broken, and the fault is on screen instead of leaving you a white window and nothing to report.

Restoring a backup asks you to type the phrase, and its safety net is real. Restore replaces your live database, but it was the one such action with a two-button confirm under copy claiming it "cannot be undone." A pre-restore snapshot was being kept all along, as a hidden file no screen mentioned. It now asks you to type RESTORE <backup name>, tells you the snapshot exists, and files it in the Files backups list where you can find and restore it. Back Up Now from the File menu lands there too, instead of reporting into a dialog the page never saw.

Recording a split confirms where you found it. The action sits under the banner that raised the flag, so the preview and the decision sit together. The copy now names both sides: it scales pre-split share counts and leaves current shares, cost basis, transactions and downloaded prices alone.

0.40.1: your license says how long updates are included. An activated copy showed only who it was licensed to, while the key on disk already carried the date. Settings → License now reads it off your own key: updates included through August 3, 2027. Once that day passes, what still works and what a renewal would pick up. Nothing about the app changes when the window closes: your license stays valid, every version you already have keeps working, prices still update and imports still work. What lapses is only your claim on newer builds, and it is never checked while you work. A license bought before this model existed carries no date at all and is perpetual, covering every version forever. It shows who the copy is licensed to and says nothing about updates.

The License panel says each state once. It restated one fact up to three times. Every state is now one line for what's true and one for what it means, including what a license actually includes: a year of updates, with every version you already have working for good afterwards, verified on your computer. A lapsed trial strip also gains a direct Buy a license exit, and an activated copy keeps a Replace license key box so an upgrade key needs no removal first.

Signed numbers agree with each other now. A value too small to print at the precision shown no longer keeps its sign, so nothing reads "−0.0%" or "−$0" when the answer is zero. And a gain or loss is written the same way everywhere: the Rebalance Planner drift row used a different minus for its percentage than for its dollars, and a withdrawal in a ticker's history used a different one again from the same withdrawal on the cash panel.

Some text was hard to read on gold. Buttons and chips filled with the signature gold drew their label in white, which barely showed against it. The problem was worst on the Screener's column button, the TSP fund chips and the money-flow toggles. They now use dark ink, and the expired-trial notice no longer paints a pale bar across the dark theme.

Also: one verb for every CSV control ("Export" for what's made on demand, "Download" for files that already exist), accepting the disclaimer now records which text you agreed to, a development build says so instead of claiming the network failed, and the update check's description names everything it sends: version, operating system, and a once-only first-run flag; no usage data and no identifier.

0.40.2: the update banner stopped pointing at the version you already have. When a newer build was offered, the strip carried "See what's new in …" naming your installed version, not the one on offer. A copy of the app only ever ships its own notes, so that link could never describe what the download would give you. The banner now offers the download alone. "See what's new" lives where it is true: Settings → Updates, on the line a completed check produces when nothing newer exists.

0.40.3: the samples show what to do with the TSP funds. Adding them has been one button in Settings, but nothing bundled with the app demonstrated them. Every sample now carries six priced TSP funds and the two target models a federal employee actually chooses between: TSP L 2040, the one-fund Lifecycle default, and TSP Custom Mix · 85/15: C 55 / S 20 / I 10 / F 5 / G 10. Load the mid-career sample, open Allocation models' Backtest tab and select both: the self-picked mix returns more over the window and gives more of it back in the drawdown, for a reason you can point at: more equity, and a quarter of the L fund's international sleeve. As everywhere else in the samples the prices are synthesized, with two things held true to the real funds: the L fund's series is the blend of the other five rather than a series of its own, so the gap between the curves is allocation and nothing else, and the G Fund never has a down day. Press Update Prices and the real published share prices replace them, which takes the comparison back to 2003.

0.39: Ways out, and a menu bar

The 0.39 line is mostly about the app being easier to leave, link to, and trust, along with the first honest menu bar it's had.

  • A way out when something's wrong. About gains Get help · Report a problem: the support page and an email link carrying your version, plus links to the site, privacy policy and terms. The same route sits at the foot of the Help center and in the Help menu.
  • A real menu bar. Settings… ⌘, · File → Import Broker CSV… / Back Up Now / Open Data Folder · Help → Help ⇧⌘/, What's New, Report a Problem…, and the product site. The native About panel finally shows the version and copyright.
  • Release notes that reach you. This panel had stopped at 0.30 under a 0.38.6 app; it now carries the current line and the two before it, and the update banner links straight here.
  • Every page has an address, such as #/holdings or #/settings?section=price-data, so the back button works, a reload returns you where you were, and Settings gains a section nav across its eight panels.

Two numbers were wrong and are now right. Until price history exists, the Overview's headline Total left out core cash while the projection counted it, so the app's first number disagreed with its second by exactly your cash. And the Holdings summary printed Market Value $0 over a full table for any account without a transaction ledger.

The expired-trial message overstated what you lose. It claimed a license restores exporting; exports were never gated. Your portfolio stays readable and exportable. A license restores editing and price updates.

Also: navigation regrouped by task, the two Screener scores renamed from version numbers to the Classic and Peer scores, model validity is green everywhere, wide tables show when they're clipped, and Inter now ships with the app so your install looks like the screenshots.

0.38: Housing decisions, and a benefits cut you can test

The 0.38 line went after two of the biggest levers a retirement plan has: when you buy a house, and what Social Security actually pays.

  • Stress-test a Social Security cut. Reduce both people's benefits by X% from a chosen year. The preset is 20% from 2034, based on the trust-fund depletion arithmetic. Then watch the plan absorb it. See stress-testing a cut.
  • "What if I wait?" The affordability finder now answers its natural follow-up: if you delay a year or two and those years run weak, soft, expected, firm, or strong, what's the most house from that state? Each recommendation is also scored under all three return models at once. See the affordability finder.
  • Withdrawal rate by age. Net portfolio draws as a percentage of that year's starting portfolio, plotted against the ceiling the KPI grades against.
  • A daily update check, disclosed and off-switchable. Version and operating system, no identifier, no usage data, and no exceptions on Store installs. See the About page.

Fixed along the way: a future-year home purchase no longer gets an inflation head start; a cheap house no longer carries an expensive house's upkeep (insurance and maintenance scale with price now); the withdrawal-rate chart stopped drawing guardrail thresholds that measured a different ratio than its own line; and chart legends draw dashed lines as dashed.

0.37: The projection explains itself

Two new topics and one button, all aimed at the same question: what is this number actually claiming?

  • How to read the results defines success % as a pass/fail tally (one unfunded dollar fails a run), failure depth, the median against its bands, and why per-age medians don't add up like one household's years.
  • How Social Security is modeled collects the claim-age math, the statement-vs-salary entry paths, worksheet taxation, and the survivor rule in one place.
  • Trace: zero volatility. One click zeroes every randomness input so the year-by-year table collapses to a single hand-checkable path, then restores your exact prior settings. See seeded simulations.
  • The implied compound rate now sits beside every return field ("≈ 5.8% comp."), where the number gets typed rather than in a caption below it.

Tax constants caught up with the July-2025 OBBBA: the standard deduction and the 65+ bonus deduction (modeled with its statutory sunset) had been understated, so taxed plans tick up slightly. IRMAA's two-year lookback now counts only the taxable part of Social Security, matching the real rule. A benefit-heavy plan is no longer charged a premium tier early. See what the tax model covers.

Fixed: Household profile's tax-rate fields accept decimals again. Typing 4. used to snap back to 4, putting a rate like 4.4% out of reach.

0.36: A fresh install that can fetch prices

A new install had two quiet cliffs. Both are gone.

  • "Set up price data" instead of a failed download. A fresh install has neither feed ready. Tiingo is the default but needs a key, while Yahoo is an explicit opt-in, so Update Prices used to fail once per ticker with no explanation. The top-bar button now names what's missing and routes to Settings → Price data, which links out to Tiingo's signup and token pages; the Screener's unpriced-funds prompt says the same. See price sources.
  • Turning Yahoo on now makes it the default when no Tiingo key is saved. This is the rule the first-run wizard already applied. Without it, enabling Yahoo changed nothing: every unpinned ticker still routed to a keyless Tiingo and the whole sync failed.
  • The sample households are half the size. The bundled fund universe became a curated sampler. Every category is still represented, with 1,914 tickers down to 127, and seeded price history starts in 2020. Each sample file drops from 18.4 MB to 9.5 MB, so a demo's one-time price update is a job that finishes instead of one that trips a rate limiter. See the Files page.

Settings → License also gained a Buy a license link and a note that the key arrives by email and on the thank-you page. The trial banner used to land someone with no key on a form asking for one.

0.30: In-app help, everywhere

This release adds the help system you're reading right now, built in, offline, and honest about the app's modeling decisions.

  • "?" tips beside computed numbers, modeling knobs, and badges offer two sentences in place and a Learn more link for the full story. Placed deliberately: self-explanatory fields stay clean.
  • A contextual panel on every page (the top-bar "?", or ⇧⌘/ / F1) with the page's guide and related topics.
  • This Help center: guides for all 15 pages, how-the-math-works methodology, a glossary, task recipes, and troubleshooting. Over 70 topics, searchable here and from ⌘K.

Nothing about help leaves your device, and reading it never changes your data. Start with using help.

0.29: Published outlooks preset

The 0.29 line focused on making the projection's forward assumptions easier to anchor honestly:

  • Published-outlooks consensus preset: seed Forward Assumptions from a blend of published capital-market outlooks instead of hand-picked numbers, with the sources named.
  • Return-unit notes in the UI: assumption fields now say whether a figure is arithmetic or compound, because mixing the two silently biases results.
  • Fix: compound CMA estimates are converted to arithmetic before the valuation shrink is applied, so the condition-on-today drift adjustment no longer double-penalized compound inputs.