Write-off is a flag on the invoice, not a status
Uncollectible debt needs an exit from the chase queue (without one, MISSING grows forever and
zombies bury live collections work — AR design §10). We record it as nullable
written_off_at / written_off_by / written_off_reason columns on invoices, owner-only and
reversible — not as a new status value and not as a collection-activity row alone.
Why not a status: status is load-bearing in every money predicate (check-allocation pool,
invoice_ar_summary, invoice_drift, send_invoices, effective-overdue derivation). A new enum
value would silently drop a written-off invoice out of the check-allocation pool, so a late check
that arrives anyway could no longer be applied and would strand as leftover. With the flag, the
invoice keeps its status: a surprise payment still lands, and the AR page flags "payment received
on written-off invoice" for the owner to decide reinstatement. The failure direction is also
safer — a predicate that forgets to exclude the flag chases dead debt (annoying, visible) rather
than losing an incoming payment (silent).
Why not activity-only: other surfaces (KPI card, recon report, dashboards) read invoices, not collection activities; debt written off only in the activity log would still count as missing everywhere else, and the two pages must never disagree on a dollar.
Written-off is distinct from dead money (void/deleted with payments = accidental erasure); the two are never summed together. (Decided 2026-08-14 in the AR-page grilling session.)