Skip to content

Forecasting

A forecast that publishes its own arithmetic

A revenue forecast is a claim. If the page does not show how each dollar was placed, and what it refuses to vouch for, it is a guess with a chart on it.

Published
26 August 2026
Reading time
5 min
Written by
Elliot Saha

Every revenue forecast is a claim about money that has not arrived yet. Most are presented without the working. Someone rebuilds the model in a spreadsheet each quarter, a number lands on a slide, and the only person who can defend it is the person who built it.

The test we use is simple. Can the controller defend each line to a board member who is trying to disprove it. If the answer is no, the forecast is not a forecast. It is a guess with a chart on it.

Here is what it took to pass that test at SMT Research, and the three habits that did most of the work.

The diagnostic came before the forecast

Three systems held pieces of the same book of work. A retiring ERP, the live Salesforce org, and the accounting ledger. Nobody had asked them to agree.

All three agreed on the size of the book. They disagreed on how much of it was done. One counted installed, another counted invoiced. That gap is work physically finished and never billed.

3Of finished work never invoicedDerived from the gap between installed value and invoiced value across three systems that agreed on the size of the book. Pre-tax, one client, one point in time.

No model produced that. It fell out of making three systems answer the same question in the same units. The engagement paid for itself before the forecasting engine existed.

Every row says how its dollar got there

The engine writes one row per order per month, and each row carries a method string naming the rule that placed it. Five rules, applied in priority order.

  • Work already finished is dropped, not spread. There is nothing left to bill.
  • Work with a billing window spreads across that window on an 80/20 split between billing and closeout.
  • Recurring work spreads evenly across twelve months.
  • Undated work lands in the current month and is flagged as undated rather than quietly placed.
  • Legacy dates fall back to straight-line, with stale dates collapsing to the current month.

Two invariants sit on top. Revenue never lands in the past, because a forecast that projects into last quarter is a data error wearing a number. And rounding drift is corrected on the final row so the rows sum to the total exactly.

A method string costs one text field. What it buys is that a challenge to a given month is answered with a row and its rule, in about a minute, rather than by rebuilding the model and hoping it lands on the same figure twice.

The bridge is printed on the page

The board headline is not presented as a single number. It is presented as the arithmetic that produced it.

  backlog                     remaining to bill, open orders
- PM-finished                 marked finished, never to be invoiced
= from orders                 what the engine actually spreads
+ pipeline                    open opportunities at 75% or better, unsigned
= projected                   the board headline
The reconciliation bridge, rendered above the chart

Five lines. Anyone can check the arithmetic, and anyone can attack one line without attacking the whole number. That is the point. A figure nobody can argue with in detail is a figure nobody trusts in general.

And so is what it refuses to vouch for

On the same page as the headline, in the same type size, the forecast states its own weak spots.

  • 49 orders are past their end date and still counted as fully billable, with nobody having marked them finished.
  • 23 orders have no billing window at all, so their placement is the weakest rule in the engine.
  • Nine orders were invoiced past their contract value, and each one is named.

That list looks like an admission of weakness. It is the opposite. It converts three vague doubts into three work queues with owners, and it means the rest of the number is not carrying their uncertainty silently.

What the weak spots were actually worth

The largest was date staleness. 115 of 154 open orders had an end date that was blank or in the past. A structured refresh with the delivery team came back with all 153 remaining orders answered.

  • The stale-date bucket went from 99 rows to zero.
  • The total projection fell once the dates were real.
  • Phantom finished-but-still-projected work left the forecast.

The forecast got smaller. It also got true. A forecast that only moves up when you improve it is not being improved, it is being tuned to an audience.

Two guardrails worth copying

Migration windows create duplicate invoices, so an invoice counts as a duplicate when it falls inside the transition window and matches another within one dollar and seven days. Both bounds are stated on the report rather than tuned quietly.

Any single invoice above a stated ceiling is excluded as a data error, and every exclusion is listed by record. A filter that removes rows without naming them is how a phantom invoice survives a migration.

The one-line version

Publish the bridge, publish the method behind each row, and publish what the number does not cover. The arithmetic is easy. The discipline is agreeing to show it.

None of this is sophisticated. It is arithmetic with its receipts attached. It is rare because printing the weaknesses feels like weakening the number, and it is worth doing because the opposite is true. The forecast that names its own gaps is the one that survives the meeting.

Written by

Elliot Saha

Co-founder and Chief Technology Officer

Elliot owns Salesforce platform architecture at ShareCo. He spent the last year embedded as sole architect, administrator and developer on a single enterprise org, and most of what he writes here came out of that.

Read next
Bring us the hard one

Bring us your hardest Salesforce problem

Send the concrete version of it. You get a written read within one business day, a 30-minute call, and a written diagnosis whether or not you hire us.

  • Reply in one business day
  • Vancouver, British Columbia