Build an audit log for every subtraction. Add events now include a grant id and are written as ('add', grant_id, amount, timestamp, duration). Subtract events are ('sub', amount, timestamp). Events may arrive out of order, but you must process them by timestamp; if multiple events share a timestamp, adds happen before subtracts. During a subtraction, consume currently active grants using expire-soonest priority; if expirations tie, consume the earlier-starting grant first, then earlier input order. If a subtraction is not fully covered, the uncovered part becomes debt. Later adds pay down debt first, and only leftover credit becomes available for future subtracts. Your function should return an audit log in chronological subtraction order. For each subtraction, output a tuple (timestamp, requested_amount, consumed_list, uncovered_amount), where consumed_list is a list of (grant_id, amount_used) pairs. Important: the log records what was consumed immediately at that subtraction time; later debt repayment does not rewrite old log rows.
Examples
Input: ([('add', 'A', 5, 0, 5), ('add', 'B', 4, 1, 4), ('sub', 6, 2)],)
Expected Output: [(2, 6, [('A', 5), ('B', 1)], 0)]
Explanation: Both grants expire at time 5, so the earlier-starting grant A is consumed first.
Input: ([('sub', 7, 3), ('add', 'g1', 4, 1, 10), ('add', 'g2', 2, 2, 10)],)
Expected Output: [(3, 7, [('g1', 4), ('g2', 2)], 1)]
Explanation: Only 6 credits are active at time 3, so the audit row shows uncovered amount 1.
Input: ([('sub', 5, 1), ('add', 'x', 3, 2, 5), ('add', 'y', 4, 3, 5), ('sub', 2, 3)],)
Expected Output: [(1, 5, [], 5), (3, 2, [('y', 2)], 0)]
Explanation: The first subtraction creates debt. Later adds pay debt first, leaving only 2 usable credits in grant y by time 3.
Input: ([('sub', 4, 5), ('add', 'g1', 10, 5, 5)],)
Expected Output: [(5, 4, [('g1', 4)], 0)]
Explanation: Same-timestamp ordering matters: adds happen before subtracts.
Input: ([],)
Expected Output: []
Explanation: Edge case: no events means no audit rows.