TARGET PROJECT: invoice — HANDOFF NOTE

Purpose:
Implement evaluate(payload) -> {invoices:[{id,charge,refunded,balance,status}]}
Do not mutate payload. Empty input produces {invoices: []}.

CURRENT CONFIGURATION (final, superseded and unrelated archive settings discarded):
{
  "currency": "USD",
  "rounding": "invoice",
  "duplicate_event": "last",
  "inclusive_limit": false,
  "max_refund_age_days": 45,
  "refunds_first": false,
  "refund_overflow": "reject",
  "void_is_tombstone": false,
  "fee_refundable": true,
  "min_invoice_cents": 25,
  "status_case": "upper",
  "order": "created"
}

INPUT ASSUMPTIONS:
- Invoices have unique id, integer created day, currency, nonnegative decimal-dollar strings in lines, nonnegative fee_cents, and ordered events.
- Events have eid, kind (refund/void/restore), day, and nonnegative cents.

ALGORITHM CONTRACT:
- Filter out invoices whose currency is not "USD".
- Convert each line to cents using exact decimal ROUND_HALF_UP.
- rounding="invoice": round the sum of lines, not each line individually.
- charge = rounded line principal + fee_cents.
- Skip invoices with charge below min_invoice_cents=25. Charge equal to 25 is kept.
- Deduplicate events by eid under duplicate_event="last": preserve the first key's insertion position, but replace its value with the last occurrence.
- refunds_first=false: preserve event order after deduplication; do not move refunds forward.
- Begin in active state.
- A void disables future refunds. void_is_tombstone=false: a subsequent restore re-enables refunds; void is not permanent against restore.
- Earlier successful refunds are never undone by void/restore.
- A refund applies only while active, and only when event day - created is >= 0 and, because inclusive_limit=false, strictly below max_refund_age_days=45. Age exactly 45 is not allowed.
- Refund ceiling: fee_refundable=true, so ceiling is principal plus fee (i.e., full charge).
- refund_overflow="reject": reject the whole oversized refund event; do not cap it and do not partially apply it.
- balance = charge - refunded.
- End status: if inactive at end, "void"; else if refunded == charge, "refunded"; else "open". Apply status_case="upper" to status values.
- Sort output invoices by (created, id) under order="created".

UNRESOLVED ITEMS:
- None. All 12 configuration keys above have current target-project values.

NOTE:
Archived records for other projects are unrelated, have separate fixtures/rules, and must not be applied to this target project.