HANDOFF NOTE: project "invoice" (only this project; archived records for other projects were discarded as unrelated)

1. INTERFACE AND ALGORITHM (fixed contract)
evaluate(payload) -> {invoices: [{id, charge, refunded, balance, status}]}
- Invoice fields: unique id, integer created day, currency, lines (nonnegative decimal-dollar strings), nonnegative fee_cents, ordered events. Each event has eid, kind (refund/void/restore), day, nonnegative cents.
- Filter out invoices whose currency does not match the configured currency.
- Convert each line to cents with exact decimal ROUND_HALF_UP (use Decimal, never floats).
- rounding=per_line: round each line, then sum. rounding=invoice: sum the exact decimals, then round once.
- charge = principal cents + fee_cents.
- Skip the invoice if charge < min_invoice_cents (skipped means omitted from output).
- Deduplicate events by eid. The first occurrence fixes the key's insertion position. With duplicate_event=last, the value is replaced by the later event. With first, the first value is kept.
- refunds_first=true: stably move refund events ahead of all other events. false: keep the original order.
- Processing starts with the invoice active.
  - void: disables future refunds (inactive).
  - void_is_tombstone=true: a void also permanently blocks later restores.
  - void_is_tombstone=false: restore re-enables refunds.
  - Earlier refunds are never undone.
- A refund applies only if all of these hold:
  - the invoice is active;
  - day - created >= 0;
  - day - created < max_refund_age_days (equality allowed only if inclusive_limit=true).
- Refund ceiling = principal + fee if fee_refundable, else principal only.
  - refund_overflow=cap: clamp the event to the remaining unrefunded ceiling.
  - refund_overflow=reject: reject the whole oversized event (no partial application).
- Final status:
  - "void" if inactive;
  - else "refunded" if refunded == charge;
  - else "open".
  - status_case controls the case of the string.
- balance = charge - refunded.
- Sort invoices by id (order=id) or by (created, id) (order=created).
- Do not mutate the payload. Empty input gives invoices: [].

2. CURRENT CONFIGURATION (after Updates 1-5; later updates override only the keys they name)
- currency = "USD"
- rounding = "invoice"
- min_invoice_cents = 25
- duplicate_event = "last"
- refunds_first = false
- void_is_tombstone = false (restore re-enables refunds)
- inclusive_limit = false (a refund with age == 45 is not allowed; the age must be < 45)
- max_refund_age_days = 45
- fee_refundable = true (ceiling = principal + fee)
- refund_overflow = "reject"
- order = "created" (sort by (created, id))
- status_case = "upper" (statuses VOID / REFUNDED / OPEN)

3. HISTORY OF OVERRIDES (superseded, do not use)
- order: id (Update 2) -> created (Update 5).
- refund_overflow: cap (Update 2) -> reject (Update 4).
- refunds_first: true (Update 2) -> false (Update 4).
- void_is_tombstone: true (Update 2) -> false (Update 5).

4. UNRESOLVED / NOTES
- No exceptions or open items were stated.
- Unspecified details that need a decision if they come up:
  - the output type of charge, refunded and balance (assumed integer cents);
  - how cap treats a refund when the ceiling is already reached (assumed a refund of 0);
  - the handling of malformed input.
- Awaiting further updates. Apply each as key-level replacements on top of section 2.