From d3e433fcb02eb21946ef7b35a2bcd04607ab7cfa Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 11 Aug 2026 19:15:59 +0200 Subject: [PATCH] Bind proposal launch to admitted thread --- epiphany-core/src/coordinator_launch.rs | 44 ++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/epiphany-core/src/coordinator_launch.rs b/epiphany-core/src/coordinator_launch.rs index fa7ac140..2c05decc 100644 --- a/epiphany-core/src/coordinator_launch.rs +++ b/epiphany-core/src/coordinator_launch.rs @@ -1188,7 +1188,6 @@ fn validate_proposal_modeling_launch( || proposal.payload_sha256 != format!("{:x}", Sha256::digest(content)) || selection.runtime_id != identity.runtime_id || selection.runtime_id != proposal.runtime_id - || selection.thread_id != persisted_state.thread_id || selection.thread_id != proposal.thread_id || persisted_state_value != *state || selection.repository != proposal.repository @@ -2103,6 +2102,49 @@ pub(crate) mod tests { Ok(()) } + #[test] + fn proposal_launch_restores_its_admitted_thread_after_resident_projection_transition( + ) -> Result<()> { + let root = tempfile::tempdir()?; + let (store, state, request, selection) = + proposal_launch_fixture(root.path(), "resident-thread-transition")?; + let mut cache = coordinator_acceptance_cache(&store)?; + cache.put( + THREAD_STATE_KEY, + &EpiphanyThreadStateEntry::from_state("resident-self-thread-runtime-1", &state)?, + )?; + + let plan = plan_coordinator_job_launch( + &state, + &request, + &store, + "launcher-after-transition".into(), + "backend-after-transition".into(), + )?; + let committed = commit_coordinator_job_launch( + &store, + &selection.thread_id, + &state, + &request, + &plan, + "2026-07-13T05:00:04Z".into(), + )?; + + let cache = coordinator_acceptance_cache(&store)?; + let restored = cache + .get::(THREAD_STATE_KEY)? + .expect("launch restores admitted cognitive thread projection"); + assert_eq!(restored.thread_id, selection.thread_id); + assert_eq!(restored.state()?, committed.epiphany_state); + let binding = cache + .get::( + "repo-frontier-proposal-modeling-launch-backend-after-transition", + )? + .expect("launch preserves admitted proposal lineage"); + assert_eq!(binding.thread_id, selection.thread_id); + Ok(()) + } + #[test] fn proposal_launch_binding_is_reusable_only_after_exact_process_terminality() -> Result<()> { let root = tempfile::tempdir()?;