Three review findings on the engine's child seam, one mechanism each:
- Cancellation now bridges to run.cancel() on every in-flight child, not
just the shared request signal — the subagent seam leaves a provider
free to honor either channel, so the consumer drives both (listener
removed in the child finally).
- A child result REJECTION (an infrastructure fault the seam allows) now
emits the paired workflow/agent-end before propagating, and propagates
as a fatal WorkflowError with the new AGENT_RESULT code — previously it
skipped agent-end (permanently open child for seq-matching observers)
and dissolved to a per-item null inside parallel()/pipeline(), letting
a broken provider read as an ordinary failed child. A rejection landing
after cancel stays a cancellation (cancelled outcome + CANCELLED).
- Every hook now guards its entry with a shared throwIfCancelled():
phase()/log() no longer emit observer events after a script caught an
earlier cancelled rejection, and parallel()/pipeline() refuse entry —
cancellation is the next HOOK boundary, not just the next agent().