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 or ExecFork.fork/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.
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}}.