Durable run identity and immutable selection fences.
An incomplete run may be resumed only inside its original resolved prompt set. This makes an omitted or changed selector incapable of widening a retry.
@type t() :: %PromptRunner.RunLifecycle{ current_path: String.t() | nil, ephemeral?: boolean(), journal_path: String.t() | nil, run_dir: String.t() | nil, run_id: String.t() | nil, snapshot_path: String.t() | nil, targets: [String.t()], upper_fence: String.t() | nil }
@spec open(PromptRunner.Plan.t(), [String.t()], map()) :: {:ok, t()} | {:error, term()}
@spec transition(t(), String.t(), map()) :: :ok | {:error, term()}