04 — Engine scenarios (golden tests)
Status: draft — S01–S04 specified with numbers; S05+ linked to ASC catalog
Purpose: Correctness for the ASC 606 engine (accounting equality). Normative ids: A606-* in 20 / 21.
Each scenario → future automated test. Spec: 08-mvp-spec.md. Examples narrative: 07-asc606-worked-examples.md.
How to add
- Copy template at bottom.
- One behavior per scenario.
- Expect balances / period amounts, not sheet columns.
- Link policy ids from 03-event-catalog.md.
Index
| ID | Name | Status |
|---|---|---|
| S01 | Single PO ratable — open + recognize | specified |
| S02 | Invoice + recognize (billing vs recognition) | specified |
| S03 | Mid-term upgrade — prospective | specified |
| S04 | Credit note — reduce unrecognized | specified |
| S05 | Cancellation mid-term | todo → card in 21 A606-P05 |
| S06 | Multi-PO + SSP | later → [21] A606-P06 |
| S07 | Usage VC | later → [21] A606-P07 |
| S08 | Proportional delivery | later → [21] A606-P08 |
| S09+ | Catch-up, collectibility, material right, RPO, … | new — see 20 backlog |
S01 — Single PO ratable (no invoice yet)
Policy: recog.method=ratable
Given: Customer C; sub sub_1; term 2026-01-01→2026-12-31; TP 1200; one PO.
Events
open_contractrecognize(2026-01)
Expect
| Measure | Value |
|---|---|
| Revenue Jan | 100 |
| Deferred | 1100 |
| Schedule lines | 12 × 100, Jan marked recognized |
Non-expect: No OrderDetails; no invoice join.
Note: Recognize-before-bill creates contract asset / unbilled depending on presentation policy — lock in ADR if product requires balance-sheet labels. MVP may require bill before recognize (see S02 as primary path).
S02 — Prepaid invoice then recognize (primary happy path)
Given: Same as S01.
Events
open_contract(TP 1200)record_billing(INV-1, 1200)+record_payment(paid in full)recognize(2026-01)… throughrecognize(2026-12)
Expect after bill (before any recognize)
| Measure | Value |
|---|---|
| Cash (or clearing) | 1200 |
| Deferred | 1200 |
| Revenue | 0 |
| AR | 0 |
Expect after Jan recognize
| Measure | Value |
|---|---|
| Revenue | 100 |
| Deferred | 1100 |
Expect after Dec
| Measure | Value |
|---|---|
| Revenue YTD | 1200 |
| Deferred | 0 |
Non-expect: Billing does not create a second PO or alter service dates.
S03 — Upgrade prospective
Given: S02 through June recognized (revenue 600, deferred 600).
Events: amend_contract(effective=2026-07-01, remaining_TP=1200)
i.e. remaining 6 months at 200/mo (Enterprise).
Expect
| Measure | Value |
|---|---|
| Jan–Jun revenue (unchanged) | 600 |
| Jul–Dec revenue each | 200 |
| Jul–Dec total | 1200 |
| Deferred just after amend (before Jul recog) | 1200 |
Non-expect: No restatement of Jan–Jun; no full invoice history rebuild.
S04 — Credit note reduces unrecognized
Policy: cn.refund_unrecog
Given: S02 after March recognize — revenue 300, deferred 900.
Events: record_credit(CN-1, amount=150)
Expect
| Measure | Value |
|---|---|
| Revenue (unchanged) | 300 |
| Deferred | 750 |
| Remaining schedule total | 750 |
Non-expect: No automatic reverse of the 300 already recognized (that would be cn.reverse_recog).
S05 — Cancellation mid-term (todo)
Intent: terminate with policy term.cancel — define whether remaining deferred → revenue, refund, or write-off.
Template
## SXX — Title
**Policy:** …
**Given:** …
**Events:** …
**Expect:** (table)
**Non-expect:** …