Finance apps ask to be trusted. A spreadsheet is trusted for the opposite reason: you can click the cell and read the formula. This page is the audit trail behind the Sonuswealth numbers: where each rule comes from, how a headline figure decomposes, which build gates fail when a figure drifts, and what happens when we don't know.
The reason a lot of careful people still run their finances on a spreadsheet is not nostalgia. It is that a spreadsheet has no opinions it can hide. Every figure is a formula, every formula is one click away, and when a number looks wrong you can find out why yourself, in about ten seconds, without asking anybody's permission.
What a spreadsheet cannot do is keep up. Tax rules move every April. Thresholds freeze, unfreeze and taper. A tab built in 2019 quietly carries a personal allowance that stopped being true two Budgets ago, and nothing in the file says so. The maintenance is the reason people eventually give up and buy an app, and the app takes the maintenance off their hands by taking the visibility with it.
We think that trade is unnecessary. The spreadsheet's virtues are properties of a build, not properties of a file format: one source for every constant, a formula attached to every result, a loud failure when two figures disagree, and a blank cell rather than a plausible guess. So we built those in, and this page is where we show the receipts rather than describing the philosophy.
A caveat before the receipts, because it matters to the kind of reader this page is for: Sonuswealth is not open source. The repository is private, so nothing below is something you can independently compile and check today. These are our claims about our own build and our own automated gates. Read them as a description of how seriously the checking is taken, not as proof you have verified yourself.
Inheritance tax is the figure people most want to argue with, so it is the right one to open. In Sonuswealth the estate bill is not a number that appears. It is the last row of a chain, and every row above it is on screen.
One function inside the engine produces that chain. It returns the stages in order, and the surfaces render them: the estate cards on Tax & Estate, the drill panel behind them, and the plain-English story beside it. The gifting decision calls the same function, which is the point. The estate screen and the gifting screen cannot quietly disagree about your inheritance tax, because there is only one calculation and they both read it.
Every one of those stages is a row the engine returns, not a description we wrote for this page. Rows that do not apply to you show as nil rather than vanishing, so the chain always adds up on screen.
A single person, no spouse's allowances to inherit, a home passing to children, nothing given away and nothing in trust. Only two of the fourteen stages bite. The two allowance figures below, and the rate, are read from the rules file at page load. The last two rows are computed in your browser from those figures rather than typed by us.
| Stage | Amount |
|---|---|
| Estate as valued | £900,000 |
| Less the nil-rate band | −£325,000 |
| Less the residence nil-rate band | −£175,000 |
| Taxable estate | £400,000 |
| Inheritance tax due, at 40% | £160,000 |
This page is itself an example of the discipline. The band figures carry a rule name; the two results carry an expression over those rule names. A check runs that expression with the same parser your browser uses and compares it to the text printed here. If the two ever disagree, the build fails before the page ships. Change the bands at a future Budget and every figure in that table moves together, including the ones nobody remembered were arithmetic.
Same discipline, worked at length, in the case studies and on Tax & Estate.
There is no tax constant typed into a screen. The engine reads a single rules bundle for the tax year, and every calculation reads the bundle through one loader. Change the file, and the whole app changes with it.
The bundle carries a version string, the tax year it describes, the date it starts and the date it stops applying, and a note on how its figures were verified. A calculation dated outside that window is a different bundle, not a fudge of this one.
Each release carries a correction log: the values that moved since the previous version, with the reason next to each. When the State Pension figure was found to be a stale year's rate, the fix and its cause were written into the file rather than quietly overwritten.
Bundles for previous tax years sit alongside the current one, and the loader can be pointed at any of them. That is what makes a back-test honest: a 2023 answer is computed with 2023 rules, not this year's.
A separate registry holds no figures of its own. It points at the tested bundle. What it adds is provenance: for the headline rules it names the publisher, the page, the date we read it, a plain-English gloss and a worked example. Read the honest limit on that in what we don't show yet.
This site is downstream of the same file. The figures quoted across these pages are not maintained here. They are generated from the app's bundle by a script, and a check re-runs that script and fails if the site's copy is not what it would write. A second check ties each of those figures back to its exact path inside the bundle, so drift is caught as drift rather than discovered by a reader.
That is also why the numbers in the table above are wrapped rather than typed. A typed figure is frozen at the day somebody typed it. A wrapped one follows the law.
A promise nothing enforces decays. These are automated checks, not intentions: each one blocks the commit, the merge or the deploy when it trips. Several exist because the thing they check went wrong once.
A set of golden vectors is worked out from statute and published thresholds by hand, deliberately not derived from the engine, so agreement means something. The engine must land within a pound of each. They run in the continuous-integration pipeline on every push.
A separate battery re-derives figures from first principles. It reports three outcomes, not two: engine versus first principles, where a miss is an engine bug; bundle versus law, which is flagged for a human rather than asserted; and could-not-verify, with the reason. A check that publishes what it could not check is worth more than one that quietly passes.
A baseline of persona-by-tax-year snapshots runs nightly and on every push that touches the engine or the rules. If any figure moves, the build fails until somebody deliberately re-records the baseline. Silent numeric drift is the failure mode this exists to make impossible.
Every read of a tax constant is checked against the keys the bundle actually builds, because a mistyped key does not crash. It falls back and renders a wrong number in silence. A small denylist also fails the build on specific figures known to be out of date. Both run early, before the build.
The deploy resolves which database region the release will actually use and compares it to the region the published privacy notice claims. If they disagree, the deploy stops. This exists because on one day in August 2026 they did disagree: the notice said London while the deployment used Ireland. The guard is the fix; the honest account is on Trust & Security.
Any money or percentage in text generated by the AI assistant is compared, by value, against the figures the engine actually produced, including numbers written out in words, so "one point two million pounds" cannot slip past a check looking for digits. Every ambiguity resolves toward rejection. A false reject costs one answer; a false accept shows you a fabricated number.
A family of tie-out tests asserts that a total shown in two places is the same total: the ledger against the tree, net worth against the estate, pensions across their surfaces, income against tax. They exist because the same pension once read three different values on three screens.
On this website, a check counts every figure printed by hand that the app already owns as a rule. The count is allowed to fall and is never allowed to rise: type one, and the build fails. It is deliberately not a target of zero. A worked example using an invented salary is a scenario, not a constant.
There is one more that is worth stating precisely because it is uncomfortable. A cross-repository check compares the legal wording published here against the wording shipped in the app. It currently cannot run. It needs a token that has not been wired up. Rather than reporting itself as skipped and appearing green in the checks list, it fails loudly and says so, because a guard that skips quietly is worse than no guard: the reader takes "skipping" for "not applicable". That lesson also came from the residency mismatch above.
The most common way a finance app misleads you is not a wrong calculation. It is a confident zero standing in for a figure it never had, and a zero is indistinguishable from an answer.
So the engine carries an explicit flag that means this is absent, not measured, and the interface reads that flag rather than testing whether the value happens to be zero. A genuine nil, no liabilities and nothing owed, still prints as nil, because that is a real answer. A missing one prints a dash, with a line underneath saying we don't have enough of your data to show a real figure here yet, and pointing at the screen where you would add it.
Monthly surplus is a good example. With no income recorded, the arithmetic would happily return nil, and nil surplus reads as a real, alarming finding. Instead the metric marks itself insufficient, shows a dash, and swaps its explanation for the one that is actually true: add your income and outgoings and this will mean something.
When a decision has no model behind it yet, the panel does not print a growth rate and a horizon. Stating them would invent a projection. It says instead that Sonuswealth does not yet calculate a figure for this decision, which is less impressive and more useful.
A figure's origin can be recorded from your entry, taken from a live average, or read from a document, and nothing else. The code rejects any other label outright rather than accepting a vague one, so "computed from your data" is a floor, never a decoration.
Two test suites exist only to catch the quiet failures: a missing rule that coerces to zero and produces a withdrawal rate of nothing with no error, and a chart that renders nothing at all while every other check stays green. Both had happened before the tests were written.
There is a companion habit on this website. Where a figure has nothing behind it but a language model's recollection, it is counted and listed as such by a check, rather than presented alongside sourced figures as if it were one of them.
The page is called "show your working", not "every number in the product shows its working". Here is the difference, stated by us rather than found by you.
A defined set of headline metrics opens into a panel naming the rule, the formula, the source and the assumptions: net worth, the wealth and risk scores, monthly surplus, the liquidity buffer, the funded ratio, the cost of inaction, the estate, gifting and tax plans, monthly income and essentials, alongside the retirement route and the decision engine. Numbers outside that set are computed by the same audited engine, but they do not yet open.
Parts of the drawdown work still label themselves as showing a convention rather than a derived answer, in the product, in those words. We would rather ship the label than quietly ship the convention.
The registry that carries a publisher, a URL and a read-date covers the headline rules, not all several hundred values in the bundle. Its entries also carry a flag marking them as awaiting external verification, which is not the same as verified. The rest of the bundle carries internal rule identifiers and notes instead.
Hundreds of figures across these pages are typed rather than wrapped. The ratchet stops the number rising and it has been falling, but it is not zero, and any typed figure is frozen at the day it was written.
The golden vectors and the independent audit were green on disk for months before anything ran them automatically. That was found and fixed in August 2026. "It runs on every commit" has been true for weeks, not since the beginning, and we would rather you heard that from us.
The repository is private. There is no build you can reproduce and no source you can read. Independent review by people outside the company is on the plan before launch; it has not happened yet.
Information and guidance only. Sonuswealth is not authorised by the Financial Conduct Authority and does not give regulated financial advice. The arithmetic on this page is an illustration of how the product decomposes a calculation, not a recommendation, and not a statement about your own tax position. Inheritance tax depends on facts specific to an estate: residence, domicile, trusts, business interests and gifts among them. Take advice from a qualified professional before acting. Published 29 August 2026 · figures read live from the UK 2026/27 rules bundle.
More on the build: how it works · the product · trust & security · pricing · insights