We flagged a stage that turns deals into revenue as a dump
This is a post-mortem of our own mistake, not a success story. Thresholds tuned on a one-month export drifted on the full history of the same account: mid-funnel conversion came out several times lower than the truth. Below: what we saw, which line of code caused it, what we fixed and what we deliberately did not. The conclusion is built into the product — the algorithm proposes the stage markup, a person confirms it.
Why a single label on a stage costs so much
Every live pipeline has stages that are not sales steps. On the pilot account those are “NEW PROJECT REACTIVATION”, “No contact” and “Deferred demand”. A deal goes there when the client could not be reached or asked to come back in six months. Deals leave a parking stage forwards, backwards and sideways, and can visit it more than once.
The stock “Sales analysis” report keeps such stages in the chain alongside sales stages, and conversion collapses for no reason: 84% at “Taken into work” turns into 66% on the parking rows. We mark parking stages up and exclude them from the calculation. Hence the price of the label: an error one way leaves a parking stage inside the chain and understates conversion; an error the other way throws a real sales stage out of the chain. We did the second.
anonymised property developer account · cumulative funnel over 32,478 deals · stock amoCRM “Sales analysis” report
What happened
Until then the core had been computed on a one-month export, and the thresholds worked on it. The first run over the full history of the same account — all 7 years — gave nothing away: the report finished and showed a different funnel. In the middle of it stood a conversion of 6.1% where the same period actually has two real steps, 26.7% and 22.2%.
Had a head of sales opened that report, they would have made decisions about people using a number that does not exist. This is the kind of bug monitoring never catches: everything green, nothing crashed, and all of it wrong.
The cause was not one stage. The heuristic thresholds were calibrated on a one-month export; on the full history it declared 7 stages of the main pipeline parking instead of 3. Only 3 stages kept a position in the sales chain, and mid-funnel conversion for the month collapsed into a single step: 48 of 782, that is 6.1%. The stage-skip flag was wrong too — across all 240,031 transitions in the account.
The real parking stages were joined by 4 sales stages — the entire middle and end of the funnel:
| Stage | What the heuristic decided | What it actually is |
|---|---|---|
| “Client qualified” | parking, exclude from the calculation | sales stage, 216 deals entered in the month |
| “KEY MEETING HELD” | parking, exclude from the calculation | sales stage, 46 deals entered in the month |
| “Flat reserved” | parking, exclude from the calculation | sales stage, 3 deals entered in the month |
| “Contract signed” | parking, exclude from the calculation | sales stage, 1 deals entered in the month |
anonymised property developer account · full history, 7 years · reviewed 25.08.2026 · docs/РЕШЕНИЯ.md, item 41
One step instead of two: the second, 22.2%, vanished with the discarded stage. This is the very number a head of sales would see on the first screen.
anonymised property developer account · full history, 7 years · reviewed 25.08.2026 · docs/РЕШЕНИЯ.md, item 41
The cause is one line of code
One of the parking signals: “deals mostly leave this stage for closure, so it is a dump”. The threshold is 50% of exits to closure with a base of at least 200 entries. The signal read the share of exits to closure as a sum: wins and losses together.
On the full history the “Contract signed” stage has 272 closures, 266 of them wins — 98%. A stage that turns deals into revenue was called a dump. A win is the end of the journey, not its absence, and the signal did not tell the two apart.
anonymised property developer account · full history, 7 years · reviewed 25.08.2026 · docs/РЕШЕНИЯ.md, item 41
Why it did not show on the monthly export
The closure share measures the depth of the observation window, not a property of the stage. Within a month half the exits have not happened yet: the deal sits on the stage and waits. Over 7 years almost nothing is cut off — everyone who could close has closed. So over time any stage starts to look like a dump, and the longer the account history, the stronger the effect.
This is a general rule, not a special case. Any signal with the share of what has already happened in its numerator behaves differently on a long window than on a short one. We did not account for that and calibrated the thresholds on what was at hand.
What we fixed
The signal now reads losses only. Measured on the same full history: 3 of 4 false positives cleared, the real parking stages were untouched. “No contact” has 72.6% of exits to lost, “Deferred demand” 80%; both remain parking stages, as they should.
The review proposed several more changes, including a rolling one-year observation window. A run on the live database showed the window breaks the reference: it loses “Deferred demand”, i.e. puts a real parking stage inside the sales chain. We took one change that is right in substance, not a bundle of changes that produce a pretty picture on one account.
anonymised property developer account · full history, 7 years · reviewed 25.08.2026 · docs/РЕШЕНИЯ.md, item 41
The fourth false positive we did not fix
“Client qualified” stayed marked as parking after the fix. It has 70% of internal exits to lost. The real parking stage “No contact” has 72.6%. By this signal they are indistinguishable.
A threshold that separates them is easy to pick, and it would work — on one account, the very one it was picked on. That is overfitting: the next client would get a report built on a number that cannot be defended. We left the threshold alone and handed the decision to a person.
anonymised property developer account · full history, 7 years · reviewed 25.08.2026 · docs/РЕШЕНИЯ.md, item 41
What it taught the product — and what it gives you
The heuristic proposes, a person confirms
The markup at connection is not a formality or a setup wizard to click through. It is the only place where the algorithm’s mistake is caught by someone who knows their pipeline. There is no confirmation screen in the widget yet: the mechanism is written and covered by tests, and we agree the parking list by email and set it on your account.
Result: no label lands on your stage until you have confirmed it.
Confirmation changes the whole calculation
This is where the second bug was: confirmation changed the stage kind but did not give it a position in the sales chain — the stage became a sales stage and still dropped out of the conversion. Now confirmation recomputes positions and skip flags in a single transaction.
Result: return a stage to the chain and conversion and skips are recomputed with it, not a week later.
The thresholds are stated openly
The signal values and thresholds are in the documentation, not only in the code. If the markup on your pipeline looks odd, you can see which signal put a stage into parking and disagree.
Result: an argument about the markup is about a signal and a number, not about whom you trust more.

Demo data · anonymised property developer account · July 2026
What this post-mortem does not prove
The entire calibration is one account. Thresholds tuned on its monthly export drifted on its own full history. What happens on the second and third account we do not know. There will be no “property developers usually…” on this site until there are more accounts — and when there are, there will be a second post-mortem, with whatever breaks in it.
How everything else is counted — the KLASTER counting rules. How the markup looks in the interface and what to do if the heuristic got your pipeline wrong — stage markup and parking.
See how a live pipeline is marked up
In the demo, parking stages are excluded from the chain and listed separately with their own numbers — you see both the markup and what it changes in conversion. No sign-up and no access to your CRM.