Divergences from the reference Excel¶
Suno's valuations began life in a spreadsheet. This engine is not a transcription of it: in ten places it deliberately computes something different. Each of those ten is a correction of something the spreadsheet got wrong, and each moves the published number.
This page lists all ten and, where it was measured, the exact effect on NPV and NAV. If you are reconciling a Suno valuation against a copy of the original spreadsheet, this page is the list of gaps you should expect to find before you conclude anything is wrong.
How these numbers were measured¶
The reference project — the one pinned in the repository's golden-master
fixture, tests/fixtures/golden_valuation.json — was re-run after each
correction, and the fixture's _note field records the resulting figures.
Every number quoted below comes from that field verbatim.
Three things follow from how the trail was kept, and they limit what can be claimed:
- The first pinned values (12 July 2026) already included corrections 1 to
- They were measured against the spreadsheet as a group, not one at a time, so there is no per-correction figure for any of them.
- Corrections 7 and 10 were re-pinned in a single step, so their effects are known together, not separately.
- Corrections 8 and 9 were each re-pinned on their own, so their effects are individually measured.
All the figures are for this one reference project. The direction of each correction generalises; the magnitude does not — the mid-year convention, for instance, is worth more on a long-dated project than a short one.
The chain of measured values¶
| Step | NPV (USD) | NAV per pWatt (USD) | Change in NPV |
|---|---|---|---|
| First pin, 2026-07-12 (corrections 1–6 already applied) | 1402670.193 | 1.0386302796 | — |
| After corrections 7 and 10 (audit, B2 + B3) | 1405747.095 | 1.0409086227 | +0.219% |
| After correction 8 (audit, S2) | 1470010.328 | 1.0884933933 | +4.57% |
| After correction 9 (audit, S3) | 1464124.622 | 1.0841352254 | −0.400% |
The last row is the currently published reference result. To full precision,
the engine returns npv_usd = 1464124.6218754272 and
pwatt_nav_usd = 1.0841352253798053, and the test suite pins both to the last
float digit: a change to the arithmetic that moves either one fails the build.
The ten divergences¶
1. PPA prices are indexed to the target year¶
The spreadsheet carried the PPA price curve at its stated values. The engine treats each point as a price in the money of the curve's base year and escalates it — by PPI, by CPI, or not at all — to every year it is applied to. A tariff is a price level, not a constant.
Measured effect: included in the first pin; not measured separately.
2. The CPI escalation base is the evaluation year¶
O&M and REC prices are expressed in today's money — the invoices are recent — so the engine escalates them from the evaluation year. The spreadsheet escalated from the commissioning year, which counts the inflation already embedded in those figures a second time, inflating every future cost and revenue line derived from them.
Measured effect: included in the first pin; not measured separately.
3. Degradation is normalised over measured production¶
Metered generation already reflects the degradation the panels have suffered. The spreadsheet projected it forward and then applied the degradation ladder on top, counting the loss twice. The engine normalises the measurement back to year-zero terms first.
Measured effect: included in the first pin; not measured separately.
4. The fee is charged on total revenue¶
The Suno fee applies to energy sales, REC sales and additional income alike. The spreadsheet charged it on energy revenue only, understating the cost to the project.
Measured effect: included in the first pin; not measured separately.
5. Age has no off-by-one, and there is one day-count convention¶
The spreadsheet's age calculation subtracted one, making a project's age negative on the day it was commissioned, and used more than one day count in different columns. The engine measures age from the commissioning date, zero on day one, with 365.2425 days per year everywhere.
Measured effect: included in the first pin; not measured separately.
6. Invoiced O&M is averaged and blended with the projection¶
Rather than taking a single projected figure, the engine averages the actual invoices and blends that average with the projection. The average is deliberately a plain one — annual charges such as insurance and land lease are real costs that fall in specific months, not outliers to be trimmed away.
The blend weight has since been corrected again, from the project's age to the billing coverage of the last twelve months, on the reasoning that an average of four invoices has probably never seen the insurance premium however old the plant is. The fixture's audit trail records no re-pin for that change, so no figure is quoted for it here.
Measured effect: included in the first pin; not measured separately.
7. The efficiency blend weights are the right way round¶
Row n of the efficiency ladder spans a commissioning anniversary: part of the year runs on degradation step n−1 and part on step n. The spreadsheet paired the weight of the first part with step n+1 — exact only for a plant commissioned on 1 January, and biased for every other one.
Measured effect: together with correction 10, NPV 1402670.193 → 1405747.095 (+0.219%), NAV 1.0386302796 → 1.0409086227.
8. Cash flows are discounted at mid-year¶
The largest of the ten. The spreadsheet discounted each year's flow as if it arrived on 31 December. A solar plant bills monthly, so the flow's centre of gravity is the middle of the period. The engine compounds the full discount factors of the earlier rows and half of the current row's — see the discounting phase.
Measured effect: NPV 1405747.095 → 1470010.328 (+4.57%), NAV 1.0409086227 → 1.0884933933.
9. Telemetry is normalised at its window's midpoint¶
When metered production is normalised back to year-zero terms, it is divided by the panel efficiency at the midpoint of the measurement window, not at the evaluation date. Twelve months of readings were produced when the panels were on average six months younger; dividing by today's efficiency inflated year-zero production — always in Suno's favour.
Of the corrections whose effect was measured, this is the only one that moves the published number down.
Measured effect: NPV 1470010.328 → 1464124.622 (−0.400%), NAV → 1.0841352254.
10. Rows with no cash flow are priced at zero, with no lookups¶
A calendar row entirely in the past carries no cash flow, so its energy price is zero and the engine performs no PPA or macro lookup for it. The spreadsheet's lookups on those rows required data for historical years that cannot affect the result, and an old plant valued with a recent macro series simply failed.
Measured effect: together with correction 7, NPV 1402670.193 → 1405747.095 (+0.219%), NAV 1.0386302796 → 1.0409086227.
Reading this list fairly¶
Of the three measurements above, two raise the valuation and one lowers it; the first six corrections were measured only as a group, so their individual directions are not separable. That balance is worth stating plainly rather than leaving a reader to find it, and it is a fair thing to probe: a model whose corrections mostly favour its author deserves the scrutiny.
What can be checked is that each correction is defensible on its own terms, independently of which way it moves the number — the mid-year convention is standard practice in project finance and would be applied by any reviewer; double-counted inflation and a double-counted degradation are errors under any sign convention. The one correction that moves the number down, the telemetry midpoint, was found and applied by the same audit that found the others.
If you disagree with any of them, the arithmetic is in the open and the disagreement is testable. Open an issue with the Calculation defect template.