From 6d055ab51894799b6771e4eac021d3f70c8a76ea Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 20 May 2026 02:37:10 +0100 Subject: [PATCH] Keep changed fields core-shaped --- epiphany-codex-bridge/src/cultnet.rs | 5 +- epiphany-codex-bridge/src/mutation.rs | 108 ++++++++++++------ epiphany-codex-bridge/src/mutation_service.rs | 16 +-- epiphany-core/src/lib.rs | 1 + epiphany-core/src/state_update.rs | 21 ++++ notes/fresh-workspace-handoff.md | 1 + state/ledgers.msgpack | Bin 137636 -> 137924 bytes state/map.yaml | 10 +- .../epiphany_automation.rs | 5 +- .../epiphany_mutation_routes.rs | 28 +++-- 10 files changed, 139 insertions(+), 56 deletions(-) diff --git a/epiphany-codex-bridge/src/cultnet.rs b/epiphany-codex-bridge/src/cultnet.rs index 25540b00..3c9f6920 100644 --- a/epiphany-codex-bridge/src/cultnet.rs +++ b/epiphany-codex-bridge/src/cultnet.rs @@ -1,7 +1,6 @@ use epiphany_core::EpiphanyGraphFreshness; -use epiphany_core::EpiphanyInvalidationInput; -use epiphany_core::EpiphanyRetrievalFreshness; pub use epiphany_core::EpiphanyGraphFreshnessStatus; +use epiphany_core::EpiphanyInvalidationInput; pub use epiphany_core::EpiphanyInvalidationStatus; pub use epiphany_core::EpiphanyJobStatus; pub use epiphany_core::EpiphanyJobView; @@ -16,7 +15,9 @@ pub use epiphany_core::EpiphanyReorientFreshnessStatus; pub use epiphany_core::EpiphanyReorientPressureLevel; pub use epiphany_core::EpiphanyReorientReason; pub use epiphany_core::EpiphanyReorientStateStatus; +use epiphany_core::EpiphanyRetrievalFreshness; pub use epiphany_core::EpiphanyRetrievalFreshnessStatus; +pub use epiphany_core::EpiphanyStateUpdatedField; pub use epiphany_state_model::EpiphanyJobKind; use serde::Deserialize; use serde::Serialize; diff --git a/epiphany-codex-bridge/src/mutation.rs b/epiphany-codex-bridge/src/mutation.rs index 08c2359d..4a61312d 100644 --- a/epiphany-codex-bridge/src/mutation.rs +++ b/epiphany-codex-bridge/src/mutation.rs @@ -9,6 +9,7 @@ use epiphany_core::EpiphanyRoleAcceptanceFinding; use epiphany_core::EpiphanyRoleFindingInterpretation as CoreEpiphanyRoleFinding; use epiphany_core::EpiphanyRoleStatePatchDocument; use epiphany_core::EpiphanyStateUpdate; +use epiphany_core::EpiphanyStateUpdatedField; use epiphany_core::build_reorient_acceptance_bundle; use epiphany_core::build_role_acceptance_bundle; use epiphany_core::imagination_role_state_patch_policy_errors; @@ -20,7 +21,7 @@ use crate::results::map_core_role_result_role_id; pub struct RoleAcceptanceUpdate { pub state_update: EpiphanyStateUpdate, pub applied_patch: EpiphanyRoleStatePatchDocument, - pub changed_fields: Vec, + pub changed_fields: Vec, pub accepted_receipt_id: String, pub accepted_observation_id: String, pub accepted_evidence_id: String, @@ -28,7 +29,7 @@ pub struct RoleAcceptanceUpdate { pub struct ReorientAcceptanceUpdate { pub state_update: EpiphanyStateUpdate, - pub changed_fields: Vec, + pub changed_fields: Vec, pub accepted_receipt_id: String, pub accepted_observation_id: String, pub accepted_evidence_id: String, @@ -128,18 +129,59 @@ pub fn epiphany_state_updated_notification( thread_id: String, source: ThreadEpiphanyStateUpdatedSource, revision: u64, - changed_fields: Vec, + changed_fields: Vec, epiphany_state: epiphany_state_model::EpiphanyThreadState, ) -> ThreadEpiphanyStateUpdatedNotification { ThreadEpiphanyStateUpdatedNotification { thread_id, source, revision, - changed_fields, + changed_fields: map_protocol_state_updated_fields(changed_fields), epiphany_state, } } +pub fn map_protocol_state_updated_fields( + fields: Vec, +) -> Vec { + fields + .into_iter() + .map(map_protocol_state_updated_field) + .collect() +} + +pub fn map_protocol_state_updated_field( + field: EpiphanyStateUpdatedField, +) -> ThreadEpiphanyStateUpdatedField { + match field { + EpiphanyStateUpdatedField::Objective => ThreadEpiphanyStateUpdatedField::Objective, + EpiphanyStateUpdatedField::ActiveSubgoalId => { + ThreadEpiphanyStateUpdatedField::ActiveSubgoalId + } + EpiphanyStateUpdatedField::Subgoals => ThreadEpiphanyStateUpdatedField::Subgoals, + EpiphanyStateUpdatedField::Invariants => ThreadEpiphanyStateUpdatedField::Invariants, + EpiphanyStateUpdatedField::Graphs => ThreadEpiphanyStateUpdatedField::Graphs, + EpiphanyStateUpdatedField::GraphFrontier => ThreadEpiphanyStateUpdatedField::GraphFrontier, + EpiphanyStateUpdatedField::GraphCheckpoint => { + ThreadEpiphanyStateUpdatedField::GraphCheckpoint + } + EpiphanyStateUpdatedField::Scratch => ThreadEpiphanyStateUpdatedField::Scratch, + EpiphanyStateUpdatedField::InvestigationCheckpoint => { + ThreadEpiphanyStateUpdatedField::InvestigationCheckpoint + } + EpiphanyStateUpdatedField::JobBindings => ThreadEpiphanyStateUpdatedField::JobBindings, + EpiphanyStateUpdatedField::AcceptanceReceipts => { + ThreadEpiphanyStateUpdatedField::AcceptanceReceipts + } + EpiphanyStateUpdatedField::RuntimeLinks => ThreadEpiphanyStateUpdatedField::RuntimeLinks, + EpiphanyStateUpdatedField::Observations => ThreadEpiphanyStateUpdatedField::Observations, + EpiphanyStateUpdatedField::Evidence => ThreadEpiphanyStateUpdatedField::Evidence, + EpiphanyStateUpdatedField::Churn => ThreadEpiphanyStateUpdatedField::Churn, + EpiphanyStateUpdatedField::Mode => ThreadEpiphanyStateUpdatedField::Mode, + EpiphanyStateUpdatedField::Planning => ThreadEpiphanyStateUpdatedField::Planning, + } +} + pub fn imagination_role_accept_patch_errors(patch: &ThreadEpiphanyUpdatePatch) -> Vec { imagination_role_state_patch_policy_errors(&core_state_patch_from_protocol(patch)) } @@ -270,15 +312,15 @@ pub fn build_reorient_acceptance_update( let investigation_checkpoint = acceptance_bundle.investigation_checkpoint; let mut changed_fields = vec![ - ThreadEpiphanyStateUpdatedField::AcceptanceReceipts, - ThreadEpiphanyStateUpdatedField::Observations, - ThreadEpiphanyStateUpdatedField::Evidence, + EpiphanyStateUpdatedField::AcceptanceReceipts, + EpiphanyStateUpdatedField::Observations, + EpiphanyStateUpdatedField::Evidence, ]; if scratch.is_some() { - changed_fields.push(ThreadEpiphanyStateUpdatedField::Scratch); + changed_fields.push(EpiphanyStateUpdatedField::Scratch); } if investigation_checkpoint.is_some() { - changed_fields.push(ThreadEpiphanyStateUpdatedField::InvestigationCheckpoint); + changed_fields.push(EpiphanyStateUpdatedField::InvestigationCheckpoint); } Ok(ReorientAcceptanceUpdate { @@ -298,10 +340,10 @@ pub fn build_reorient_acceptance_update( }) } -pub fn epiphany_job_launch_changed_fields() -> Vec { +pub fn epiphany_job_launch_changed_fields() -> Vec { vec![ - ThreadEpiphanyStateUpdatedField::JobBindings, - ThreadEpiphanyStateUpdatedField::RuntimeLinks, + EpiphanyStateUpdatedField::JobBindings, + EpiphanyStateUpdatedField::RuntimeLinks, ] } @@ -327,68 +369,68 @@ pub fn thread_epiphany_patch_has_state_replacements( pub fn epiphany_update_patch_changed_fields( patch: &ThreadEpiphanyUpdatePatch, -) -> Vec { +) -> Vec { let mut fields = Vec::new(); if patch.objective.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Objective); + fields.push(EpiphanyStateUpdatedField::Objective); } if patch.active_subgoal_id.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::ActiveSubgoalId); + fields.push(EpiphanyStateUpdatedField::ActiveSubgoalId); } if patch.subgoals.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Subgoals); + fields.push(EpiphanyStateUpdatedField::Subgoals); } if patch.invariants.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Invariants); + fields.push(EpiphanyStateUpdatedField::Invariants); } if patch.graphs.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Graphs); + fields.push(EpiphanyStateUpdatedField::Graphs); } if patch.graph_frontier.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::GraphFrontier); + fields.push(EpiphanyStateUpdatedField::GraphFrontier); } if patch.graph_checkpoint.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::GraphCheckpoint); + fields.push(EpiphanyStateUpdatedField::GraphCheckpoint); } if patch.scratch.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Scratch); + fields.push(EpiphanyStateUpdatedField::Scratch); } if patch.investigation_checkpoint.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::InvestigationCheckpoint); + fields.push(EpiphanyStateUpdatedField::InvestigationCheckpoint); } if patch.job_bindings.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::JobBindings); + fields.push(EpiphanyStateUpdatedField::JobBindings); } if !patch.acceptance_receipts.is_empty() { - fields.push(ThreadEpiphanyStateUpdatedField::AcceptanceReceipts); + fields.push(EpiphanyStateUpdatedField::AcceptanceReceipts); } if !patch.runtime_links.is_empty() { - fields.push(ThreadEpiphanyStateUpdatedField::RuntimeLinks); + fields.push(EpiphanyStateUpdatedField::RuntimeLinks); } if !patch.observations.is_empty() { - fields.push(ThreadEpiphanyStateUpdatedField::Observations); + fields.push(EpiphanyStateUpdatedField::Observations); } if !patch.evidence.is_empty() { - fields.push(ThreadEpiphanyStateUpdatedField::Evidence); + fields.push(EpiphanyStateUpdatedField::Evidence); } if patch.churn.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Churn); + fields.push(EpiphanyStateUpdatedField::Churn); } if patch.mode.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Mode); + fields.push(EpiphanyStateUpdatedField::Mode); } if patch.planning.is_some() { - fields.push(ThreadEpiphanyStateUpdatedField::Planning); + fields.push(EpiphanyStateUpdatedField::Planning); } fields } pub fn epiphany_promote_changed_fields( patch: &EpiphanyRoleStatePatchDocument, -) -> Vec { +) -> Vec { let mut fields = epiphany_update_patch_changed_fields(&protocol_patch_from_core(patch.clone())); - if !fields.contains(&ThreadEpiphanyStateUpdatedField::Evidence) { - fields.push(ThreadEpiphanyStateUpdatedField::Evidence); + if !fields.contains(&EpiphanyStateUpdatedField::Evidence) { + fields.push(EpiphanyStateUpdatedField::Evidence); } fields } diff --git a/epiphany-codex-bridge/src/mutation_service.rs b/epiphany-codex-bridge/src/mutation_service.rs index 1b004b9d..bf64e3f7 100644 --- a/epiphany-codex-bridge/src/mutation_service.rs +++ b/epiphany-codex-bridge/src/mutation_service.rs @@ -5,7 +5,6 @@ use std::path::PathBuf; use codex_app_server_protocol::ThreadEpiphanyReorientSource; use codex_app_server_protocol::ThreadEpiphanyRoleId; -use codex_app_server_protocol::ThreadEpiphanyStateUpdatedField; use epiphany_core::EpiphanyJobInterruptRequest; use epiphany_core::EpiphanyJobInterruptResult; use epiphany_core::EpiphanyJobLaunchRequest; @@ -18,6 +17,7 @@ use epiphany_core::EpiphanyReorientStateStatus; use epiphany_core::EpiphanyRoleFindingInterpretation; use epiphany_core::EpiphanyRoleStatePatchDocument; use epiphany_core::EpiphanyStateUpdate; +use epiphany_core::EpiphanyStateUpdatedField; use epiphany_core::EpiphanyTokenUsageSnapshot; use epiphany_core::RuntimeSpineHeartbeatJobOptions; use epiphany_core::RuntimeSpineHeartbeatLaunchPlanOptions; @@ -75,7 +75,7 @@ pub trait EpiphanyMutationHost { #[derive(Debug, Clone)] pub struct EpiphanyThreadUpdateApplied { pub revision: u64, - pub changed_fields: Vec, + pub changed_fields: Vec, pub epiphany_state: EpiphanyThreadState, } @@ -88,7 +88,7 @@ pub enum EpiphanyThreadPromoteApplied { #[derive(Debug, Clone)] pub struct EpiphanyRoleAcceptApplied { pub revision: u64, - pub changed_fields: Vec, + pub changed_fields: Vec, pub epiphany_state: EpiphanyThreadState, pub accepted_receipt_id: String, pub accepted_observation_id: String, @@ -100,7 +100,7 @@ pub struct EpiphanyRoleAcceptApplied { #[derive(Debug, Clone)] pub struct EpiphanyReorientAcceptApplied { pub revision: u64, - pub changed_fields: Vec, + pub changed_fields: Vec, pub epiphany_state: EpiphanyThreadState, pub accepted_receipt_id: String, pub accepted_observation_id: String, @@ -113,7 +113,7 @@ pub struct EpiphanyJobLaunchApplied { pub launcher_job_id: String, pub backend_job_id: String, pub revision: u64, - pub changed_fields: Vec, + pub changed_fields: Vec, pub epiphany_state: EpiphanyThreadState, pub job: EpiphanyJobView, } @@ -123,7 +123,7 @@ pub struct EpiphanyJobInterruptApplied { pub cancel_requested: bool, pub interrupted_thread_ids: Vec, pub revision: u64, - pub changed_fields: Vec, + pub changed_fields: Vec, pub epiphany_state: EpiphanyThreadState, pub job: EpiphanyJobView, } @@ -137,7 +137,7 @@ pub struct EpiphanyReorientLaunchApplied { pub state_revision: Option, pub decision: EpiphanyReorientDecision, pub revision: u64, - pub changed_fields: Vec, + pub changed_fields: Vec, pub epiphany_state: EpiphanyThreadState, pub job: EpiphanyJobView, } @@ -544,7 +544,7 @@ pub async fn interrupt_thread_epiphany_job( binding_id: &str, reason: Option, ) -> BridgeResult { - let changed_fields = vec![ThreadEpiphanyStateUpdatedField::JobBindings]; + let changed_fields = vec![EpiphanyStateUpdatedField::JobBindings]; let interrupted = interrupt_epiphany_job_on_thread( thread, EpiphanyJobInterruptRequest { diff --git a/epiphany-core/src/lib.rs b/epiphany-core/src/lib.rs index 1fd09166..643a9969 100644 --- a/epiphany-core/src/lib.rs +++ b/epiphany-core/src/lib.rs @@ -216,6 +216,7 @@ pub use state_ledger::close_state_branch; pub use state_ledger::load_state_ledger; pub use state_ledger::state_ledger_status; pub use state_update::EpiphanyStateUpdate; +pub use state_update::EpiphanyStateUpdatedField; pub use state_update::apply_epiphany_state_update; pub use state_update::epiphany_state_update_validation_errors; pub use surfaces::EpiphanyAcceptanceBundle; diff --git a/epiphany-core/src/state_update.rs b/epiphany-core/src/state_update.rs index 358f8da0..8ebe6929 100644 --- a/epiphany-core/src/state_update.rs +++ b/epiphany-core/src/state_update.rs @@ -19,6 +19,27 @@ use epiphany_state_model::EpiphanySubgoal; use epiphany_state_model::EpiphanyThreadState; use std::collections::HashSet; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum EpiphanyStateUpdatedField { + Objective, + ActiveSubgoalId, + Subgoals, + Invariants, + Graphs, + GraphFrontier, + GraphCheckpoint, + Scratch, + InvestigationCheckpoint, + JobBindings, + AcceptanceReceipts, + RuntimeLinks, + Observations, + Evidence, + Churn, + Mode, + Planning, +} + #[derive(Debug, Clone, Default)] pub struct EpiphanyStateUpdate { pub expected_revision: Option, diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index d5b64d6a..004dc130 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -61,6 +61,7 @@ remembers doctrine; the branch remembers the blade. - Context and graph-query derivation now receive core `EpiphanyContextParams` / `EpiphanyGraphQuery` documents. The bridge converts `ThreadEpiphanyContextParams` / `ThreadEpiphanyGraphQuery` before invoking core policy, so Codex JSON-RPC request DTOs no longer define the internal graph question. - Role/reorient acceptance service results now carry core typed findings, and role acceptance carries a typed `EpiphanyRoleStatePatchDocument` for the applied patch. App-server mutation routes project those into `ThreadEpiphany*Finding` / `ThreadEpiphanyUpdatePatch` only for legacy accept responses. - Generic update/promote service entry points now accept typed `EpiphanyRoleStatePatchDocument` patches. Vendored app-server converts `ThreadEpiphanyUpdatePatch` request cargo before invoking the bridge, so the mutation service no longer treats the JSON-RPC patch as its native write document. +- Changed-field authority is native now. `EpiphanyStateUpdatedField` lives in `epiphany-core`; bridge mutation results carry that typed enum, while app-server projects it into `ThreadEpiphanyStateUpdatedField` only for JSON-RPC responses and notifications. - 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 059418d62d014aa21d81ca10b71848994af3dbb1..cff557cd635a248481d03fcfa566f02c1756b8cb 100644 GIT binary patch delta 268 zcmZ3ond8V-jtR<4Qe7KW3mF-Eo2N6jPiJJ@KAn;2hq%y`okj*mX1WHZx<&>e28LF~ zW|IS_O3U5+=$w(5m!6uUo0gfHlcJDVT9T1plvz@#kX%|~HT{AyqewuC8(1nYzg!_F zvn;h(Au~@QwIH(qsIgKvIlm}XM#sHqqGmilKi}!N`qC7EfN$zY3$^|qjU%gV$o3IGI%U8ev5 delta 52 zcmX@Im1D_fjtR<4l35#73mF-Enx`|iPiJJ@KAn;2hq&k#BLgEdT?12HBZCkFLn|W- ID`WF00MBm^lmGw# diff --git a/state/map.yaml b/state/map.yaml index 1c3387f9..32256af4 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -338,7 +338,11 @@ current_status: finding interpretations and typed role-state patches; app-server projects them into legacy accept-response DTOs. Generic update/promote service entry points now take typed `EpiphanyRoleStatePatchDocument` documents; app-server - converts `ThreadEpiphanyUpdatePatch` request cargo at the JSON-RPC edge. The - bridge still depends on vendored Codex for app-server protocol DTOs and - absolute path validation, so the purification is not done. + converts `ThreadEpiphanyUpdatePatch` request cargo at the JSON-RPC edge. + Changed-field authority is now native `EpiphanyStateUpdatedField` in + `epiphany-core`; app-server projects it into + `ThreadEpiphanyStateUpdatedField` only for legacy responses and + notifications. 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 `ThreadEpiphany*` authority. Prioritize role-result/reorient-result DTO coupling next: derive typed CultNet surfaces first, push JSON-RPC projection into app-server, and keep MCP/OpenAI JSON only at their true protocol/text edges. Do not add compatibility adapters unless they protect a named ownership invariant. diff --git a/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_automation.rs b/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_automation.rs index 43a8fab8..03608ad1 100644 --- a/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_automation.rs +++ b/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_automation.rs @@ -15,6 +15,7 @@ use epiphany_codex_bridge::coordinator::select_epiphany_coordinator_automation; use epiphany_codex_bridge::invalidation::EpiphanyInvalidationManager; use epiphany_codex_bridge::invalidation::epiphany_freshness_watcher_snapshot; use epiphany_codex_bridge::mutation::epiphany_job_launch_changed_fields; +use epiphany_codex_bridge::mutation::map_protocol_state_updated_fields; use epiphany_codex_bridge::mutation_service::launch_epiphany_job_on_thread; use epiphany_codex_bridge::pressure::derive_epiphany_pressure; use epiphany_codex_bridge::pressure::render_epiphany_pre_compaction_checkpoint_intervention; @@ -98,7 +99,9 @@ pub(crate) async fn maybe_run_epiphany_coordinator_automation_for_turn_boundary( thread_id: thread_id_text, source: ThreadEpiphanyStateUpdatedSource::JobLaunch, revision: epiphany_state.revision, - changed_fields: epiphany_job_launch_changed_fields(), + changed_fields: map_protocol_state_updated_fields( + epiphany_job_launch_changed_fields(), + ), epiphany_state, }, )) diff --git a/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_mutation_routes.rs b/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_mutation_routes.rs index f8764f76..ddc6b0db 100644 --- a/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_mutation_routes.rs +++ b/vendor/codex/codex-rs/app-server/src/codex_message_processor/epiphany_mutation_routes.rs @@ -13,6 +13,7 @@ use epiphany_codex_bridge::cultnet::EpiphanyReorientFreshnessStatus; use epiphany_codex_bridge::cultnet::EpiphanyReorientPressureLevel; use epiphany_codex_bridge::cultnet::EpiphanyReorientReason; use epiphany_codex_bridge::cultnet::EpiphanyReorientStateStatus; +use epiphany_codex_bridge::cultnet::EpiphanyStateUpdatedField; use epiphany_codex_bridge::error::EpiphanyBridgeError; use epiphany_codex_bridge::invalidation::epiphany_freshness_watcher_snapshot; use epiphany_codex_bridge::launch::EPIPHANY_REORIENT_LAUNCH_BINDING_ID; @@ -20,6 +21,7 @@ use epiphany_codex_bridge::launch::build_epiphany_job_launch_request; use epiphany_codex_bridge::launch::epiphany_role_binding_id; use epiphany_codex_bridge::mutation::core_state_patch_from_protocol; use epiphany_codex_bridge::mutation::epiphany_state_updated_notification; +use epiphany_codex_bridge::mutation::map_protocol_state_updated_fields; use epiphany_codex_bridge::mutation::protocol_patch_from_core; use epiphany_codex_bridge::mutation_service::EpiphanyThreadPromoteApplied; use epiphany_codex_bridge::mutation_service::apply_thread_epiphany_promote; @@ -79,7 +81,7 @@ impl CodexMessageProcessor { &self, thread_uuid: ThreadId, source: ThreadEpiphanyStateUpdatedSource, - changed_fields: Vec, + changed_fields: Vec, epiphany_state: EpiphanyThreadState, ) { self.outgoing @@ -137,6 +139,7 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; self.outgoing @@ -146,7 +149,7 @@ impl CodexMessageProcessor { thread_id: thread_uuid.to_string(), role_id, revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), job: thread_epiphany_job_from_surface( applied.job, @@ -211,6 +214,7 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; self.outgoing @@ -218,7 +222,7 @@ impl CodexMessageProcessor { request_id, ThreadEpiphanyRoleAcceptResponse { revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), role_id, binding_id: binding_id.clone(), @@ -308,6 +312,7 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; self.outgoing @@ -320,7 +325,7 @@ impl CodexMessageProcessor { state_revision: applied.state_revision, decision: thread_epiphany_reorient_decision(applied.decision), revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), job: thread_epiphany_job_from_surface( applied.job, @@ -383,6 +388,7 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; self.outgoing @@ -390,7 +396,7 @@ impl CodexMessageProcessor { request_id, ThreadEpiphanyReorientAcceptResponse { revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), binding_id: binding_id.clone(), accepted_receipt_id: applied.accepted_receipt_id, @@ -508,12 +514,13 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; let response = ThreadEpiphanyPromoteResponse { accepted: true, reasons: Vec::new(), revision: Some(applied.revision), - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: Some(epiphany_state.clone()), }; @@ -562,10 +569,11 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; let response = ThreadEpiphanyUpdateResponse { revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), }; @@ -642,6 +650,7 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; self.outgoing @@ -649,7 +658,7 @@ impl CodexMessageProcessor { request_id, ThreadEpiphanyJobLaunchResponse { revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), job: thread_epiphany_job_from_surface( applied.job, @@ -709,6 +718,7 @@ impl CodexMessageProcessor { } }; let changed_fields = applied.changed_fields; + let protocol_changed_fields = map_protocol_state_updated_fields(changed_fields.clone()); let epiphany_state = applied.epiphany_state; self.outgoing @@ -718,7 +728,7 @@ impl CodexMessageProcessor { cancel_requested: applied.cancel_requested, interrupted_thread_ids: applied.interrupted_thread_ids.clone(), revision: applied.revision, - changed_fields: changed_fields.clone(), + changed_fields: protocol_changed_fields, epiphany_state: epiphany_state.clone(), job: thread_epiphany_job_from_surface(applied.job, None, None), },