diff --git a/epiphany-core/src/surfaces/role_result.rs b/epiphany-core/src/surfaces/role_result.rs index 7163fde1..4ccb2a3b 100644 --- a/epiphany-core/src/surfaces/role_result.rs +++ b/epiphany-core/src/surfaces/role_result.rs @@ -1,4 +1,7 @@ -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub enum EpiphanyRoleResultRoleId { Implementation, Imagination, @@ -7,14 +10,16 @@ pub enum EpiphanyRoleResultRoleId { Reorientation, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub enum EpiphanyRoleSelfPersistenceStatus { Missing, Accepted, Rejected, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyRoleSelfPersistenceReview { pub status: EpiphanyRoleSelfPersistenceStatus, pub target_agent_id: Option, @@ -22,7 +27,8 @@ pub struct EpiphanyRoleSelfPersistenceReview { pub reasons: Vec, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyRoleFindingInterpretation { pub verdict: Option, pub summary: Option, @@ -45,7 +51,8 @@ pub struct EpiphanyRoleFindingInterpretation { pub item_error: Option, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyRoleAcceptanceFinding { pub role_id: EpiphanyRoleResultRoleId, pub verdict: Option, @@ -57,7 +64,8 @@ pub struct EpiphanyRoleAcceptanceFinding { pub projected_fields: Vec, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyReorientAcceptanceFinding { pub mode: Option, pub summary: Option, @@ -68,7 +76,8 @@ pub struct EpiphanyReorientAcceptanceFinding { pub runtime_job_id: Option, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyReorientFindingInterpretation { pub mode: Option, pub summary: Option, @@ -84,7 +93,8 @@ pub struct EpiphanyReorientFindingInterpretation { pub item_error: Option, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyAcceptanceBundle { pub accepted_receipt_id: String, pub accepted_observation_id: String, @@ -94,7 +104,8 @@ pub struct EpiphanyAcceptanceBundle { pub receipt: EpiphanyAcceptanceReceipt, } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct EpiphanyReorientAcceptanceBundle { pub accepted_receipt_id: String, pub accepted_observation_id: String, diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 85da1c25..600146bd 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -49,6 +49,7 @@ remembers doctrine; the branch remembers the blade. - `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/reorient decision/status is less contaminated now: `epiphany-codex-bridge` stores reorient decisions, coordinator decisions, source signals, CRRC recommendations, and role-board lanes as core-shaped types, core CRRC/coordinator/role-board surfaces serialize natively, and `ThreadEpiphany*` projection happens at the legacy view emission boundary. Keep cutting remaining result inputs until Aquarium/CultNet can read coordinator surfaces without JSON-RPC DTO authority. +- Core role/reorient finding interpretations and acceptance bundles now serialize natively too. Use those typed result surfaces as the next authority target; do not let `ThreadEpiphanyRoleFinding` or `ThreadEpiphanyReorientFinding` remain the bridge's internal result truth just because legacy view/accept responses still expose them. - 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 27775faa..a55acec1 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 8bb1b65a..b3fed513 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -312,9 +312,10 @@ current_status: launch mutation results return typed decision/state-status values from the bridge, and core reorient decisions are serializable CultNet-ready state. Reorient decisions, coordinator decisions, coordinator source signals, CRRC - recommendations, and role-board lanes now remain core-shaped inside the - bridge; app-server still projects those typed surfaces into - `ThreadEpiphany*` responses at the legacy JSON-RPC edge. The bridge still + recommendations, role-board lanes, and core role/reorient result + interpretations now remain serializable typed surfaces; app-server still + projects those typed surfaces into `ThreadEpiphany*` responses at the legacy + 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. 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.