2026.08.15.1
New features
Section titled “New features”Budget: retire the “Reserved” forecast – adopt the reserve-free math contract on the month header + mobile (KAN-1626) Your budget’s monthly summary now gives you a truer picture of your plan. Previously, the app quietly set aside an estimated amount for spending in categories you hadn’t budgeted, which shrank your headline number and could even make you look over-budgeted when you weren’t. That hidden set-aside is gone: your headline now simply shows your expected income minus what you’ve actually planned, and past months show what really came in and went out. Spending outside your budget lines now appears as an “Everything else” line you control – you can set an amount for it each month, and it behaves like any other budget line, with a gentle one-time reminder if that spending has been adding up. Because of this change, your headline number will rise by the amount that was previously set aside and some over-budgeted warnings will disappear – this is a correction to how the number was calculated, not extra money to spend. One note for shared households: the “Everything else” amount is shared, so setting it updates the plan everyone sees.
Mobile header plan – Phase 2-4 reconciliation: Reports figure, breakdown runway bar, STS copy table, chrome-row search (HDR-4/6/7/9) (KAN-1639) Each report in the mobile app now leads with the number that matters: the top of the screen shows a big headline total – your total income for the category and month views, total spent for payees, and your net cash flow – with three quick time-period choices right underneath, and you can switch between reports just by tapping the report’s name at the top. The breakdown screen now shows the colored bar that illustrates where your balance goes, right under its heading, and it always matches the bar on your dashboard exactly. The wording that describes how your safe-to-spend money is doing now reads the same everywhere – the dashboard and the breakdown can never show two different phrases for the same situation. Searching your bills is also easier: instead of being tucked away in the filter panel, the search now sits right at the top of the Bills screen, narrows the list as you type, and shows a live count of how many bills match.
Opening-plug re-arm cannot clear a stale plug whose correct value is $0 (‘already-balanced’ skip leaves the drifted row); KAN-930 monitor’s rearmOpeningPlug remedy is a no-op for this class (KAN-1239) Until now, changing anything about a transaction from a linked bank account stopped the app from helping with the rest of it – rename a purchase and its category would never be filled in for you again, or pick a category and the messy bank text would stay messy forever. Now your changes are protected one piece at a time: whatever you set by hand stays exactly as you left it, and the app keeps tidying up only the parts you have not touched. Separately, when a linked account’s starting balance no longer needs the small opening adjustment the app originally added to make things line up, that adjustment is now removed on its own instead of lingering and quietly throwing the account’s balance off. We also fixed a problem with the tool our support team uses to rebuild an account’s history from scratch: bills that had already been marked paid are now cleared out and put back on schedule properly, so those payments are recognized again once the history reloads. The rest of this release is behind-the-scenes tidying with no change to how the app behaves.
Mobile header snaps between full and collapsed states instead of animating with the scroll (KAN-1353) When scrolling on the mobile app, the header used to jump abruptly from its full size to its compact size in a single snap, which looked jarring. Now the header shrinks smoothly as you scroll, animating gradually from the full header into the compact one – and expanding back just as smoothly when you scroll up. This happens across every main screen: Home, Accounts, Budget, Bills, Reports, and the account register. We also removed the unused “Help & support” item from the menu, which now shows Alerts, Bills & schedule, and Settings.
clean-user-account erasure can be resurrected by the login-time orphan heal (KAN-1360) When an account was deleted, the system could sometimes fail to fully remove the associated login credentials. If this happened, the next sign-in attempt would detect the orphaned credentials and automatically recreate an empty account under the same identity, effectively undoing the deletion. The deletion process now removes login credentials first and only proceeds with the rest of the erasure after confirming they were successfully cleared. If credential removal fails, the deletion stops and reports the issue rather than leaving the account in a state where it can be silently resurrected. Rerunning the deletion after resolving the underlying issue completes it cleanly.
Mobile web login offers Google but no Sign in with Apple (KAN-1434) When signing in from a phone browser, the only quick sign-in option offered was Google – the option to sign in with an Apple account was missing entirely, even though it was available to people using a computer. Which options you saw depended on the size of your screen. Now both options appear everywhere, so you can sign in with Apple from your phone’s browser just as easily as from a computer. The two buttons are stacked full width on smaller screens so the labels are easy to read and comfortable to tap.
other.sharePct in the category range report uses a different, incoherent denominator than sibling rows (KAN-1540) Percentages in your reports now always add up the way you would expect. Before, if a category or a payee ended a period with more refunded back to you than you spent or earned, its percentage could show up as a negative slice and push another percentage above 100%, which made the whole breakdown hard to trust. Now a refunded line keeps its real amount but simply shows a dash instead of a percentage, and every remaining percentage is measured against the same total, so the shares you see never add up to more than the whole. The Income vs Expenses report also gains a new breakdown showing which income sources and which spending categories contributed most to the period, with an amount and a share for each. And the Spending by Category chart now says “of spending” when you hover a slice, which is a clearer description of what that percentage actually measures.
sigma-collapse floor missing on gateEnterMergeCandidates / pending-bill indicator path (unfloored learned band) (KAN-1559) When a bill had been paid the exact same amount several times in a row, Tovari would only recognize that bill again if the next payment matched to the penny, so a payment that came in a cent or two different showed up as a separate, unmatched charge and the bill kept looking unpaid. Bills like that are now recognized within a sensible range around the amount you set, so the payment lines up with the bill automatically and the bill stops showing as still due. Amounts that are genuinely far off are still left alone for you to review, and if you have set your own upper and lower limits for a bill, those limits are respected exactly as you entered them. Separately, changes you make to a transaction that came from your bank are now remembered more reliably: edits are held onto correctly on every transaction, and repeating the same change no longer causes the app to keep track of it over and over. The rest of this update is behind-the-scenes work that protects those behaviors from quietly breaking in the future.
Mobile header: negative Safe to Spend not legible + Home/Budget lack an offline banner (HDR-2, HDR-3) (KAN-1604) When your Safe to Spend went negative, the amount appeared in a soft colour that was easy to mistake for a healthy balance – at the exact moment it mattered most. It now shows in a clear red alert with a short line telling you how much you are over, so an over-budget month is obvious at a glance and stays visible as you scroll.
We also added an “Offline – showing your last sync” banner to the Home and Budget screens, so when you lose your connection you can tell your numbers are from your last sync rather than live.
Home runway card: doubled top spacing + low-contrast legend amount ink (HDR-8) (KAN-1627) The Home screen’s spending breakdown card had a bit too much empty space at the top, and the dollar amounts in its legend were shown in a dark red that was hard to read against the card’s dark background. The card now opens with balanced spacing, and each amount appears in a brighter, easy-to-read red. Together these make it clearer at a glance where your balance is going. The improvement shows up automatically the next time you open Home – nothing to turn on.
Plaid attach mode is a second path to same-institution consent clobbering (no update-mode targeted attach) (KAN-629) Before this fix, linking a bank to an account you were already tracking by hand could quietly create a second connection to a bank you had already connected – and that second sign-in could cause your original connection to stop receiving new activity, with no warning or error. Now, when you link a bank to one of your accounts and that bank is already connected, the app recognizes it and simply asks which of the bank’s accounts belongs to yours, using the connection you already have. Your existing connected accounts keep updating normally, and no duplicate connection is created. If your account already has its own history, only new activity from today onward comes in, so nothing you entered by hand gets duplicated. And if you genuinely have a separate login at the same bank, you can still say so and connect it on its own.
Improvements
Section titled “Improvements”Migrate remaining modals onto useModalDialog and fix BottomSheet’s backward-focus-leak (KAN-1080) Pop-up windows across Tovari now behave consistently when you use the keyboard. Previously, if a pop-up was open but nothing on it was selected, pressing Tab could jump you onto the page hidden behind it, and pressing Escape did nothing at all – and several pop-ups, including the one that confirms closing an account, could not be dismissed with Escape or reached with the keyboard in the first place. Now every one of these windows keeps your place inside it while you tab through, closes when you press Escape, and returns you to whatever you were on when it opens and closes. The confirmation for closing an account starts on Cancel, so a stray press of Enter never archives an account by accident, and both of its choices now work properly with the keyboard. On phones, the sliding panels that come up from the bottom of the screen no longer let a backward tab slip out onto the screen behind them. Screen readers also announce these windows correctly now.
Fix the mint-inside-mutationFn idempotency key defects across the clients (KAN-1298) When you approved or dismissed a suggested transfer, or filed an alert from your review list, and the action could not go through, the app said nothing at all – the item could appear handled when nothing had actually been saved. Those actions now tell you plainly when something went wrong, leave the item exactly as it was so you can try again, and clear the message as soon as the next action succeeds. Undoing an approved transfer behaves the same way: if the undo does not take, the transfer stays linked rather than looking reversed when it is not. Separately, adding, renaming, deleting, and merging payees, along with saving your register view settings, are now protected against being applied twice if a request is sent more than once on a shaky connection. Each of your decisions counts exactly once, and pressing a button again after a failure retries that same decision instead of creating a duplicate. Together these changes make review and payee actions honest about what saved and what did not.
Converge PUT /dashboard/safe-to-spend-settings on the shared X-Idempotency-Key reader (hand-rolled parser at upsertSafeToSpendSettings.ts:26) (KAN-1355) Actions you take in Tovari are now safer to repeat. If a request was sent twice – because a connection dropped, a button was tapped again, or the app quietly retried in the background – the app used to sometimes treat the second attempt as brand new work. Setting up your categories could add ones you never chose, and undoing a recurring bill suggestion could come back with an error saying there was nothing to undo, even though the undo had already worked. Now a repeated request simply returns the result of the original one, so you see the same answer instead of a confusing error or an unexpected change. If a repeat genuinely asks for something different from the first attempt, the app stops and says so rather than silently doing both. We also cleaned up records left behind by the older behavior, so past activity is consistent with how the app works today.
No reconciliation sweep for the removeMember compensation-failed residual state (KAN-1401) Removing someone from your household now behaves more predictably when something goes wrong behind the scenes. Previously, if a removal could not be completed, the app reported a general failure even when the real cause was a temporary problem on our side, so there was no way to tell whether trying again would help – now a temporary problem is reported as exactly that, and trying again is the right next step. If the same removal request reaches us twice, from a double tap or an automatic retry on a shaky connection, the person is removed only once and the repeat simply returns the same result instead of acting a second time. When a removal does fail partway through, the app now puts that person’s access back exactly as it was before the attempt, so nobody is left half-removed. We also added continuous background monitoring that catches the rare case where a failed removal leaves someone’s sign-in out of step with their membership, so it can be spotted and corrected quickly. Nothing about how you remove a member changes – the steps are the same, the results are just more dependable.
Apply CognitoClientError -> 503 mapping to acceptInvite.ts Cognito calls (second KAN-1363 residual producer) (KAN-1438) We tidied up the messages Tovari shows when something goes wrong while signing in, resetting a password, or joining a shared household by invitation. Before, if our sign-in service was momentarily busy or unreachable, you could be told your email or password was wrong – so you would retype perfectly good details and get nowhere; now you are told plainly that the service is temporarily unavailable and to try again in a moment. When you accept an invitation and choose a password the service will not accept, you now get a clear explanation of what needs to change instead of a vague “try again later”, so you can finish joining right away. Invitation errors also no longer hint at whether an email address already has an account – every problem with an invite now gives the same neutral response, which keeps your details private. And in the rare cases where something unexpected happens, you will see a plain, readable message rather than raw technical text. None of this changes your accounts, balances, or day-to-day use of the app.
Register action row uses div onClick – Add Transaction and Reconcile are not keyboard-reachable (KAN-251) If you use a keyboard instead of a mouse, several buttons in the transaction register were impossible to reach – you could see them, but tabbing never landed on them and pressing Enter did nothing. That included Add Transaction, Add Scheduled Item, Edit account and Reconcile at the top of the register, the row menu with Edit, Make recurring and Delete, the Save and Cancel buttons when editing a row inline, and the prompt that offers to match a possible transfer. All of these are now proper buttons: they take focus as you tab, show a clear focus outline, and respond to Enter. Buttons that are not available right now – Reconcile before an account has loaded, or Save while a save is already in progress – are correctly skipped over and cannot be triggered by accident. Screen readers now announce these controls by name and, for the row menu, whether it is open or closed. Nothing about the register’s appearance or behavior changes when you use a mouse, and one control, the small circle that marks a transaction cleared, is still mouse-only and is being handled separately.
Merged bill_payment_history rows keep source=‘manual_entry’ so the observed learned band never narrows (KAN-511) When you recorded a bill payment yourself and your bank later reported the real charge, the app kept your typed figure on record and often listed the bank’s version of it as a second, duplicate payment – and bills paid at merchants whose bank descriptions carry extra text, such as a payment reference or a longer company name, were also often missed entirely and treated as brand-new spending. Those payments are now recognised and combined into one, using the amount your bank actually charged, so a bill that varies month to month still lines up even when the amount and the date differ slightly from what you entered. Because the app now learns from real charges, it gets better at spotting each bill over time, while still leaving plenty of room for normal month-to-month variation and always respecting any amount range you set yourself. Your own edits are also protected more precisely: if you only changed a transaction’s category, that choice sticks while your bank’s final payee name and date still fill in as usual, instead of the whole transaction being frozen. And when your bank withdraws a transaction it reported in error, the app now clears it out even if you had already edited it, while carefully leaving alone anything tied to a reconciled statement, a transfer, or a bill payment you have already recorded.
AcceptInvitePage inputs are 14px – iOS auto-zooms the invite accept form (KAN-523) Using Tovari on a phone is easier now. Several buttons and controls were too small to tap reliably – the retry button on cards that failed to load, the cancel and close buttons when adding an account, the account picker, the bank-history dropdown, and the link on your policy cards – and they are all comfortably sized on a phone from now on. When you accepted an invitation to join a household, tapping into a field would make the page jump and zoom in; the fields are now large enough that the page stays put, and the show-password control is easier to hit and works with a keyboard. On the policies screen you can also give your consent using just the keyboard, and opening the full policy no longer changes your consent by accident. On the bills screen, screen readers now correctly announce which tab you are on and read the matching list beneath it. Everything looks and behaves exactly as before on a computer.
Extract db-client PG error mapping to a testable mapPgError (40P01/57014 have zero test coverage) (KAN-575) When a lot of activity happens at the same moment, the app occasionally has to stop and unwind a change part-way through so nothing is saved incorrectly. Until now, that brief moment was reported to you the same way as a genuine failure – a generic error message that gave no hint whether trying again would help. It now tells you plainly that things are busy and that nothing was changed, so you know the right response is simply to try again in a moment. This applies everywhere the app talks to your data, including signing in, managing payees, and loading your category and reference lists. Nothing about your accounts, transactions, or balances changes, and no action you took is affected. Behind the scenes, the way these interruptions are recognized and reported has also been reorganized so it stays consistent and easier to keep correct going forward.
Make-recurring seed anchors monthly bills to the 1st, not the transaction date (KAN-630) When you turned a transaction into a recurring bill, the app set the monthly due day to the 1st no matter what day the original transaction fell on, so you had to correct it by hand every time; the bill now starts out on the same day of the month as the transaction you created it from, including the 29th, 30th, and 31st. Opening the Make Recurring window is also easier from the keyboard: your typing stays inside the window, and pressing Escape closes it without saving anything. If a payee suggestion list is showing, that first Escape just closes the list and leaves everything you have entered untouched, so a stray keystroke can no longer wipe out a bill you were part way through setting up. Finally, choosing Save on a transaction you opened but did not actually change now simply closes the editor instead of resaving the row, which had been quietly stopping bank-linked transactions from picking up later updates from your bank. Changing something and saving works exactly as before.
parseAccountIds fails open: a malformed UUID silently drops the whole account filter in every report handler (KAN-652) When you filtered a report down to specific accounts, an account selection the app could not recognize was quietly discarded – instead of telling you, the report came back covering every account you have, with nothing on screen to signal that your choice had been dropped. Reports now say plainly that the account selection was not understood, so the totals you see always match the accounts you actually picked. Every report and every drill-down within a report answers the same way, so a detail view can no longer disagree with the summary it came from. Payee search has been corrected too: typing a percent sign or an underscore used to be treated as a stand-in for “any characters”, so those searches returned far more payees than they should have. Those characters are now matched exactly as typed, so searching for a payee whose name contains one finds that payee instead of a flood of unrelated ones. Nothing about your accounts, transactions, or balances changes.
Case (b) + “Enter now”: bank’s posted amount is never applied on same-id institutions (KAN-822) We fixed several ways your bills and bank-linked transactions could fall out of sync when your bank removed, changed, or reversed a transaction. Previously, if a transaction that had already paid a bill was later pulled back by your bank, the bill’s due date and payment history could stay stuck as if it had still been paid. A similar problem could leave a transaction you’d manually matched to your bank feed in a confusing in-between state after that transaction disappeared from your bank. We also improved what happens when your bank posts a transaction for a slightly different amount than what you’d already recorded – instead of silently overwriting your entry, the app now adds a small adjustment so your account balance stays accurate while keeping the amount you entered intact. These changes make your bills, transaction history, and account balances more reliable and consistent after any change your bank makes to a transaction.
Category render metadata (color + icon) must come from the API on every endpoint mode – harmonize web and mobile category coloring (KAN-941) Categories now display the same color everywhere in the app. Previously, a category could appear as a different color on the web dashboard, the web reports screen, and the mobile reports screen. Now the color you chose for a category is consistently used across all of these views. The only exception is charts that show a very large number of categories at once, where unique computed colors keep them visually distinct. The dashboard spending cards also now show the same percentage figures as the full reports screen, eliminating minor rounding differences that could appear between the two.
KAN-931 tech debt: Matching root cause (deliberately not widened into KAN-931): billScore’s name term in… (KAN-957) Marking a scheduled bill as paid could leave you with the same payment listed twice – once from the bill and again when your bank’s copy of it arrived – and clearing that up meant deleting a row by hand. Bills paid at merchants whose bank descriptions carry extra text, such as a payment reference or a longer company name, were also often missed entirely and treated as brand-new spending. Now a bill you mark as paid is recognised as the same payment your bank sends, and the two are kept together as a single entry in your register, even for banks that report a payment while it is still pending. When the payment finally settles, the amount and date recorded against that bill are updated to match what your bank actually charged, so your payment history and the amounts the app learns from it stay accurate. Importing a file that includes a bill you have already paid no longer records the payment a second time, and the transaction still appears in your register as normal. When a bill is matched to a payment already in your register, the app now tells you so instead of implying a new entry was created, and your Safe to Spend figure updates right away.
KAN-931 tech debt: Hardening (belt-and-braces, deliberately deferred from KAN-931): add a DB unique constraint on… (KAN-960) Previously, the app could record the same bill payment more than once. This could happen when an imported bank file contained two similar charges near a bill’s due date, when a bank connection re-processed a payment it had already recorded, or when a bill’s next payment date was moved back to a date that had already been paid and then entered again. Each duplicate quietly distorted the bill’s payment history and your spending picture. Now every bill payment can only be recorded once: if you try to enter a payment for a date that is already paid, the app clearly tells you instead of recording it twice, and file imports and bank syncs simply record the extra charge as a regular transaction rather than a second bill payment. Any duplicate bill payments that were recorded in the past are cleaned up automatically, with no transactions deleted.