Remove protocol projection from reorient derivation

This commit is contained in:
Meta Vens 2026-05-20 14:09:06 +01:00
commit 37791c3fc0
6 changed files with 11 additions and 266 deletions

View file

@ -66,11 +66,11 @@ use crate::pressure::derive_epiphany_pressure;
use crate::protocol_edge::protocol_job_from_surface;
use crate::protocol_edge::protocol_pressure_level;
use crate::protocol_edge::protocol_reorient_result_status;
use crate::protocol_edge::protocol_reorient_state_status;
use crate::protocol_edge::protocol_role_result_status;
use crate::reorient::EpiphanyFreshnessWatcherSnapshot;
use crate::reorient::derive_epiphany_freshness_view;
use crate::reorient::derive_epiphany_reorient;
use crate::reorient::map_protocol_reorient_state_status;
use crate::runtime_results::load_core_epiphany_reorient_result_snapshot;
use crate::runtime_results::load_core_epiphany_role_result_snapshot;
@ -285,7 +285,7 @@ pub fn map_epiphany_coordinator_view(
} else {
ThreadEpiphanyRolesSource::Stored
},
state_status: map_protocol_reorient_state_status(state_status),
state_status: protocol_reorient_state_status(state_status),
state_revision,
action: map_protocol_coordinator_action(status.core.decision.action),
target_role: status

View file

