4107a595db
launchSessionRun and launchSessionResumeWithRehydrate each inlined their own copy of the freestyle phase-2 handoff with different guard sets — the run path had none, so a failed planning run still called lockAndRun and emitted a spurious ExecutionPlanRejected. Both now call one handoff that checks graph id, planning result, and an existing plan lock before locking and running phase 2.