diff --git a/epiphany-codex-bridge/src/protocol_edge.rs b/epiphany-codex-bridge/src/protocol_edge.rs index 937da68b..c7fcbaf2 100644 --- a/epiphany-codex-bridge/src/protocol_edge.rs +++ b/epiphany-codex-bridge/src/protocol_edge.rs @@ -48,6 +48,7 @@ use codex_app_server_protocol::ThreadEpiphanyRoleResultStatus; use codex_app_server_protocol::ThreadEpiphanyRoleSelfPersistenceReview; use codex_app_server_protocol::ThreadEpiphanyRoleSelfPersistenceStatus; use codex_app_server_protocol::ThreadEpiphanyRoleWorkerLaunchDocument; +use codex_app_server_protocol::ThreadEpiphanyRolesSource; use codex_app_server_protocol::ThreadEpiphanyStateUpdatedField; use codex_app_server_protocol::ThreadEpiphanyStateUpdatedNotification; use codex_app_server_protocol::ThreadEpiphanyStateUpdatedSource; @@ -91,6 +92,19 @@ pub fn protocol_view_lenses_to_core(lenses: Vec) -> Vec< lenses.into_iter().map(protocol_view_lens_to_core).collect() } +pub fn protocol_view_lens_from_core(lens: EpiphanyViewLens) -> ThreadEpiphanyViewLens { + match lens { + EpiphanyViewLens::Scene => ThreadEpiphanyViewLens::Scene, + EpiphanyViewLens::Jobs => ThreadEpiphanyViewLens::Jobs, + EpiphanyViewLens::Roles => ThreadEpiphanyViewLens::Roles, + EpiphanyViewLens::Planning => ThreadEpiphanyViewLens::Planning, + EpiphanyViewLens::Pressure => ThreadEpiphanyViewLens::Pressure, + EpiphanyViewLens::Reorient => ThreadEpiphanyViewLens::Reorient, + EpiphanyViewLens::Crrc => ThreadEpiphanyViewLens::Crrc, + EpiphanyViewLens::Coordinator => ThreadEpiphanyViewLens::Coordinator, + } +} + pub fn core_epiphany_view_needs_jobs(lenses: &[EpiphanyViewLens]) -> bool { epiphany_view_needs_jobs(lenses) } @@ -475,6 +489,13 @@ pub fn protocol_reorient_source(source: EpiphanySurfaceSource) -> ThreadEpiphany } } +pub fn protocol_roles_source(source: EpiphanySurfaceSource) -> ThreadEpiphanyRolesSource { + match source { + EpiphanySurfaceSource::Stored => ThreadEpiphanyRolesSource::Stored, + EpiphanySurfaceSource::Live => ThreadEpiphanyRolesSource::Live, + } +} + pub fn protocol_reorient_decision( decision: EpiphanyReorientDecision, ) -> ThreadEpiphanyReorientDecision { diff --git a/epiphany-codex-bridge/src/view.rs b/epiphany-codex-bridge/src/view.rs index 9ee9a9b5..8fcd3d34 100644 --- a/epiphany-codex-bridge/src/view.rs +++ b/epiphany-codex-bridge/src/view.rs @@ -42,10 +42,13 @@ use crate::protocol_edge::protocol_pressure_from_core; use crate::protocol_edge::protocol_reorient_decision; use crate::protocol_edge::protocol_reorient_finding; use crate::protocol_edge::protocol_reorient_result_status; +use crate::protocol_edge::protocol_reorient_source; use crate::protocol_edge::protocol_reorient_state_status; use crate::protocol_edge::protocol_role_finding; use crate::protocol_edge::protocol_role_id_from_core; use crate::protocol_edge::protocol_role_result_status; +use crate::protocol_edge::protocol_roles_source; +use crate::protocol_edge::protocol_view_lens_from_core; use crate::reorient::EpiphanyFreshnessWatcherSnapshot; use crate::reorient::derive_epiphany_freshness_view; use crate::reorient::derive_epiphany_reorient; @@ -55,19 +58,6 @@ use crate::scene::derive_epiphany_scene; use crate::scene_protocol::protocol_scene; use crate::scene_protocol::protocol_scene_action; -fn map_protocol_epiphany_view_lens(lens: EpiphanyViewLens) -> ThreadEpiphanyViewLens { - match lens { - EpiphanyViewLens::Scene => ThreadEpiphanyViewLens::Scene, - EpiphanyViewLens::Jobs => ThreadEpiphanyViewLens::Jobs, - EpiphanyViewLens::Roles => ThreadEpiphanyViewLens::Roles, - EpiphanyViewLens::Planning => ThreadEpiphanyViewLens::Planning, - EpiphanyViewLens::Pressure => ThreadEpiphanyViewLens::Pressure, - EpiphanyViewLens::Reorient => ThreadEpiphanyViewLens::Reorient, - EpiphanyViewLens::Crrc => ThreadEpiphanyViewLens::Crrc, - EpiphanyViewLens::Coordinator => ThreadEpiphanyViewLens::Coordinator, - } -} - pub struct EpiphanyFreshnessResponseInput<'a> { pub thread_id: String, pub loaded: bool, @@ -436,7 +426,7 @@ pub async fn map_epiphany_view_response( coordinator: coordinator_response, lenses: lenses .into_iter() - .map(map_protocol_epiphany_view_lens) + .map(protocol_view_lens_from_core) .collect(), } } @@ -462,13 +452,15 @@ pub async fn map_epiphany_role_result_response( runtime_store_path, } = input; let protocol_role_id = protocol_role_id_from_core(role_id); - let protocol_source = map_protocol_roles_source(source); + let protocol_source = protocol_roles_source(source); let Some(state) = state else { return ThreadEpiphanyRoleResultResponse { thread_id, role_id: protocol_role_id, source: protocol_source, - state_status: ThreadEpiphanyReorientStateStatus::Missing, + state_status: protocol_reorient_state_status( + epiphany_core::EpiphanyReorientStateStatus::Missing, + ), state_revision: None, binding_id, status: ThreadEpiphanyRoleResultStatus::MissingState, @@ -490,7 +482,9 @@ pub async fn map_epiphany_role_result_response( thread_id, role_id: protocol_role_id, source: protocol_source, - state_status: ThreadEpiphanyReorientStateStatus::Ready, + state_status: protocol_reorient_state_status( + epiphany_core::EpiphanyReorientStateStatus::Ready, + ), state_revision: Some(state.revision), binding_id, status: protocol_role_result_status(result.status), @@ -520,12 +514,14 @@ pub async fn map_epiphany_reorient_result_response( state, runtime_store_path, } = input; - let protocol_source = map_protocol_reorient_result_source(source); + let protocol_source = protocol_reorient_source(source); let Some(state) = state else { return ThreadEpiphanyReorientResultResponse { thread_id, source: protocol_source, - state_status: ThreadEpiphanyReorientStateStatus::Missing, + state_status: protocol_reorient_state_status( + epiphany_core::EpiphanyReorientStateStatus::Missing, + ), state_revision: None, binding_id, status: ThreadEpiphanyReorientResultStatus::MissingState, @@ -546,7 +542,9 @@ pub async fn map_epiphany_reorient_result_response( ThreadEpiphanyReorientResultResponse { thread_id, source: protocol_source, - state_status: ThreadEpiphanyReorientStateStatus::Ready, + state_status: protocol_reorient_state_status( + epiphany_core::EpiphanyReorientStateStatus::Ready, + ), state_revision: Some(state.revision), binding_id, status: protocol_reorient_result_status(result.status), @@ -556,22 +554,6 @@ pub async fn map_epiphany_reorient_result_response( } } -fn map_protocol_roles_source(source: EpiphanySurfaceSource) -> ThreadEpiphanyRolesSource { - match source { - EpiphanySurfaceSource::Live => ThreadEpiphanyRolesSource::Live, - EpiphanySurfaceSource::Stored => ThreadEpiphanyRolesSource::Stored, - } -} - -fn map_protocol_reorient_result_source( - source: EpiphanySurfaceSource, -) -> ThreadEpiphanyReorientSource { - match source { - EpiphanySurfaceSource::Live => ThreadEpiphanyReorientSource::Live, - EpiphanySurfaceSource::Stored => ThreadEpiphanyReorientSource::Stored, - } -} - pub fn map_epiphany_distill_response( expected_revision: u64, input: EpiphanyDistillInput, diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index fe8995f9..5f22be0e 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -91,6 +91,7 @@ remembers doctrine; the branch remembers the blade. - Context/planning/graph projection is split out too. `context.rs` returns typed `epiphany-core` view documents; `context_protocol.rs` owns Codex JSON-RPC tuple/projection cargo for context, planning, and graph-query responses. - Scene projection is split out too. `scene.rs` returns the typed core `EpiphanyScene`; `scene_protocol.rs` owns `ThreadEpiphanyScene` and scene-action response projection. - Retrieval projection is split out too. `retrieve.rs` normalizes, indexes, looks up state, and retrieves typed core results; `retrieve_protocol.rs` owns Codex JSON-RPC retrieve/index response projection and absolute-path DTO validation. +- View response assembly no longer owns private lens/source/reorient-status projection helpers; those enum conversions route through `protocol_edge`. The larger typed-view wall is still the next architectural judgment, not something to fake with another adapter. - 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. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 64f5c4b7..7e05f1ce 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 7be5f5be..20d13c9b 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -443,6 +443,10 @@ current_status: indexing, state lookup, and typed retrieval responses; `retrieve_protocol.rs` owns Codex JSON-RPC retrieve/index response projection and absolute-path DTO validation. + View response assembly no longer owns private lens/source/reorient-status + projection helpers; those small enum conversions route through + `protocol_edge`, so `view.rs` does not grow a second protocol dialect while + the larger typed-view wall remains under judgment. 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.