Package receivables publishes a receivables aging report and the resulting allowance for credit losses over invoices held in r/invoices.
An issuer registers an aging schedule — age bands in BLOCKS and a loss rate per band — and then names the invoice ids to age. This realm reads every FACT from the invoice realm (amount, amount paid, due height, status) and prices the result with p/aging. The published report is frozen: the per-bucket unpaid totals, the per-bucket provision, the grand provision, and a snapshot of the schedule that priced it.
The caller supplies the selection, the chain supplies the facts
This is the central design constraint and it is a measured one, not a preference. r/invoices exports no per-issuer id enumerator — its internal `Iterate` is unexported and nothing above it can walk an issuer's records — so a realm here CANNOT derive "every open invoice" on its own. It therefore takes the id list from the caller.
The consequence is stated rather than hidden: **a report can under-report**. An issuer who omits an overdue invoice from the list gets a provision that is too small, and no check here can see the omission. What this realm does instead is publish a COVERAGE LINE with every report — how many ids were listed, how many were aged, how many were filtered and why, and how many open invoices and stored records the issuer held at that height — so a reader can compute the shortfall themselves. See Coverage.
Under-reporting is made VISIBLE here. It is not prevented, and a reader who treats a published provision as complete without reading the coverage line is reading it wrongly.
Ages are in BLOCKS
r/invoices stores `dueHeight` as a block height, so an age is a count of blocks and every schedule edge is a count of blocks. A "30/60/90 day" schedule is a conversion the ISSUER owns and this realm never performs: nothing here knows the block time, and compiling a guess in would make every published rate wrong by whatever the guess was off by.
This realm writes no ledger entry
A provision is an accounting entry — debit a credit-loss expense, credit an allowance — and this realm deliberately does not post it. r/books derives the owner of a book structurally from its caller, so a realm that called `PostMulti` would post into ITS OWN book and not the issuer's. There is no owner parameter to pass and no delegation path to use.
So ProposedEntry returns the entry as a string in the form r/books' `PostMulti` accepts, and the issuer posts it themselves from their own account. The realm stays keyless with respect to every ledger, which is the stronger position: it cannot write a wrong entry because it cannot write.
Custody
None. This realm holds no coins, has no withdrawal path, and refuses a user call that arrives carrying any. Nothing here moves value; a provision is a statement about value, which is not the same thing.
Limitations
- **The report is a self-report of a self-report.** r/invoices' amounts are whatever an issuer typed; an aging of them inherits that entirely and then looks like an audited artifact. No audit happens here.
- **It can under-report, by construction.** See above and Coverage.
- **It cannot over-report an unlisted invoice**, because every fact comes from the chain — but it CAN over-report a *listed* one whose amount the issuer inflated in r/invoices in the first place.
- **No write-off.** p/aging prices an expected loss and never removes an obligation; a receivable this report provisions at 100% is still a live invoice in r/invoices. Voiding is that realm's operation, not this one's.
- **A frozen report does not track the invoices.** A payment landing after publication leaves the published figures untouched, which is what "frozen" means. There is no `Verify` here: re-deriving would need the id list, which is not stored (see Publish).
- **Buckets are floored per bucket**, so the per-bucket column sums to the grand provision exactly and both are at or below the unrounded figure. p/aging's package doc carries the counterexample.
- **No cross-issuer aggregate.** There is no enumerator and no total provision across issuers; such a figure would sum strangers' assertions.
r/invoices: /r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/invoices r/books: /r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/books p/aging: /p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/aging