Handoff: target project scheduler only

Current authoritative settings (Updates 1–5 merged):
{
  "timezone": "America/New_York",
  "cutoff_hour": 17,
  "cutoff_inclusive": true,
  "lead_minutes": 30,
  "adjacency_allowed": true,
  "duration_max": 120,
  "duplicate_policy": "first",
  "cancelled_blocks": true,
  "capacity": 1,
  "report_order": "id",
  "blackout_day": "2026-11-02",
  "priority_high_first": false
}

Fixed interface:
Implement evaluate(payload) returning:
{selected: [id], blocked: [id], rejected: [id]}

Input:
- payload.now: offset-aware ISO datetime.
- payload.appointments: rows with id, start (offset-aware ISO datetime), duration (positive minutes), priority (integer), cancelled (boolean).
- Do not mutate input.
- Use zoneinfo or equivalent timezone conversion.

Required algorithm and current behavior:
1. Deduplicate by id, preserving each id's first insertion position. Current policy retains the FIRST row. The retained original index must be the retained value's actual index in the original appointments array.
2. Process retained rows by priority ASCENDING (priority_high_first=false), with ties ordered by retained original index.
3. Perform start/end arithmetic and lead-time arithmetic using UTC elapsed minutes, never local wall-clock minutes.
4. Reject appointments unless duration > 0 and duration <= 120 minutes.
5. Require start >= now + 30 elapsed minutes; equality is allowed.
6. Convert start to America/New_York. Reject if its local calendar date is 2026-11-02.
7. Construct cutoff at 17:00 America/New_York on start's local calendar day. Require end <= cutoff; equality is allowed. Compare instants consistently, using UTC.
8. Cancelled rows can reserve capacity because cancelled_blocks=true. They must pass the same validity and capacity checks. Accepted cancelled ids go to blocked, not selected. Rejected cancelled ids go to rejected.
9. Accept only when fewer than capacity already accepted intervals intersect the candidate. Capacity is currently 1, so no intersecting accepted interval is allowed. Both selected and blocked intervals count as accepted reservations.
10. Endpoint-only contact does NOT count as overlap (adjacency_allowed=true).
11. The general capacity rule counts intersecting accepted intervals, NOT peak concurrency. Preserve this distinction if capacity changes later.
12. All invalid or conflicting ids go to rejected.
13. Sort each output list independently by id (report_order="id"), not processing order.

Continuity:
- Later scheduler updates replace only their named keys; all other current choices remain unchanged.
- Ignore every archive-* work record: those settings apply only to unrelated projects.
- Discard superseded scheduler values.
- No implementation or tests have been provided in this session.
- No explicit unresolved scheduler choices remain. Exact behavior for malformed top-level payloads, missing/unusable ids, and mixed/non-comparable id types has not been specified; do not invent requirements for those cases.
- The next update and later questions are not yet available.