From 253ef34084c7b450e587c1938a68cd3e983ed79b Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 8 Aug 2026 11:11:20 +0100 Subject: [PATCH] Derive CRRC checkpoint from admitted RepoModel --- epiphany-core/src/bin/epiphany-mvp-status.rs | 53 +++++++++++++++++--- epiphany-core/src/lib.rs | 1 + epiphany-core/src/surfaces/mod.rs | 1 + epiphany-core/src/surfaces/reorient.rs | 37 ++++++++++---- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/epiphany-core/src/bin/epiphany-mvp-status.rs b/epiphany-core/src/bin/epiphany-mvp-status.rs index 11959e2a..8f5e45e9 100644 --- a/epiphany-core/src/bin/epiphany-mvp-status.rs +++ b/epiphany-core/src/bin/epiphany-mvp-status.rs @@ -308,9 +308,52 @@ fn run_native_status(args: &Args, include_auxiliary_status: bool) -> Result EpiphanyReorientPressureLevel::High, epiphany_core::EpiphanyPressureLevel::Critical => EpiphanyReorientPressureLevel::Critical, }; + let admitted_model_projection = + match epiphany_core::runtime_current_repo_model(&runtime_store_path)? { + Some(_) => Some( + epiphany_core::runtime_modeling_semantic_projection_input(&runtime_store_path) + .context("failed to validate current RepoModel continuity projection")?, + ), + None => None, + }; + let investigation_checkpoint = + state_ref.and_then(|state| state.investigation_checkpoint.as_ref()); + let repo_model_code_refs = admitted_model_projection + .as_ref() + .map(|projection| { + projection + .snapshot() + .frontier + .iter() + .filter(|item| item.status == epiphany_core::RepoFrontierStatus::Active) + .flat_map(|item| item.source_scope.iter()) + .map(|path| epiphany_state_model::EpiphanyCodeRef { + path: path.into(), + start_line: None, + end_line: None, + symbol: None, + note: Some("Current admitted RepoModel frontier scope".to_string()), + }) + .collect::>() + }) + .unwrap_or_default(); + let reorient_checkpoint = investigation_checkpoint + .map(epiphany_core::EpiphanyReorientCheckpoint::from) + .or_else(|| { + admitted_model_projection.as_ref().map(|projection| { + epiphany_core::EpiphanyReorientCheckpoint { + checkpoint_id: &projection.obligation().obligation_id, + disposition: + epiphany_state_model::EpiphanyInvestigationDisposition::ResumeReady, + next_action: Some("Resume from the current Mind-admitted RepoModel frontier."), + code_refs: &repo_model_code_refs, + } + }) + }); + let durable_checkpoint_present = reorient_checkpoint.is_some(); let (reorient_state_status, reorient_decision) = recommend_reorientation(EpiphanyReorientInput { - checkpoint: state_ref.and_then(|state| state.investigation_checkpoint.as_ref()), + checkpoint: reorient_checkpoint, state_present: state_ref.is_some(), pressure_level: reorient_pressure_level, retrieval_status: reorient_retrieval_status(freshness.retrieval.status), @@ -359,9 +402,7 @@ fn run_native_status(args: &Args, include_auxiliary_status: bool) -> Result Result { - pub checkpoint: Option<&'a EpiphanyInvestigationCheckpoint>, + pub checkpoint: Option>, pub state_present: bool, pub pressure_level: EpiphanyReorientPressureLevel, pub retrieval_status: EpiphanyReorientFreshnessStatus, @@ -80,6 +80,25 @@ pub struct EpiphanyReorientInput<'a> { pub watched_root: Option, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct EpiphanyReorientCheckpoint<'a> { + pub checkpoint_id: &'a str, + pub disposition: EpiphanyInvestigationDisposition, + pub next_action: Option<&'a str>, + pub code_refs: &'a [epiphany_state_model::EpiphanyCodeRef], +} + +impl<'a> From<&'a EpiphanyInvestigationCheckpoint> for EpiphanyReorientCheckpoint<'a> { + fn from(checkpoint: &'a EpiphanyInvestigationCheckpoint) -> Self { + Self { + checkpoint_id: &checkpoint.checkpoint_id, + disposition: checkpoint.disposition, + next_action: checkpoint.next_action.as_deref(), + code_refs: &checkpoint.code_refs, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct EpiphanyReorientDecision { @@ -196,7 +215,7 @@ pub fn recommend_reorientation( }; let workspace_root = input.watched_root.as_deref(); let checkpoint_dirty_paths = overlapping_checkpoint_paths( - checkpoint, + &checkpoint, input .retrieval_dirty_paths .iter() @@ -204,7 +223,7 @@ pub fn recommend_reorientation( workspace_root, ); let checkpoint_changed_paths = overlapping_checkpoint_paths( - checkpoint, + &checkpoint, input.watcher_changed_paths.iter(), workspace_root, ); @@ -266,12 +285,12 @@ pub fn recommend_reorientation( build_decision( EpiphanyReorientAction::Resume, checkpoint_status, - Some(checkpoint.checkpoint_id.clone()), + Some(checkpoint.checkpoint_id.to_string()), reasons, Vec::new(), Vec::new(), Vec::new(), - checkpoint.next_action.clone().unwrap_or_else(|| { + checkpoint.next_action.map(str::to_string).unwrap_or_else(|| { "Resume from the durable checkpoint focus and verify the seam before broad edits." .to_string() }), @@ -333,14 +352,14 @@ pub fn recommend_reorientation( build_decision( EpiphanyReorientAction::Regather, checkpoint_status, - Some(checkpoint.checkpoint_id.clone()), + Some(checkpoint.checkpoint_id.to_string()), reasons, checkpoint_dirty_paths, checkpoint_changed_paths, input.active_frontier_node_ids, checkpoint .next_action - .clone() + .map(str::to_string) .unwrap_or_else(|| "Re-gather source context before editing.".to_string()), format!("Re-gather before editing: {}.", note_fragments.join("; ")), ), @@ -348,7 +367,7 @@ pub fn recommend_reorientation( } fn overlapping_checkpoint_paths<'a>( - checkpoint: &EpiphanyInvestigationCheckpoint, + checkpoint: &EpiphanyReorientCheckpoint<'_>, candidate_paths: impl IntoIterator, workspace_root: Option<&Path>, ) -> Vec { @@ -416,7 +435,7 @@ mod tests { fn input(checkpoint: Option<&EpiphanyInvestigationCheckpoint>) -> EpiphanyReorientInput<'_> { EpiphanyReorientInput { - checkpoint, + checkpoint: checkpoint.map(EpiphanyReorientCheckpoint::from), state_present: true, pressure_level: EpiphanyReorientPressureLevel::Low, retrieval_status: EpiphanyReorientFreshnessStatus::Clean,