TARGET PROJECT: invoice — HANDOFF NOTE

Current authoritative configuration (later target updates supersede earlier values; all archived/unrelated project settings discarded):
{
  "currency": "USD",
  "fee_refundable": true,
  "min_invoice_cents": 25,
  "status_case": "upper",
  "rounding": "invoice",
  "duplicate_event": "last",
  "inclusive_limit": false,
  "max_refund_age_days": 45,
  "refunds_first": false,
  "refund_overflow": "reject",
  "void_is_tombstone": false,
  "order": "created"
}

Fixed interface/algorithm contract:
- Implement evaluate(payload) -> {invoices:[{id,charge,refunded,balance,status}]}. Do not mutate payload. Empty input produces {invoices: []}.
- Invoices have unique id, integer created day, currency, nonnegative decimal-dollar strings in lines, nonnegative fee_cents, and ordered events with eid, kind (refund/void/restore), day and nonnegative cents.
- Filter out invoices whose currency is not USD.
- Convert lines to cents using exact decimal ROUND_HALF_UP. With rounding="invoice", round the summed lines once, not per line. charge = line-principal in cents + fee_cents.
- Skip invoices with charge below min_invoice_cents=25.
- Deduplicate events by eid with duplicate_event="last": preserve the first occurrence's insertion position, but use the last occurrence's value.
- refunds_first=false: preserve event order; do not move refunds ahead.
- Begin active. A void disables future refunds. void_is_tombstone=false, so a subsequent restore re-enables refunds (a void is not permanent). Earlier refunds are never undone.
- A refund applies only while active, and only if 0 <= event.day - created < 45. Because inclusive_limit=false, age exactly 45 is not allowed.
- Refund ceiling: because fee_refundable=true, ceiling is principal + fee (i.e., charge). Because refund_overflow="reject", reject the entire oversized refund event rather than capping it.
- balance = charge - refunded.
- End status, uppercased via status_case="upper": VOID if inactive at end, else REFUNDED if refunded == charge, else OPEN.
- Sort output invoices by (created, id) via order="created".

Exceptions/unresolved items: None known; all 12 configuration keys above are resolved to current values.