```python
"""Cent-exact money helpers for order totals."""


def split_evenly(total_cents: int, ways: int) -> list:
    """Split a total in whole cents into `ways` parts that sum exactly to the total."""
    if not isinstance(total_cents, int) or total_cents < 0:
        raise ValueError("total_cents must be a non-negative integer")
    if not isinstance(ways, int) or ways <= 0:
        raise ValueError("ways must be a positive integer")
    base = total_cents // ways
    remainder = total_cents % ways
    return [base + 1] * remainder + [base] * (ways - remainder)


def apply_bps(cents: int, bps: int) -> int:
    """Convert cents to basis points, rounding up."""
    if isinstance(cents, bool) or not isinstance(cents, int) or cents < 0:
        raise ValueError("cents must be a non-negative integer")
    if isinstance(bps, bool) or not isinstance(bps, int) or bps < 0:
        raise ValueError("bps must be a non-negative integer")
    return (cents * bps + 5000) // 10000


def sum_parts(parts: list) -> int:
    """Sum a list of integer parts."""
    total = 0
    for part in parts:
        if isinstance(part, bool) or not isinstance(part, int):
            raise ValueError("parts must be integers")
        total += part
    return total
```

Key changes to `split_evenly`:
- Replaced `round(total_cents / ways)` with integer division `total_cents // ways` to avoid rounding errors.
- Split the remainder `total_cents % ways` by giving 1 extra cent to the first `remainder` parts, and 0 to the rest. This guarantees:
  - Exact sum (no rounding drift).
  - Non-increasing order (extra cents land on earliest parts).
  - No two parts differ by more than 1 cent.
- Added validation for `total_cents` (non-negative integer) and `ways` (positive integer), raising `ValueError` otherwise.
- `apply_bps` and `sum_parts` are unchanged.