Keep coordinator decisions core-shaped
This commit is contained in:
parent
ac6510c929
commit
c45cd1bf46
7 changed files with 216 additions and 152 deletions
|
|
@ -38,6 +38,7 @@ use epiphany_core::EpiphanyCrrcResultStatus as CoreEpiphanyCrrcResultStatus;
|
|||
use epiphany_core::EpiphanyCrrcSceneAction as CoreEpiphanyCrrcSceneAction;
|
||||
use epiphany_core::EpiphanyCrrcStateStatus as CoreEpiphanyCrrcStateStatus;
|
||||
use epiphany_core::EpiphanyJobLaunchRequest;
|
||||
use epiphany_core::EpiphanyReorientAction as CoreEpiphanyReorientAction;
|
||||
use epiphany_core::EpiphanyRoleBoardCheckpointSummary;
|
||||
use epiphany_core::EpiphanyRoleBoardInput;
|
||||
use epiphany_core::EpiphanyRoleBoardJob;
|
||||
|
|
@ -80,7 +81,7 @@ use std::path::Path;
|
|||
pub fn map_epiphany_crrc_recommendation(
|
||||
loaded: bool,
|
||||
state_status: ThreadEpiphanyReorientStateStatus,
|
||||
pressure: &ThreadEpiphanyPressure,
|
||||
pressure: &epiphany_core::EpiphanyPressure,
|
||||
decision: &ThreadEpiphanyReorientDecision,
|
||||
result_status: ThreadEpiphanyReorientResultStatus,
|
||||
checkpoint_present: bool,
|
||||
|
|
@ -117,6 +118,15 @@ fn map_core_crrc_reorient_action(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_core_reorient_action_from_protocol(
|
||||
action: ThreadEpiphanyReorientAction,
|
||||
) -> CoreEpiphanyReorientAction {
|
||||
match action {
|
||||
ThreadEpiphanyReorientAction::Resume => CoreEpiphanyReorientAction::Resume,
|
||||
ThreadEpiphanyReorientAction::Regather => CoreEpiphanyReorientAction::Regather,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_core_crrc_result_status(
|
||||
status: ThreadEpiphanyReorientResultStatus,
|
||||
) -> CoreEpiphanyCrrcResultStatus {
|
||||
|
|
@ -141,6 +151,79 @@ fn map_core_crrc_result_status(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_protocol_coordinator_source_signals(
|
||||
signals: EpiphanyCoordinatorSourceSignals,
|
||||
) -> ThreadEpiphanyCoordinatorSignals {
|
||||
ThreadEpiphanyCoordinatorSignals {
|
||||
pressure_level: map_protocol_pressure_level(signals.pressure_level),
|
||||
should_prepare_compaction: signals.should_prepare_compaction,
|
||||
reorient_action: map_protocol_reorient_action(signals.reorient_action),
|
||||
crrc_action: map_core_crrc_action(signals.crrc_action),
|
||||
modeling_result_status: map_protocol_coordinator_role_result_status(
|
||||
signals.modeling_result_status,
|
||||
),
|
||||
verification_result_status: map_protocol_coordinator_role_result_status(
|
||||
signals.verification_result_status,
|
||||
),
|
||||
reorient_result_status: map_protocol_crrc_result_status(signals.reorient_result_status),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_protocol_pressure_level(
|
||||
level: epiphany_core::EpiphanyPressureLevel,
|
||||
) -> codex_app_server_protocol::ThreadEpiphanyPressureLevel {
|
||||
match level {
|
||||
epiphany_core::EpiphanyPressureLevel::Unknown => {
|
||||
codex_app_server_protocol::ThreadEpiphanyPressureLevel::Unknown
|
||||
}
|
||||
epiphany_core::EpiphanyPressureLevel::Low => {
|
||||
codex_app_server_protocol::ThreadEpiphanyPressureLevel::Low
|
||||
}
|
||||
epiphany_core::EpiphanyPressureLevel::Elevated => {
|
||||
codex_app_server_protocol::ThreadEpiphanyPressureLevel::Elevated
|
||||
}
|
||||
epiphany_core::EpiphanyPressureLevel::High => {
|
||||
codex_app_server_protocol::ThreadEpiphanyPressureLevel::High
|
||||
}
|
||||
epiphany_core::EpiphanyPressureLevel::Critical => {
|
||||
codex_app_server_protocol::ThreadEpiphanyPressureLevel::Critical
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn map_protocol_reorient_action(
|
||||
action: CoreEpiphanyReorientAction,
|
||||
) -> ThreadEpiphanyReorientAction {
|
||||
match action {
|
||||
CoreEpiphanyReorientAction::Resume => ThreadEpiphanyReorientAction::Resume,
|
||||
CoreEpiphanyReorientAction::Regather => ThreadEpiphanyReorientAction::Regather,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_protocol_crrc_result_status(
|
||||
status: CoreEpiphanyCrrcResultStatus,
|
||||
) -> ThreadEpiphanyReorientResultStatus {
|
||||
match status {
|
||||
CoreEpiphanyCrrcResultStatus::MissingState => {
|
||||
ThreadEpiphanyReorientResultStatus::MissingState
|
||||
}
|
||||
CoreEpiphanyCrrcResultStatus::MissingBinding => {
|
||||
ThreadEpiphanyReorientResultStatus::MissingBinding
|
||||
}
|
||||
CoreEpiphanyCrrcResultStatus::BackendUnavailable => {
|
||||
ThreadEpiphanyReorientResultStatus::BackendUnavailable
|
||||
}
|
||||
CoreEpiphanyCrrcResultStatus::BackendMissing => {
|
||||
ThreadEpiphanyReorientResultStatus::BackendMissing
|
||||
}
|
||||
CoreEpiphanyCrrcResultStatus::Pending => ThreadEpiphanyReorientResultStatus::Pending,
|
||||
CoreEpiphanyCrrcResultStatus::Running => ThreadEpiphanyReorientResultStatus::Running,
|
||||
CoreEpiphanyCrrcResultStatus::Completed => ThreadEpiphanyReorientResultStatus::Completed,
|
||||
CoreEpiphanyCrrcResultStatus::Failed => ThreadEpiphanyReorientResultStatus::Failed,
|
||||
CoreEpiphanyCrrcResultStatus::Cancelled => ThreadEpiphanyReorientResultStatus::Cancelled,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_core_crrc_action(action: CoreEpiphanyCrrcAction) -> ThreadEpiphanyCrrcAction {
|
||||
match action {
|
||||
CoreEpiphanyCrrcAction::Continue => ThreadEpiphanyCrrcAction::Continue,
|
||||
|
|
@ -183,18 +266,21 @@ fn map_core_crrc_recommendation(
|
|||
}
|
||||
}
|
||||
|
||||
pub struct EpiphanyCoordinatorDecision {
|
||||
pub action: ThreadEpiphanyCoordinatorAction,
|
||||
pub target_role: Option<ThreadEpiphanyRoleId>,
|
||||
pub recommended_scene_action: Option<ThreadEpiphanySceneAction>,
|
||||
pub requires_review: bool,
|
||||
pub can_auto_run: bool,
|
||||
pub reason: String,
|
||||
pub type EpiphanyCoordinatorDecision = CoreEpiphanyCoordinatorDecision;
|
||||
|
||||
pub struct EpiphanyCoordinatorSourceSignals {
|
||||
pub pressure_level: epiphany_core::EpiphanyPressureLevel,
|
||||
pub should_prepare_compaction: bool,
|
||||
pub reorient_action: CoreEpiphanyReorientAction,
|
||||
pub crrc_action: CoreEpiphanyCrrcAction,
|
||||
pub modeling_result_status: CoreEpiphanyCoordinatorRoleResultStatus,
|
||||
pub verification_result_status: CoreEpiphanyCoordinatorRoleResultStatus,
|
||||
pub reorient_result_status: CoreEpiphanyCrrcResultStatus,
|
||||
}
|
||||
|
||||
pub struct EpiphanyCoordinatorStatus {
|
||||
pub decision: EpiphanyCoordinatorDecision,
|
||||
pub source_signals: ThreadEpiphanyCoordinatorSignals,
|
||||
pub source_signals: EpiphanyCoordinatorSourceSignals,
|
||||
pub roles: Vec<ThreadEpiphanyRoleLane>,
|
||||
pub note: String,
|
||||
pub modeling_result_accepted: bool,
|
||||
|
|
@ -206,7 +292,7 @@ pub async fn derive_epiphany_coordinator_status(
|
|||
state: Option<&EpiphanyThreadState>,
|
||||
runtime_store_path: Option<&Path>,
|
||||
state_status: ThreadEpiphanyReorientStateStatus,
|
||||
pressure: &ThreadEpiphanyPressure,
|
||||
pressure: &epiphany_core::EpiphanyPressure,
|
||||
recommendation: &ThreadEpiphanyCrrcRecommendation,
|
||||
roles: Vec<ThreadEpiphanyRoleLane>,
|
||||
reorient_decision: Option<&ThreadEpiphanyReorientDecision>,
|
||||
|
|
@ -285,16 +371,19 @@ pub async fn derive_epiphany_coordinator_status(
|
|||
let reorient_finding_accepted = reorient_finding.is_some_and(|finding| {
|
||||
state.is_some_and(|state| epiphany_reorient_finding_already_accepted(state, finding))
|
||||
});
|
||||
let source_signals = ThreadEpiphanyCoordinatorSignals {
|
||||
let source_signals = EpiphanyCoordinatorSourceSignals {
|
||||
pressure_level: pressure.level,
|
||||
should_prepare_compaction: pressure.should_prepare_compaction,
|
||||
reorient_action: reorient_decision
|
||||
.map(|decision| decision.action)
|
||||
.unwrap_or(ThreadEpiphanyReorientAction::Resume),
|
||||
crrc_action: recommendation.action,
|
||||
modeling_result_status,
|
||||
verification_result_status,
|
||||
reorient_result_status,
|
||||
.map(map_core_reorient_action_from_protocol)
|
||||
.unwrap_or(CoreEpiphanyReorientAction::Resume),
|
||||
crrc_action: map_core_crrc_action_from_protocol(recommendation.action),
|
||||
modeling_result_status: map_core_coordinator_role_result_status(modeling_result_status),
|
||||
verification_result_status: map_core_coordinator_role_result_status(
|
||||
verification_result_status,
|
||||
),
|
||||
reorient_result_status: map_core_crrc_result_status(reorient_result_status),
|
||||
};
|
||||
let decision = map_epiphany_coordinator(
|
||||
state_status,
|
||||
|
|
@ -316,11 +405,11 @@ pub async fn derive_epiphany_coordinator_status(
|
|||
);
|
||||
let note = render_epiphany_coordinator_note(
|
||||
recommendation.action,
|
||||
pressure.level,
|
||||
map_protocol_pressure_level(pressure.level),
|
||||
modeling_result_status,
|
||||
verification_result_status,
|
||||
reorient_result_status,
|
||||
decision.action,
|
||||
map_protocol_coordinator_action(decision.action),
|
||||
);
|
||||
|
||||
EpiphanyCoordinatorStatus {
|
||||
|
|
@ -350,13 +439,19 @@ pub fn map_epiphany_coordinator_view(
|
|||
},
|
||||
state_status,
|
||||
state_revision,
|
||||
action: status.decision.action,
|
||||
target_role: status.decision.target_role,
|
||||
recommended_scene_action: status.decision.recommended_scene_action,
|
||||
action: map_protocol_coordinator_action(status.decision.action),
|
||||
target_role: status
|
||||
.decision
|
||||
.target_role
|
||||
.map(map_protocol_coordinator_role_id),
|
||||
recommended_scene_action: status
|
||||
.decision
|
||||
.recommended_scene_action
|
||||
.map(map_protocol_coordinator_scene_action),
|
||||
requires_review: status.decision.requires_review,
|
||||
can_auto_run: status.decision.can_auto_run,
|
||||
reason: status.decision.reason,
|
||||
source_signals: status.source_signals,
|
||||
source_signals: map_protocol_coordinator_source_signals(status.source_signals),
|
||||
roles: status.roles,
|
||||
note: status.note,
|
||||
}
|
||||
|
|
@ -372,9 +467,7 @@ pub enum EpiphanyCoordinatorAutomationAction {
|
|||
pub fn map_epiphany_coordinator_automation_action(
|
||||
decision: &EpiphanyCoordinatorDecision,
|
||||
) -> EpiphanyCoordinatorAutomationAction {
|
||||
map_protocol_coordinator_automation_action(coordinator_automation_action(
|
||||
&map_core_coordinator_decision_from_protocol(decision),
|
||||
))
|
||||
map_protocol_coordinator_automation_action(coordinator_automation_action(decision))
|
||||
}
|
||||
|
||||
pub fn select_epiphany_coordinator_automation_action(
|
||||
|
|
@ -382,7 +475,7 @@ pub fn select_epiphany_coordinator_automation_action(
|
|||
force_checkpoint_compaction: bool,
|
||||
) -> EpiphanyCoordinatorAutomationAction {
|
||||
map_protocol_coordinator_automation_action(select_coordinator_automation_action(
|
||||
&map_core_coordinator_decision_from_protocol(decision),
|
||||
decision,
|
||||
force_checkpoint_compaction,
|
||||
))
|
||||
}
|
||||
|
|
@ -450,7 +543,7 @@ pub async fn select_epiphany_coordinator_automation(
|
|||
let crrc_recommendation = map_epiphany_crrc_recommendation(
|
||||
true,
|
||||
state_status,
|
||||
&pressure,
|
||||
&core_pressure,
|
||||
&reorient_decision,
|
||||
reorient_result_status,
|
||||
input.state.investigation_checkpoint.as_ref().is_some(),
|
||||
|
|
@ -470,7 +563,7 @@ pub async fn select_epiphany_coordinator_automation(
|
|||
Some(input.state),
|
||||
Some(input.runtime_store_path),
|
||||
state_status,
|
||||
&pressure,
|
||||
&core_pressure,
|
||||
&crrc_recommendation,
|
||||
roles,
|
||||
Some(&reorient_decision),
|
||||
|
|
@ -521,10 +614,10 @@ pub async fn select_epiphany_coordinator_automation(
|
|||
pub fn map_epiphany_coordinator(
|
||||
state_status: ThreadEpiphanyReorientStateStatus,
|
||||
checkpoint_present: bool,
|
||||
pressure: &ThreadEpiphanyPressure,
|
||||
pressure: &epiphany_core::EpiphanyPressure,
|
||||
recommendation: &ThreadEpiphanyCrrcRecommendation,
|
||||
roles: &[ThreadEpiphanyRoleLane],
|
||||
signals: &ThreadEpiphanyCoordinatorSignals,
|
||||
signals: &EpiphanyCoordinatorSourceSignals,
|
||||
modeling_result_accepted: bool,
|
||||
modeling_result_reviewable: bool,
|
||||
modeling_result_accepted_after_verification: bool,
|
||||
|
|
@ -536,19 +629,15 @@ pub fn map_epiphany_coordinator(
|
|||
verification_result_needs_evidence: bool,
|
||||
reorient_finding_accepted: bool,
|
||||
) -> EpiphanyCoordinatorDecision {
|
||||
map_core_coordinator_decision(recommend_coordinator_action(EpiphanyCoordinatorInput {
|
||||
recommend_coordinator_action(EpiphanyCoordinatorInput {
|
||||
state_status: map_core_crrc_state_status(state_status),
|
||||
checkpoint_present,
|
||||
should_prepare_compaction: pressure.should_prepare_compaction,
|
||||
recommendation: map_core_coordinator_crrc_recommendation(recommendation),
|
||||
roles: roles.iter().map(map_core_coordinator_role_lane).collect(),
|
||||
signals: EpiphanyCoordinatorSignals {
|
||||
modeling_result_status: map_core_coordinator_role_result_status(
|
||||
signals.modeling_result_status,
|
||||
),
|
||||
verification_result_status: map_core_coordinator_role_result_status(
|
||||
signals.verification_result_status,
|
||||
),
|
||||
modeling_result_status: signals.modeling_result_status,
|
||||
verification_result_status: signals.verification_result_status,
|
||||
},
|
||||
modeling_result_accepted,
|
||||
modeling_result_reviewable,
|
||||
|
|
@ -560,7 +649,7 @@ pub fn map_epiphany_coordinator(
|
|||
verification_result_allows_implementation,
|
||||
verification_result_needs_evidence,
|
||||
reorient_finding_accepted,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
fn map_core_coordinator_crrc_recommendation(
|
||||
|
|
@ -625,12 +714,6 @@ fn map_protocol_coordinator_role_id(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_core_coordinator_role_id_from_protocol(
|
||||
role_id: ThreadEpiphanyRoleId,
|
||||
) -> CoreEpiphanyCoordinatorRoleId {
|
||||
map_core_coordinator_role_id(role_id)
|
||||
}
|
||||
|
||||
fn map_core_coordinator_role_status(
|
||||
status: ThreadEpiphanyRoleStatus,
|
||||
) -> CoreEpiphanyCoordinatorRoleStatus {
|
||||
|
|
@ -674,6 +757,34 @@ fn map_core_coordinator_role_result_status(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_protocol_coordinator_role_result_status(
|
||||
status: CoreEpiphanyCoordinatorRoleResultStatus,
|
||||
) -> ThreadEpiphanyRoleResultStatus {
|
||||
match status {
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::MissingState => {
|
||||
ThreadEpiphanyRoleResultStatus::MissingState
|
||||
}
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::MissingBinding => {
|
||||
ThreadEpiphanyRoleResultStatus::MissingBinding
|
||||
}
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::BackendUnavailable => {
|
||||
ThreadEpiphanyRoleResultStatus::BackendUnavailable
|
||||
}
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::BackendMissing => {
|
||||
ThreadEpiphanyRoleResultStatus::BackendMissing
|
||||
}
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::Pending => ThreadEpiphanyRoleResultStatus::Pending,
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::Running => ThreadEpiphanyRoleResultStatus::Running,
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::Completed => {
|
||||
ThreadEpiphanyRoleResultStatus::Completed
|
||||
}
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::Failed => ThreadEpiphanyRoleResultStatus::Failed,
|
||||
CoreEpiphanyCoordinatorRoleResultStatus::Cancelled => {
|
||||
ThreadEpiphanyRoleResultStatus::Cancelled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn map_core_coordinator_scene_action_from_protocol(
|
||||
action: ThreadEpiphanySceneAction,
|
||||
) -> CoreEpiphanyCoordinatorSceneAction {
|
||||
|
|
@ -733,46 +844,6 @@ fn map_protocol_coordinator_scene_action(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_core_coordinator_action_from_protocol(
|
||||
action: ThreadEpiphanyCoordinatorAction,
|
||||
) -> CoreEpiphanyCoordinatorAction {
|
||||
match action {
|
||||
ThreadEpiphanyCoordinatorAction::PrepareCheckpoint => {
|
||||
CoreEpiphanyCoordinatorAction::PrepareCheckpoint
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::CompactRehydrateReorient => {
|
||||
CoreEpiphanyCoordinatorAction::CompactRehydrateReorient
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::LaunchReorientWorker => {
|
||||
CoreEpiphanyCoordinatorAction::LaunchReorientWorker
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::WaitForReorientWorker => {
|
||||
CoreEpiphanyCoordinatorAction::WaitForReorientWorker
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::ReviewReorientResult => {
|
||||
CoreEpiphanyCoordinatorAction::ReviewReorientResult
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::RegatherManually => {
|
||||
CoreEpiphanyCoordinatorAction::RegatherManually
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::LaunchModeling => {
|
||||
CoreEpiphanyCoordinatorAction::LaunchModeling
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::ReviewModelingResult => {
|
||||
CoreEpiphanyCoordinatorAction::ReviewModelingResult
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::LaunchVerification => {
|
||||
CoreEpiphanyCoordinatorAction::LaunchVerification
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::ReviewVerificationResult => {
|
||||
CoreEpiphanyCoordinatorAction::ReviewVerificationResult
|
||||
}
|
||||
ThreadEpiphanyCoordinatorAction::ContinueImplementation => {
|
||||
CoreEpiphanyCoordinatorAction::ContinueImplementation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn map_protocol_coordinator_action(
|
||||
action: CoreEpiphanyCoordinatorAction,
|
||||
) -> ThreadEpiphanyCoordinatorAction {
|
||||
|
|
@ -813,38 +884,6 @@ fn map_protocol_coordinator_action(
|
|||
}
|
||||
}
|
||||
|
||||
fn map_core_coordinator_decision_from_protocol(
|
||||
decision: &EpiphanyCoordinatorDecision,
|
||||
) -> CoreEpiphanyCoordinatorDecision {
|
||||
CoreEpiphanyCoordinatorDecision {
|
||||
action: map_core_coordinator_action_from_protocol(decision.action),
|
||||
target_role: decision
|
||||
.target_role
|
||||
.map(map_core_coordinator_role_id_from_protocol),
|
||||
recommended_scene_action: decision
|
||||
.recommended_scene_action
|
||||
.map(map_core_coordinator_scene_action_from_protocol),
|
||||
requires_review: decision.requires_review,
|
||||
can_auto_run: decision.can_auto_run,
|
||||
reason: decision.reason.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_core_coordinator_decision(
|
||||
decision: CoreEpiphanyCoordinatorDecision,
|
||||
) -> EpiphanyCoordinatorDecision {
|
||||
EpiphanyCoordinatorDecision {
|
||||
action: map_protocol_coordinator_action(decision.action),
|
||||
target_role: decision.target_role.map(map_protocol_coordinator_role_id),
|
||||
recommended_scene_action: decision
|
||||
.recommended_scene_action
|
||||
.map(map_protocol_coordinator_scene_action),
|
||||
requires_review: decision.requires_review,
|
||||
can_auto_run: decision.can_auto_run,
|
||||
reason: decision.reason,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_protocol_coordinator_automation_action(
|
||||
action: CoreEpiphanyCoordinatorAutomationAction,
|
||||
) -> EpiphanyCoordinatorAutomationAction {
|
||||
|
|
|
|||
|
|
@ -228,21 +228,22 @@ pub async fn map_epiphany_view_response(
|
|||
let reorient_finding_accepted = reorient_finding.as_ref().is_some_and(|finding| {
|
||||
state.is_some_and(|state| epiphany_reorient_finding_already_accepted(state, finding))
|
||||
});
|
||||
let recommendation =
|
||||
if let (Some(pressure), Some(decision)) = (pressure.as_ref(), reorient_decision.as_ref()) {
|
||||
Some(map_epiphany_crrc_recommendation(
|
||||
loaded,
|
||||
reorient_state_status,
|
||||
pressure,
|
||||
decision,
|
||||
reorient_result_status,
|
||||
checkpoint_present,
|
||||
reorient_finding.is_some(),
|
||||
reorient_finding_accepted,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let recommendation = if let (Some(core_pressure), Some(decision)) =
|
||||
(core_pressure.as_ref(), reorient_decision.as_ref())
|
||||
{
|
||||
Some(map_epiphany_crrc_recommendation(
|
||||
loaded,
|
||||
reorient_state_status,
|
||||
core_pressure,
|
||||
decision,
|
||||
reorient_result_status,
|
||||
checkpoint_present,
|
||||
reorient_finding.is_some(),
|
||||
reorient_finding_accepted,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let roles = if let (Some(pressure), Some(decision), Some(recommendation)) = (
|
||||
pressure.as_ref(),
|
||||
reorient_decision.as_ref(),
|
||||
|
|
@ -261,14 +262,16 @@ pub async fn map_epiphany_view_response(
|
|||
None
|
||||
};
|
||||
let coordinator_response = if lenses.contains(&ThreadEpiphanyViewLens::Coordinator) {
|
||||
if let (Some(pressure), Some(recommendation), Some(roles)) =
|
||||
(pressure.as_ref(), recommendation.as_ref(), roles.clone())
|
||||
{
|
||||
if let (Some(core_pressure), Some(recommendation), Some(roles)) = (
|
||||
core_pressure.as_ref(),
|
||||
recommendation.as_ref(),
|
||||
roles.clone(),
|
||||
) {
|
||||
let status = derive_epiphany_coordinator_status(
|
||||
state,
|
||||
runtime_store_path,
|
||||
reorient_state_status,
|
||||
pressure,
|
||||
core_pressure,
|
||||
recommendation,
|
||||
roles,
|
||||
reorient_decision.as_ref(),
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
use super::EpiphanyCrrcAction;
|
||||
use super::EpiphanyCrrcSceneAction;
|
||||
use super::EpiphanyCrrcStateStatus;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCoordinatorRoleId {
|
||||
Implementation,
|
||||
Imagination,
|
||||
|
|
@ -11,7 +14,8 @@ pub enum EpiphanyCoordinatorRoleId {
|
|||
Reorientation,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCoordinatorRoleStatus {
|
||||
Ready,
|
||||
Needed,
|
||||
|
|
@ -23,7 +27,8 @@ pub enum EpiphanyCoordinatorRoleStatus {
|
|||
Completed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCoordinatorRoleResultStatus {
|
||||
MissingState,
|
||||
MissingBinding,
|
||||
|
|
@ -36,7 +41,8 @@ pub enum EpiphanyCoordinatorRoleResultStatus {
|
|||
Cancelled,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCoordinatorAction {
|
||||
PrepareCheckpoint,
|
||||
CompactRehydrateReorient,
|
||||
|
|
@ -51,7 +57,8 @@ pub enum EpiphanyCoordinatorAction {
|
|||
ContinueImplementation,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCoordinatorSceneAction {
|
||||
Update,
|
||||
Reorient,
|
||||
|
|
@ -62,26 +69,30 @@ pub enum EpiphanyCoordinatorSceneAction {
|
|||
RoleResult,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCoordinatorAutomationAction {
|
||||
None,
|
||||
CompactRehydrateReorient,
|
||||
LaunchReorientWorker,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EpiphanyCoordinatorCrrcRecommendation {
|
||||
pub action: EpiphanyCrrcAction,
|
||||
pub recommended_scene_action: Option<EpiphanyCoordinatorSceneAction>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EpiphanyCoordinatorSignals {
|
||||
pub modeling_result_status: EpiphanyCoordinatorRoleResultStatus,
|
||||
pub verification_result_status: EpiphanyCoordinatorRoleResultStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EpiphanyCoordinatorRoleLane {
|
||||
pub id: EpiphanyCoordinatorRoleId,
|
||||
pub status: EpiphanyCoordinatorRoleStatus,
|
||||
|
|
@ -107,7 +118,8 @@ pub struct EpiphanyCoordinatorInput {
|
|||
pub reorient_finding_accepted: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EpiphanyCoordinatorDecision {
|
||||
pub action: EpiphanyCoordinatorAction,
|
||||
pub target_role: Option<EpiphanyCoordinatorRoleId>,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCrrcStateStatus {
|
||||
Missing,
|
||||
Ready,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCrrcReorientAction {
|
||||
Resume,
|
||||
Regather,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCrrcResultStatus {
|
||||
MissingState,
|
||||
MissingBinding,
|
||||
|
|
@ -23,7 +29,8 @@ pub enum EpiphanyCrrcResultStatus {
|
|||
Cancelled,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCrrcAction {
|
||||
Continue,
|
||||
PrepareCheckpoint,
|
||||
|
|
@ -34,7 +41,8 @@ pub enum EpiphanyCrrcAction {
|
|||
RegatherManually,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EpiphanyCrrcSceneAction {
|
||||
Update,
|
||||
Reorient,
|
||||
|
|
@ -43,7 +51,8 @@ pub enum EpiphanyCrrcSceneAction {
|
|||
ReorientAccept,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EpiphanyCrrcRecommendation {
|
||||
pub action: EpiphanyCrrcAction,
|
||||
pub recommended_scene_action: Option<EpiphanyCrrcSceneAction>,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ remembers doctrine; the branch remembers the blade.
|
|||
- `epiphany-codex-bridge` no longer depends on vendored `codex-core` at all. Retrieval takes workspace/Codex-home paths, invalidation owns a native `notify` watcher, runtime-result acceptance takes typed state plus runtime-store path, live rollout/thread reads moved into app-server `epiphany_thread_host`, and mutation policy depends on the small `EpiphanyMutationHost` trait implemented by app-server's `EpiphanyCodexThreadHost` wrapper. The bridge owns Epiphany law; vendored app-server owns CodexThread access.
|
||||
- `epiphany-codex-bridge` also no longer depends on `codex-protocol`. Bridge durable-state imports point at `epiphany-state-model`, token pressure takes native `EpiphanyTokenUsageSnapshot`, app-server maps Codex token telemetry at the host wall, Codex token usage rollout replay lives in `codex_message_processor/token_usage_replay.rs`, and bridge errors are `EpiphanyBridgeError`. The only remaining vendored bridge dependencies are app-server protocol DTOs and absolute path validation.
|
||||
- The first bridge JSON-RPC starvation cuts are landed. Freshness now returns a serializable `EpiphanyFreshnessSurface`, job launch/interrupt mutation results carry typed `EpiphanyJobView` plus separate host-edge launcher/backend ids, reorient/pre-compaction decisions consume typed `EpiphanyPressure`, reorient policy consumes typed freshness directly, and reorient launch documents/results use typed core reorient decisions/status before app-server projects them into legacy JSON-RPC DTOs. Continue by cutting the full view/coordinator board into typed surfaces, not by inventing adapters with nicer uniforms.
|
||||
- Coordinator decision/status is less contaminated now: `epiphany-codex-bridge` stores coordinator decisions and source signals as core-shaped types, core CRRC/coordinator surfaces serialize natively, and `ThreadEpiphany*` projection happens at the legacy view emission boundary. Keep cutting remaining role-board/result/reorient inputs until Aquarium/CultNet can read coordinator surfaces without JSON-RPC DTO authority.
|
||||
- MCP remains JSON because MCP is a JSON protocol. The latest processor cut only moved MCP refresh/OAuth/status/resource/tool-call route handling into `codex_message_processor/mcp_routes.rs`, reducing the root processor to about 8,977 lines; it did not claim MCP payloads are CultNet or make MCP an Epiphany-owned runtime contract.
|
||||
- Codex account auth route handling remains in vendored Codex but now lives in `codex_message_processor/auth_routes.rs`: API-key login, ChatGPT browser/device-code/external-token login, logout, auth status, account, rate limits, and add-credits nudge handling. This preserves Codex ownership of subscription auth while cutting the root processor to about 8,094 lines.
|
||||
- One-off command execution and command stream write/resize/terminate route handling now live in `codex_message_processor/command_routes.rs`; `CommandExecManager` remains the lifecycle owner, while the root processor is about 7,800 lines.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -134,7 +134,7 @@ accepted_design:
|
|||
- The `reorient` view lens derives a bounded read-only `resume` versus `regather` verdict from checkpoint, freshness, watcher, and pressure signals without mutating state, compacting, scheduling, or silently continuing work.
|
||||
- The `crrc` view lens composes pressure, the reorientation verdict, fixed reorient-worker binding/result status, finding read-back, and available actions into one read-only recommendation without launching, accepting, compacting, scheduling, or mutating state.
|
||||
- A narrow auditable coordinator is central to the MVP because implementation, modeling/checkpoint, verification/review, and CRRC automation feed each other's machine-signals. CRRC itself is harness workflow automation, not a specialist-agent soul: it watches pressure/continuity, ensures persistence, triggers compaction/rehydration/reorientation when needed, and may launch a bounded reorient-worker specialist when semantic regathering is required.
|
||||
- The `coordinator` view lens is the harness-native fixed-lane coordinator surface: it composes roles, pressure, reorient, CRRC, roleResult, and reorientResult into a read-only action recommendation with target role, source signals, review requirements, automation eligibility, reason, and current lane summaries without mutating state or launching work.
|
||||
- The `coordinator` view lens is the harness-native fixed-lane coordinator surface: it composes roles, pressure, reorient, CRRC, roleResult, and reorientResult into a read-only action recommendation with target role, source signals, review requirements, automation eligibility, reason, and current lane summaries without mutating state or launching work. Coordinator decision and source-signal authority now stays core-shaped inside `epiphany-codex-bridge`; `ThreadEpiphany*` projection is a legacy app-server emission step, not the internal decision model.
|
||||
- Coordinator implementation clearance is stricter than review acceptance: an accepted verification/review finding only opens the implementation gate when its verdict is `pass`; accepted `needs-evidence`, `needs-review`, or `fail` findings send the loop back toward modeling/checkpoint strengthening or reorientation instead of blessing a sick machine.
|
||||
- Coordinator regather handling is now fixed-lane first, not supervisor improvisation: `regatherManually` is a fallback only after reorient/modeling/verification review and launch lanes cannot advance the state, completed modeling findings must be reviewed before verification, and the CLI coordinator's explicit test-only `--auto-review` mode may accept modeling state patches before launching verification while production semantics remain review-gated.
|
||||
- Native `epiphany-mvp-coordinator` is the first auditable coordinator runner: it drives the fixed single-user lanes through app-server APIs, opens a native runtime-spine session, records native runtime job/result receipts for launched specialists and reorient workers when terminal results arrive, keeps semantic findings review-gated by default, and writes coordinator summaries, JSONL steps, rendered snapshots, transcript, stderr, runtime-spine status, and final next-action artifacts. It refuses direct backend-completion mutation; full specialist completion smoke must use live workers while the execution path is cauterized into CultNet.
|
||||
|
|
|
|||
Reference in a new issue