@ -1,15 +1,3 @@
use codex_app_server_protocol::ThreadEpiphanyGraphFreshness;
use codex_app_server_protocol::ThreadEpiphanyGraphFreshnessStatus;
use codex_app_server_protocol::ThreadEpiphanyInvalidationInput;
use codex_app_server_protocol::ThreadEpiphanyInvalidationStatus;
use codex_app_server_protocol::ThreadEpiphanyPressureLevel;
use codex_app_server_protocol::ThreadEpiphanyReorientAction;
use codex_app_server_protocol::ThreadEpiphanyReorientCheckpointStatus;
use codex_app_server_protocol::ThreadEpiphanyReorientDecision;
use codex_app_server_protocol::ThreadEpiphanyReorientReason;
use codex_app_server_protocol::ThreadEpiphanyReorientStateStatus;
use codex_app_server_protocol::ThreadEpiphanyRetrievalFreshness;
use codex_app_server_protocol::ThreadEpiphanyRetrievalFreshnessStatus;
use epiphany_core::EpiphanyFreshnessInput;
use epiphany_core::EpiphanyFreshnessView;
use epiphany_core::EpiphanyFreshnessWatcherInput;
@ -19,13 +7,10 @@ use epiphany_core::EpiphanyInvalidationInput as CoreEpiphanyInvalidationInput;
use epiphany_core::EpiphanyInvalidationStatus as CoreEpiphanyInvalidationStatus;
use epiphany_core::EpiphanyPressure;
use epiphany_core::EpiphanyPressureLevel;
use epiphany_core::EpiphanyReorientAction as CoreEpiphanyReorientAction;
use epiphany_core::EpiphanyReorientCheckpointStatus as CoreEpiphanyReorientCheckpointStatus;
use epiphany_core::EpiphanyReorientDecision as CoreEpiphanyReorientDecision;
use epiphany_core::EpiphanyReorientFreshnessStatus as CoreEpiphanyReorientFreshnessStatus;
use epiphany_core::EpiphanyReorientInput;
use epiphany_core::EpiphanyReorientPressureLevel as CoreEpiphanyReorientPressureLevel;
use epiphany_core::EpiphanyReorientReason as CoreEpiphanyReorientReason;
use epiphany_core::EpiphanyReorientStateStatus as CoreEpiphanyReorientStateStatus;
use epiphany_core::EpiphanyRetrievalFreshness as CoreEpiphanyRetrievalFreshness;
use epiphany_core::EpiphanyRetrievalFreshnessStatus as CoreEpiphanyRetrievalFreshnessStatus;
@ -43,20 +28,6 @@ pub struct EpiphanyFreshnessWatcherSnapshot<'a> {
pub changed_paths: &'a [PathBuf],
}
pub fn map_epiphany_freshness(
state: Option<&EpiphanyThreadState>,
retrieval_override: Option<&EpiphanyRetrievalState>,
watcher_snapshot: Option<EpiphanyFreshnessWatcherSnapshot<'_>>,
) -> (
Option<u64>,
ThreadEpiphanyRetrievalFreshness,
ThreadEpiphanyGraphFreshness,
ThreadEpiphanyInvalidationInput,
) {
let freshness = derive_epiphany_freshness_view(state, retrieval_override, watcher_snapshot);
map_core_epiphany_freshness(freshness)
}
pub fn derive_epiphany_freshness_view(
state: Option<&EpiphanyThreadState>,
retrieval_override: Option<&EpiphanyRetrievalState>,
@ -75,94 +46,6 @@ pub fn derive_epiphany_freshness_view(
})
}
fn map_core_epiphany_freshness(
freshness: EpiphanyFreshnessView,
) -> (
Option<u64>,
ThreadEpiphanyRetrievalFreshness,
ThreadEpiphanyGraphFreshness,
ThreadEpiphanyInvalidationInput,
) {
(
freshness.state_revision,
map_core_epiphany_retrieval_freshness(freshness.retrieval),
map_core_epiphany_graph_freshness(freshness.graph),
map_core_epiphany_invalidation_input(freshness.watcher),
)
}
fn map_core_epiphany_retrieval_freshness(
retrieval: CoreEpiphanyRetrievalFreshness,
) -> ThreadEpiphanyRetrievalFreshness {
ThreadEpiphanyRetrievalFreshness {
status: match retrieval.status {
CoreEpiphanyRetrievalFreshnessStatus::Missing => {
ThreadEpiphanyRetrievalFreshnessStatus::Missing
}
CoreEpiphanyRetrievalFreshnessStatus::Ready => {
ThreadEpiphanyRetrievalFreshnessStatus::Ready
}
CoreEpiphanyRetrievalFreshnessStatus::Stale => {
ThreadEpiphanyRetrievalFreshnessStatus::Stale
}
CoreEpiphanyRetrievalFreshnessStatus::Indexing => {
ThreadEpiphanyRetrievalFreshnessStatus::Indexing
}
CoreEpiphanyRetrievalFreshnessStatus::Unavailable => {
ThreadEpiphanyRetrievalFreshnessStatus::Unavailable
}
},
semantic_available: retrieval.semantic_available,
last_indexed_at_unix_seconds: retrieval.last_indexed_at_unix_seconds,
indexed_file_count: retrieval.indexed_file_count,
indexed_chunk_count: retrieval.indexed_chunk_count,
dirty_paths: retrieval.dirty_paths,
note: retrieval.note,
}
}
fn map_core_epiphany_graph_freshness(
graph: CoreEpiphanyGraphFreshness,
) -> ThreadEpiphanyGraphFreshness {
ThreadEpiphanyGraphFreshness {
status: match graph.status {
CoreEpiphanyGraphFreshnessStatus::Missing => {
ThreadEpiphanyGraphFreshnessStatus::Missing
}
CoreEpiphanyGraphFreshnessStatus::Ready => ThreadEpiphanyGraphFreshnessStatus::Ready,
CoreEpiphanyGraphFreshnessStatus::Stale => ThreadEpiphanyGraphFreshnessStatus::Stale,
},
graph_freshness: graph.graph_freshness,
checkpoint_id: graph.checkpoint_id,
dirty_path_count: graph.dirty_path_count,
dirty_paths: graph.dirty_paths,
open_question_count: graph.open_question_count,
open_gap_count: graph.open_gap_count,
note: graph.note,
}
}
fn map_core_epiphany_invalidation_input(
watcher: CoreEpiphanyInvalidationInput,
) -> ThreadEpiphanyInvalidationInput {
ThreadEpiphanyInvalidationInput {
status: match watcher.status {
CoreEpiphanyInvalidationStatus::Unavailable => {
ThreadEpiphanyInvalidationStatus::Unavailable
}
CoreEpiphanyInvalidationStatus::Clean => ThreadEpiphanyInvalidationStatus::Clean,
CoreEpiphanyInvalidationStatus::Changed => ThreadEpiphanyInvalidationStatus::Changed,
},
watched_root: watcher.watched_root,
observed_at_unix_seconds: watcher.observed_at_unix_seconds,
changed_path_count: watcher.changed_path_count,
changed_paths: watcher.changed_paths,
graph_node_ids: watcher.graph_node_ids,
active_frontier_node_ids: watcher.active_frontier_node_ids,
note: watcher.note,
}
}
pub fn derive_epiphany_reorient(
state: Option<&EpiphanyThreadState>,
pressure: &EpiphanyPressure,
@ -236,146 +119,3 @@ fn map_core_reorient_watcher_status(
CoreEpiphanyInvalidationStatus::Changed => CoreEpiphanyReorientFreshnessStatus::Changed,
}
}
pub fn map_protocol_reorient_state_status(
status: CoreEpiphanyReorientStateStatus,
) -> ThreadEpiphanyReorientStateStatus {
match status {
CoreEpiphanyReorientStateStatus::Missing => ThreadEpiphanyReorientStateStatus::Missing,
CoreEpiphanyReorientStateStatus::Ready => ThreadEpiphanyReorientStateStatus::Ready,
}
}
pub fn map_protocol_reorient_decision(
decision: epiphany_core::EpiphanyReorientDecision,
) -> ThreadEpiphanyReorientDecision {
ThreadEpiphanyReorientDecision {
action: map_protocol_reorient_action(decision.action),
checkpoint_status: map_protocol_reorient_checkpoint_status(decision.checkpoint_status),
checkpoint_id: decision.checkpoint_id,
pressure_level: map_protocol_reorient_pressure_level(decision.pressure_level),
retrieval_status: map_protocol_reorient_retrieval_status(decision.retrieval_status),
graph_status: map_protocol_reorient_graph_status(decision.graph_status),
watcher_status: map_protocol_reorient_watcher_status(decision.watcher_status),
reasons: decision
.reasons
.into_iter()
.map(map_protocol_reorient_reason)
.collect(),
checkpoint_dirty_paths: decision.checkpoint_dirty_paths,
checkpoint_changed_paths: decision.checkpoint_changed_paths,
active_frontier_node_ids: decision.active_frontier_node_ids,
next_action: decision.next_action,
note: decision.note,
}
}
fn map_protocol_reorient_action(
action: CoreEpiphanyReorientAction,
) -> ThreadEpiphanyReorientAction {
match action {
CoreEpiphanyReorientAction::Resume => ThreadEpiphanyReorientAction::Resume,
CoreEpiphanyReorientAction::Regather => ThreadEpiphanyReorientAction::Regather,
}
}
fn map_protocol_reorient_checkpoint_status(
status: CoreEpiphanyReorientCheckpointStatus,
) -> ThreadEpiphanyReorientCheckpointStatus {
match status {
CoreEpiphanyReorientCheckpointStatus::Missing => {
ThreadEpiphanyReorientCheckpointStatus::Missing
}
CoreEpiphanyReorientCheckpointStatus::ResumeReady => {
ThreadEpiphanyReorientCheckpointStatus::ResumeReady
}
CoreEpiphanyReorientCheckpointStatus::RegatherRequired => {
ThreadEpiphanyReorientCheckpointStatus::RegatherRequired
}
}
}
fn map_protocol_reorient_pressure_level(
level: CoreEpiphanyReorientPressureLevel,
) -> ThreadEpiphanyPressureLevel {
match level {
CoreEpiphanyReorientPressureLevel::Unknown => ThreadEpiphanyPressureLevel::Unknown,
CoreEpiphanyReorientPressureLevel::Low => ThreadEpiphanyPressureLevel::Low,
CoreEpiphanyReorientPressureLevel::Medium => ThreadEpiphanyPressureLevel::Elevated,
CoreEpiphanyReorientPressureLevel::High => ThreadEpiphanyPressureLevel::High,
CoreEpiphanyReorientPressureLevel::Critical => ThreadEpiphanyPressureLevel::Critical,
}
}
fn map_protocol_reorient_retrieval_status(
status: CoreEpiphanyReorientFreshnessStatus,
) -> ThreadEpiphanyRetrievalFreshnessStatus {
match status {
CoreEpiphanyReorientFreshnessStatus::Unknown => {
ThreadEpiphanyRetrievalFreshnessStatus::Missing
}
CoreEpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyRetrievalFreshnessStatus::Ready,
CoreEpiphanyReorientFreshnessStatus::Dirty => {
ThreadEpiphanyRetrievalFreshnessStatus::Indexing
}
CoreEpiphanyReorientFreshnessStatus::Stale
| CoreEpiphanyReorientFreshnessStatus::Changed => {
ThreadEpiphanyRetrievalFreshnessStatus::Stale
}
}
}
fn map_protocol_reorient_graph_status(
status: CoreEpiphanyReorientFreshnessStatus,
) -> ThreadEpiphanyGraphFreshnessStatus {
match status {
CoreEpiphanyReorientFreshnessStatus::Unknown => ThreadEpiphanyGraphFreshnessStatus::Missing,
CoreEpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyGraphFreshnessStatus::Ready,
CoreEpiphanyReorientFreshnessStatus::Dirty
| CoreEpiphanyReorientFreshnessStatus::Stale
| CoreEpiphanyReorientFreshnessStatus::Changed => ThreadEpiphanyGraphFreshnessStatus::Stale,
}
}
fn map_protocol_reorient_watcher_status(
status: CoreEpiphanyReorientFreshnessStatus,
) -> ThreadEpiphanyInvalidationStatus {
match status {
CoreEpiphanyReorientFreshnessStatus::Unknown => {
ThreadEpiphanyInvalidationStatus::Unavailable
}
CoreEpiphanyReorientFreshnessStatus::Clean => ThreadEpiphanyInvalidationStatus::Clean,
CoreEpiphanyReorientFreshnessStatus::Dirty
| CoreEpiphanyReorientFreshnessStatus::Stale
| CoreEpiphanyReorientFreshnessStatus::Changed => ThreadEpiphanyInvalidationStatus::Changed,
}
}
fn map_protocol_reorient_reason(
reason: CoreEpiphanyReorientReason,
) -> ThreadEpiphanyReorientReason {
match reason {
CoreEpiphanyReorientReason::MissingState => ThreadEpiphanyReorientReason::MissingState,
CoreEpiphanyReorientReason::MissingCheckpoint => {
ThreadEpiphanyReorientReason::MissingCheckpoint
}
CoreEpiphanyReorientReason::CheckpointReady => {
ThreadEpiphanyReorientReason::CheckpointReady
}
CoreEpiphanyReorientReason::CheckpointRequestedRegather => {
ThreadEpiphanyReorientReason::CheckpointRequestedRegather
}
CoreEpiphanyReorientReason::CheckpointPathsDirty => {
ThreadEpiphanyReorientReason::CheckpointPathsDirty
}
CoreEpiphanyReorientReason::CheckpointPathsChanged => {
ThreadEpiphanyReorientReason::CheckpointPathsChanged
}
CoreEpiphanyReorientReason::FrontierChanged => {
ThreadEpiphanyReorientReason::FrontierChanged
}
CoreEpiphanyReorientReason::UnanchoredCheckpointWhileStateStale => {
ThreadEpiphanyReorientReason::UnanchoredCheckpointWhileStateStale
}
}
}

