```python
def carve_shift(start: int, end: int, span: int, rest: int, least: int) -> list:
    """
    Carve a work shift into stretches of at most span units, separated by rest units,
    with the final stretch being at least least units long.
    
    :param start: The starting point of the shift (inclusive).
    :param end: The ending point of the shift (exclusive).
    :param span: The maximum length of a work stretch.
    :param rest: The duration between consecutive stretches.
    :param least: The minimum length of the final stretch.
    :return: A list of half-open [from, to) pairs representing the work stretches.
    """
    
    if not all(isinstance(arg, int) for arg in (start, end, span, rest, least)):
        raise ValueError("All arguments must be whole numbers.")
    
    if start >= end:
        raise ValueError("Start must precede end.")
    
    if span < 1 or rest < 1 or least < 1 or least > span:
        raise ValueError("Span and rest must be at least 1, and least must be between 1 and span.")
    
    stretches = []
    current_start = start
    
    while current_start + span <= end:
        stretch_length = min(span, end - current_start)
        if stretch_length >= least:
            stretches.append((current_start, current_start + stretch_length))
        current_start += rest
    
    return stretches
```