Shared opt-in execution for fresh, resumed and forked commands.
Pass session_observer: {local_pid, reference} to Exec.execute/3,
ExecResume.execute/3, ExecFork.execute/3, ExecFork.fork/3 or Review.execute/3.
Existing CodexWrapper.exec/2 and exec_json/2 accept the same option.
Observed commands force --json and require a runner implementing
CodexWrapper.Runner.run_observed/5; no Port fallback occurs.
Add execution_observer: {local_pid, reference} to request a terminal
CodexWrapper.ExecutionObservation on success or failure. This requires
CodexWrapper.Runner.run_evidenced/5 and never falls back. Supply both
observer options for early identity followed by terminal evidence. The caller
sends both facts before returning. The evidence path uses finite wall/idle
bounds (300,000 ms by default) and combined output (1 MiB by default),
configurable with Config.runner_options. A valid execution target also
receives a terminal fact for capability/option preflight failures; an invalid
execution target cannot be notified. Missing cleanup remains unknown.
Only the first valid stdout thread.started with a nonblank thread_id
produces a CodexWrapper.SessionObservation. Malformed, duplicate and
conflicting later announcements are ignored. Stderr cannot supply identity.
A dead observer is harmless. The execution caller sends the observation
before returning, preserving order with its later reply to that observer.
Results retain every byte in separate stdout and stderr fields. Legacy
execute/2 keeps its merged output. Exit codes and process success semantics
are unchanged, including a successful process with no thread announcement.
Completion waits for the transport, not a JSON event. The configured
whole-run timeout and runner cleanup apply; no new idle timeout is added.
Identity framing uses at most 1 MiB per line. Oversized lines are ignored
until the next newline without changing final raw output. Observer targets
and runner support are checked before spawning. Invalid options return
{:error, :invalid_session_observer}; unsupported runners return
{:error, {:observation_unsupported, runner}}.