Cascadia Portfolio · Revenue Assurance
A subscription-licensing book with three timing rules: adding licences takes effect at once, reducing them waits for the next term boundary, and cancelling rides out the term. The order register records what each customer asked for. The billable quantity is derived from the event stream and the rules, and the two sit apart for up to a year on an annual term with nothing erroring and no register showing it.
Whether to keep invoicing from the register's current quantity, or to derive the billable quantity from the event stream and the rules and reconcile the invoice to it.
The reader is the finance or revenue-operations owner who signs the monthly invoice run and is accountable for the number on it. The benchmark is the register's own quantity, the naive answer. Invoices are computed from the effective quantity; the register is what the customer and the partner see. The gap between them is money correctly billed that the register does not show. Billed from the register instead, June 2026 would under-bill by $59,264. Every chart below shows where the two quantities part ways, and by how much.
Effective licences at 2026-06-30
102,554
Billable under the rules, summed across every subscription effective that day (M-01).
Register licences at 2026-06-30
96,679
What the register shows: the last quantity each customer asked for (M-02).
Entitlement gap
5,875 licences
$59,264 per month at the term rates, 5.5% of the month's billable (M-03). The register never exceeds the effective quantity, so the gap is never negative.
Subscription-months carrying a gap
8.9%
4,467 of 50,110 subscription-months across the 24-month window.
Most common wait 330–359 days; the right tail is partly the window's edge
| Days pending | Monthly term (orders) | Annual term (orders) |
|---|---|---|
| 0–29 | 580 | 32 |
| 30–59 | 35 | 53 |
| 60–89 | 0 | 44 |
| 90–119 | 0 | 50 |
| 120–149 | 0 | 67 |
| 150–179 | 0 | 58 |
| 180–209 | 0 | 65 |
| 210–239 | 0 | 80 |
| 240–269 | 0 | 67 |
| 270–299 | 0 | 64 |
| 300–329 | 0 | 100 |
| 330–359 | 0 | 116 |
| 360–389 | 0 | 49 |
| Term type | Order label | Orders | Median days | 90th pct days | Min | Max |
|---|---|---|---|---|---|---|
| Annual | REDUCE | 526 | 235 | 353 | 2 | 365 |
| Annual | CANCEL | 279 | 226 | 353 | 1 | 364 |
| Annual | ADD | 40 | 152 | 275 | 18 | 352 |
| Monthly | REDUCE | 403 | 16 | 28 | 1 | 31 |
| Monthly | CANCEL | 212 | 17 | 29 | 1 | 31 |
63% of annual gap licences are cancellations still billing
| Term type and cause | Licences | Dollars per month | Subscription-months |
|---|---|---|---|
| Annual — cancellations riding out the term | 3,556 | $35,560 | 127 |
| Annual — deferred reductions | 2,062 | $20,620 | 221 |
| Monthly — deferred reductions | 136 | $1,632 | 12 |
| Monthly — cancellations riding out the term | 121 | $1,452 | 15 |
June 2026: 5,875 licences the register does not show, $59,264 a month
| Month | Effective licences | Register licences | Gap (licences) | Gap share of effective |
|---|---|---|---|---|
| Jul 2024 | 3,752 | 3,723 | 29 | 0.8% |
| Aug 2024 | 6,694 | 6,611 | 83 | 1.2% |
| Sep 2024 | 13,139 | 12,944 | 195 | 1.5% |
| Oct 2024 | 15,774 | 15,551 | 223 | 1.4% |
| Nov 2024 | 20,695 | 19,685 | 1,010 | 4.9% |
| Dec 2024 | 23,396 | 22,846 | 550 | 2.4% |
| Jan 2025 | 26,302 | 25,509 | 793 | 3.0% |
| Feb 2025 | 29,443 | 28,265 | 1,178 | 4.0% |
| Mar 2025 | 33,163 | 31,941 | 1,222 | 3.7% |
| Apr 2025 | 38,864 | 37,090 | 1,774 | 4.6% |
| May 2025 | 43,925 | 41,831 | 2,094 | 4.8% |
| Jun 2025 | 49,368 | 47,141 | 2,227 | 4.5% |
| Jul 2025 | 52,594 | 49,768 | 2,826 | 5.4% |
| Aug 2025 | 57,263 | 53,216 | 4,047 | 7.1% |
| Sep 2025 | 61,691 | 57,307 | 4,384 | 7.1% |
| Oct 2025 | 66,072 | 61,432 | 4,640 | 7.0% |
| Nov 2025 | 71,210 | 65,902 | 5,308 | 7.5% |
| Dec 2025 | 73,988 | 68,147 | 5,841 | 7.9% |
| Jan 2026 | 78,244 | 71,280 | 6,964 | 8.9% |
| Feb 2026 | 81,596 | 75,033 | 6,563 | 8.0% |
| Mar 2026 | 87,970 | 81,433 | 6,537 | 7.4% |
| Apr 2026 | 91,852 | 86,021 | 5,831 | 6.3% |
| May 2026 | 96,969 | 90,831 | 6,138 | 6.3% |
| Jun 2026 | 102,554 | 96,679 | 5,875 | 5.7% |
By design: every monthly term after the first auto-renews without an order
| Term type | Derived share | Derived rows | All rows |
|---|---|---|---|
| Monthly term | 83.1% | 16,641 | 20,024 |
| Annual term | 18.6% | 5,607 | 30,086 |
Every partner invoice line and every Direct customer invoice line is a roll-up of subscription-months, re-derived through a second join. 2,398 invoice lines (72 partner-by-month, 2,326 customer-by-month), 0 with a non-zero tie-out (M-08). Published because the value of a reconciliation is the discipline of checking, not the size of what it finds. Separately, 259 of 7,493 transactions received were refused under a fixed vocabulary of reasons and kept in the register rather than dropped (M-07); a refusal is a fact about the sender and says nothing about the engine.
Two derivation paths, written to be different. A record-at-a-time state machine in Python derives every term, every subscription-month and every measure from the event stream and a normative rules document. A set-based SQL path in DuckDB, written from the same rules document and not from the first path's code, re-derives every published cell and must agree before anything is published. On this build it did, on every cell.
A hand-specified golden fixture written before either engine. Fifteen worked cases, including a boundary-day order, a monthly term opened on the 31st, and a Direct-channel subscription, with expected values computed by hand. Both paths pass it.
Derived rows are declared, never hidden. Every term and every billing row that rests on
a manufactured renewal carries a derived flag, and Chart 4 counts them.
No accuracy, error-rate or correctness percentage exists in this module, and none may be added. Its only correctness claim is that an independent re-derivation agrees and that the golden fixture passes. That is a statement about method.
The layer the author cannot self-verify. Whether a reader who does not know the finding takes it away from these charts is not something the author can test alone. A blind reading panel of four seats, three domain readers and one visualization reader, read static renders of this page at 320 and 1,040 pixels before it shipped. It returned 26 findings; 20 changed the charts, 3 were accepted with a reason and 3 were rejected with one, and every finding is recorded with the reviewer's own words in the repository's chart review. The charts here are the ones rebuilt after that read.
An independent portfolio project by Aaron Robbins. Synthetic data from a seeded generator (seed 20260911). Simulated: not a real company, customer, partner, product or book of business. Every customer, partner, subscription and transaction was invented by a seeded generator; the partner names are invented and resemble no real reseller, carrier or company. Nothing here is a claim about how any real company operates, and nothing is financial or legal advice.
Source, governance documents, the rules the engines implement, and the build scripts:
github.com/RobbinsAnalytics/cascadia-revenue-assurance. Every figure on this
page is computed at build time from data/conformed/measures_manifest.json and
data/conformed/measures_stage2.json; the independent re-derivation that gates publication is
src/validate_measures.py.
As of 2026-06-30 · seed 20260911 · billable across the window $12,621,679.44