```python
def remaining_for(used: dict, key: str, allowance: int) -> int:
    """Return the remaining allowance for a key based on current usage."""
    if not isinstance(allowance, int) or allowance <= 0:
        raise ValueError("Allowance must be a positive integer")
    if not isinstance(key, str) or len(key) == 0:
        raise ValueError("Key must be a non-empty string")
    
    spent = used.get(key, 0)
    return allowance - spent


def meter_draws(draws: list, allowance: int) -> dict:
    """Replay draws against a ledger and return used ledger and denied positions."""
    if not isinstance(allowance, int) or allowance <= 0:
        raise ValueError("Allowance must be a positive integer")
    
    used: dict = {}
    denied: list = []
    
    for i, draw in enumerate(draws):
        if not isinstance(draw, list) or len(draw) != 2:
            raise ValueError("Each draw must be a list of [key, units]")
        
        key = draw[0]
        units = draw[1]
        
        if not isinstance(key, str) or len(key) == 0:
            raise ValueError("Key must be a non-empty string")
        if not isinstance(units, int) or units <= 0:
            raise ValueError("Units must be a positive integer")
        
        # Ensure key is in ledger (even if draw is refused)
        if key not in used:
            used[key] = 0
        
        remaining = remaining_for(used, key, allowance)
        
        if units <= remaining:
            used[key] += units
        else:
            denied.append(i)
            
    return {"used": used, "denied": denied}
```