- streaming_runner.py runner_phase/lifecycle_active list-cells + atexit
  breadcrumb registration: coarse diagnostic labeling only, NOT a lifecycle
  state machine. #424 should keep the breadcrumb sink separate from
  execution/finalization (explicit callbacks or a small runner-owned
  diagnostic context) rather than promoting these cells into state.
- HarnessHistoryWriter's last-observed-event marker (throttled projection,
  state/history.py) should not be carried into #424 as a projection API —
  rewrite-era design should derive orphan evidence from authoritative
  history or an explicitly-owned diagnostics sink.
- [#454] Bind-seam env projection is not structurally final. Pi timeout/ping
  are projected post-bind by two writers (spawn_service, streaming_runner) and
  the primary path skips apply_pi_bind_time_env; bindings.chat_id is set after
  bind; generic env.py holds adapter.id branches. Consolidate to an
  adapter-owned projection hook invoked inside bind_launch_context(), building
  ResolvedLaunchEnvironment.final_env only after it. (A1)
- [#454] prepare_prelaunch() has two output channels — a mutable child_env and
  a returned env_overrides — handled differently by spawned vs primary callers.
  Make child_env a read-only Mapping and env_overrides the sole output, applied
  once via a shared launch helper. (A2)
- native_run.py: group post-exit process facts (`pid`, start time, child env/cwd)
  into an `ExitFacts` value if the pipeline grows; keep serve's started-connection
  distinction rather than inferring every caller's start solely from pid.
- process/runner.py: replace the remaining `managed` local and post-scope spawn-ID
  injection when session-attempt construction is next revised; these names no
  longer describe a separate managed-session abstraction.
- `request.py` and `tests/support/launch.py`: production rejects the `DIRECT`
  composition surface, but `LaunchRuntime.composition_surface` still defaults to
  `DIRECT` and 18 test/support files reference a facade that reimplements direct
  preparation. In a test-architecture pass, remove the production-invalid default
  and migrate those tests through the production prepare/bind pipeline.
- policy_snapshot.py / policies.py `_resolve_policy_from_snapshot`: replay rebuilds
  `ResolvedLaunchPolicy` without `bundle_available_skills`, so on continue the
  available skills survive only as persisted `bundle_inventory_prompt` text and are
  not projected into the workspace. Persist and replay the available entries if a
  continued agent needs to load them natively.
- ops/spawn/api.py fork path: `inherited_skills` re-passes the source spawn's
  resolved skill names to Mars as extra skills, duplicating the profile's own
  loads (Mars dedupes, so it is harmless). Pass only the source's caller-requested
  extras once the snapshot records them separately.
