Desktop terminal batching pre-collects the approval for every command in
a run before any of them executes, so the user consents to a batch in
which all commands are expected to run. When an earlier command then
fails (or is denied/blocked), that informed consent no longer describes
the world the later commands will run in — yet the executor still
consumed the pre-made decision as though nothing had happened.
- _TerminalBatch.failure_seen: set by the sequential publisher after a
slot's failed (or blocked) result is committed — i.e. after the failure
the model actually sees, never from a wedged worker's late result.
- consume_prepared_guard drops the prepared decision for any later slot
once a failure is published and returns None, so the guard runs its
live flow again: tirith scan, allowlist, and a fresh human approval
request when the command still warrants one. Nothing is auto-denied
and an explicit denial of the failing command remains authoritative.
- The flag is sticky for the batch: a later success must not un-stale an
approval collected before an even earlier failure.
Success-path batching is unchanged: with no failure, prepared decisions
are consumed exactly as before (byte-for-byte the same flow).