View file

@ -36,13 +36,13 @@ use crate::launch::EPIPHANY_REORIENT_LAUNCH_BINDING_ID;
use crate::pressure::derive_epiphany_pressure;
use crate::pressure::map_epiphany_pressure;
use crate::protocol_edge::protocol_job_from_surface;
use crate::protocol_edge::protocol_reorient_decision;
use crate::protocol_edge::protocol_reorient_result_status;
use crate::protocol_edge::protocol_reorient_state_status;
use crate::protocol_edge::protocol_role_result_status;
use crate::reorient::EpiphanyFreshnessWatcherSnapshot;
use crate::reorient::derive_epiphany_freshness_view;
use crate::reorient::derive_epiphany_reorient;
use crate::reorient::map_protocol_reorient_decision;
use crate::reorient::map_protocol_reorient_state_status;
use crate::results::map_protocol_reorient_finding;
use crate::results::map_protocol_role_result_role_id;
use crate::runtime_results::load_core_epiphany_reorient_result_snapshot;
@ -190,10 +190,10 @@ pub async fn map_epiphany_view_response(
None,
)
};
let reorient_state_status = map_protocol_reorient_state_status(core_reorient_state_status);
let reorient_state_status = protocol_reorient_state_status(core_reorient_state_status);
let reorient_decision = core_reorient_decision
.clone()
.map(map_protocol_reorient_decision);
.map(protocol_reorient_decision);
let jobs = if needs_jobs {
map_epiphany_jobs(state, retrieval_override)
} else {

View file

@ -83,6 +83,7 @@ remembers doctrine; the branch remembers the blade.
- Job projection has one mapper now. `epiphany-codex-bridge::jobs` derives typed `EpiphanyJobView` and no longer imports app-server protocol DTOs; `protocol_edge::protocol_job_from_surface` is the only `EpiphanyJobView` -> `ThreadEpiphanyJob` conversion path.
- Runtime result loading is typed-only now. Role/reorient result status projection moved out of `runtime_results` and duplicate coordinator helpers into `protocol_edge`, so view and coordinator response builders share one Codex JSON-RPC status mapper.
- Pressure projection is centralized too. `pressure.rs` derives typed `EpiphanyPressure`, coordinator consumes typed pressure signals, and `protocol_edge` owns the `ThreadEpiphanyPressure*` DTO mapping.
- Reorientation derivation is typed-only too. `reorient.rs` no longer imports app-server protocol DTOs and no longer exposes the unused freshness DTO tuple; view/coordinator response builders call `protocol_edge` for reorient state/decision projection.
- 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.

View file

@ -410,6 +410,10 @@ current_status:
typed `EpiphanyPressure`, coordinator consumes typed pressure signals, and
`protocol_edge` owns the `EpiphanyPressure` /
`EpiphanyPressureLevel` -> `ThreadEpiphanyPressure*` mapping.
Reorientation derivation is now typed-only at its module boundary:
`reorient.rs` no longer imports Codex app-server protocol DTOs, no longer
exposes the unused freshness DTO tuple, and view/coordinator response
builders use `protocol_edge` for reorient state/decision projection.
The bridge still depends on vendored Codex for app-server protocol DTOs and
absolute path validation, so the purification is not done.
next_action: Continue Codex starvation and CultNet liberation by cutting bridge-internal response/projection authority. Prioritize the next coordinator/view seam that still composes policy-shaped facts instead of merely loading host facts and projecting core surfaces; keep MCP/OpenAI JSON only at their true protocol/text edges. Do not add compatibility adapters unless they protect a named ownership invariant.