HANDOFF — target project: importer

Scope
Only importer requirements are authoritative. Ignore all archived records for other projects. Updates 1–5 have been applied; superseded settings are discarded. No later update or question is available.

CURRENT choices
{
  "duplicate_policy": "last",
  "fold_case": false,
  "trim_ids": false,
  "tombstone_wins": false,
  "null_mode": "delete",
  "nested_merge": false,
  "list_merge": "unique",
  "version_floor": 3,
  "order": "id",
  "unknown_fields": "keep",
  "empty_id": "error",
  "audit_all": false
}

Fixed interface
Implement evaluate(payload) -> {records:[{id,fields}],audit:[string]}.
Events contain id (string), version (integer), deleted (boolean), and fields (JSON object). Do not mutate input.

Algorithm and exceptions
1. Normalize each event's id: trim only if trim_ids; ASCII case folding only if fold_case. Currently neither is enabled, so preserve ids exactly.
2. Empty normalized id raises ValueError under current empty_id="error". Normalize and empty-check BEFORE discarding versions below version_floor, including for events that would otherwise be discarded. Whitespace-only ids are not empty with current trim_ids=false.
3. Discard events with version < 3.
4. Deduplicate by normalized (id,version). Retain the key's first insertion position, but currently select the LAST event for each key. Sorting must use the selected event's actual original index, not the duplicate key's first insertion position.
5. Process selected events by (version, selected original index). Save each normalized id's first processed index.
6. Deletion removes a record. A deletion is applied only if a record existed or it installs a new sticky tombstone; redundant deletions are blocked/no-change.
   Current tombstone_wins=false: do not install sticky tombstones; later non-deletions may recreate deleted records. Deleting an absent record is blocked.
   Fixed conditional rule if tombstone_wins is later enabled: deletion permanently blocks later non-deletions; installing a new sticky tombstone counts as applied even without an existing record.
7. Otherwise merge fields, creating {} if the record does not exist.
   - Current null_mode="delete": null deletes an existing key; an absent key remains absent.
   - Current nested_merge=false: object-valued updates replace objects, rather than recursively merging them. Fixed recursive behavior applies only when nested_merge is enabled and both values are objects.
   - When both old and incoming values are arrays, current list_merge="unique" concatenates incoming items that are not structurally JSON-equal to ANY item in the old array.
   - Compare against the old array only. Do NOT deduplicate incoming items against one another. Preserve existing old-array duplicates.
   - Otherwise replace the value.
8. Current unknown_fields="keep": retain all top-level field names. If changed to "drop", filter only the top level to name,tags,meta.
9. Current audit_all=false: audit only applied processed events. If enabled, audit every processed event, including blocked ones.
   Format: normalized_id:version:applied or normalized_id:version:blocked.
   Preserve audit processing order.
10. Current order="id": sort output records lexically by normalized id.
    Fixed alternative: otherwise sort by each id's first processed index, then id. Keep that first index through deletion/recreation.

Unresolved / not supplied
- The contract names payload but does not specify its input envelope or how the event sequence is stored in it.
- No explicit definition is supplied for whether an unblocked non-deletion that produces no field change counts as applied. Do not infer additional no-change blocking rules from the deletion-specific rule.
- No implementation language, additional input-validation policy, fixtures, or acceptance tests are supplied here.
- Do not invent settings or borrow requirements from archived projects. Future updates replace only their named keys and leave all others unchanged.