Delete protocol result helper residue

This commit is contained in:
Meta Vens 2026-05-20 01:47:04 +01:00
commit 8f2d7deefd
6 changed files with 3 additions and 289 deletions

View file

@ -1,7 +1,3 @@
use std::path::PathBuf;
use codex_app_server_protocol::ThreadEpiphanyReorientFinding;
use codex_app_server_protocol::ThreadEpiphanyRoleFinding;
use codex_app_server_protocol::ThreadEpiphanyRoleId;
use codex_app_server_protocol::ThreadEpiphanyStateUpdatedField;
use codex_app_server_protocol::ThreadEpiphanyStateUpdatedNotification;
@ -17,10 +13,7 @@ use epiphany_core::build_reorient_acceptance_bundle;
use epiphany_core::build_role_acceptance_bundle;
use epiphany_core::imagination_role_state_patch_policy_errors;
use epiphany_core::modeling_role_state_patch_policy_errors;
use epiphany_state_model::EpiphanyCodeRef;
use epiphany_state_model::EpiphanyInvestigationCheckpoint;
use epiphany_state_model::EpiphanyInvestigationDisposition;
use epiphany_state_model::EpiphanyScratchPad;
use crate::results::map_core_role_result_role_id;
@ -40,15 +33,6 @@ pub struct ReorientAcceptanceUpdate {
pub accepted_evidence_id: String,
}
pub fn parse_role_finding_state_patch(
finding: &ThreadEpiphanyRoleFinding,
) -> Result<ThreadEpiphanyUpdatePatch, String> {
finding
.state_patch
.clone()
.ok_or_else(|| "completed role finding did not include a reviewable statePatch".to_string())
}
pub fn parse_core_role_finding_state_patch(
finding: &CoreEpiphanyRoleFinding,
) -> Result<EpiphanyRoleStatePatchDocument, String> {
@ -156,26 +140,6 @@ pub fn modeling_role_accept_patch_errors(patch: &ThreadEpiphanyUpdatePatch) -> V
modeling_role_state_patch_policy_errors(&core_state_patch_from_protocol(patch))
}
pub fn epiphany_modeling_finding_has_reviewable_state_patch(
finding: &ThreadEpiphanyRoleFinding,
) -> bool {
finding.role_id == ThreadEpiphanyRoleId::Modeling
&& finding
.state_patch
.as_ref()
.is_some_and(|patch| modeling_role_accept_patch_errors(patch).is_empty())
}
pub fn epiphany_imagination_finding_has_reviewable_state_patch(
finding: &ThreadEpiphanyRoleFinding,
) -> bool {
finding.role_id == ThreadEpiphanyRoleId::Imagination
&& finding
.state_patch
.as_ref()
.is_some_and(|patch| imagination_role_accept_patch_errors(patch).is_empty())
}
pub fn build_role_acceptance_update(
role_id: ThreadEpiphanyRoleId,
binding_id: &str,
@ -322,89 +286,6 @@ pub fn build_reorient_acceptance_update(
})
}
pub fn role_finding_summary(finding: &ThreadEpiphanyRoleFinding) -> String {
let summary = finding
.summary
.clone()
.unwrap_or_else(|| "Role worker returned a structured finding.".to_string());
if let Some(next_safe_move) = finding.next_safe_move.as_deref() {
format!("{summary} Next safe move: {next_safe_move}")
} else {
summary
}
}
pub fn reorient_finding_code_refs(finding: &ThreadEpiphanyReorientFinding) -> Vec<EpiphanyCodeRef> {
finding
.files_inspected
.iter()
.filter(|path| !path.trim().is_empty())
.map(|path| EpiphanyCodeRef {
path: PathBuf::from(path),
start_line: None,
end_line: None,
symbol: None,
note: Some("Inspected by accepted reorientation worker.".to_string()),
})
.collect()
}
pub fn reorient_finding_scratch(
binding_id: &str,
finding: &ThreadEpiphanyReorientFinding,
) -> EpiphanyScratchPad {
let mode = finding.mode.as_deref().unwrap_or("unknown");
let checkpoint_validity = match finding.checkpoint_still_valid {
Some(true) => "valid",
Some(false) => "invalid",
None => "unknown",
};
EpiphanyScratchPad {
summary: finding.summary.clone(),
hypothesis: Some(format!(
"Accepted {mode} reorientation finding from {binding_id}; checkpoint validity is {checkpoint_validity}."
)),
next_probe: finding.next_safe_move.clone(),
notes: vec![format!(
"Files inspected: {}",
if finding.files_inspected.is_empty() {
"none reported".to_string()
} else {
finding.files_inspected.join(", ")
}
)],
}
}
pub fn reorient_finding_investigation_checkpoint(
checkpoint: &EpiphanyInvestigationCheckpoint,
evidence_id: &str,
code_refs: &[EpiphanyCodeRef],
finding: &ThreadEpiphanyReorientFinding,
) -> EpiphanyInvestigationCheckpoint {
let mut checkpoint = checkpoint.clone();
checkpoint.summary = finding.summary.clone().or(checkpoint.summary);
checkpoint.next_action = finding.next_safe_move.clone().or(checkpoint.next_action);
checkpoint.disposition = EpiphanyInvestigationDisposition::ResumeReady;
if !checkpoint
.evidence_ids
.iter()
.any(|existing| existing == evidence_id)
{
checkpoint.evidence_ids.push(evidence_id.to_string());
}
for code_ref in code_refs {
if !checkpoint
.code_refs
.iter()
.any(|existing| existing.path == code_ref.path)
{
checkpoint.code_refs.push(code_ref.clone());
}
}
checkpoint
}
pub fn epiphany_job_launch_changed_fields() -> Vec<ThreadEpiphanyStateUpdatedField> {
vec![
ThreadEpiphanyStateUpdatedField::JobBindings,

View file

@ -1,8 +1,6 @@
use codex_app_server_protocol::ThreadEpiphanyReorientFinding;
use codex_app_server_protocol::ThreadEpiphanyReorientResultStatus;
use codex_app_server_protocol::ThreadEpiphanyRoleFinding;
use codex_app_server_protocol::ThreadEpiphanyRoleId;
use codex_app_server_protocol::ThreadEpiphanyRoleResultStatus;
use codex_app_server_protocol::ThreadEpiphanyRoleSelfPersistenceReview;
use codex_app_server_protocol::ThreadEpiphanyRoleSelfPersistenceStatus;
use codex_app_server_protocol::ThreadEpiphanyUpdatePatch;
@ -121,71 +119,6 @@ fn map_protocol_role_self_persistence_review(
}
}
pub fn render_epiphany_role_result_note(
role_id: ThreadEpiphanyRoleId,
status: ThreadEpiphanyRoleResultStatus,
finding: Option<&ThreadEpiphanyRoleFinding>,
item_error: Option<&str>,
) -> String {
match status {
ThreadEpiphanyRoleResultStatus::Completed => {
if let Some(finding) = finding {
let next = finding.next_safe_move.as_deref().unwrap_or("not supplied");
let self_note =
render_epiphany_self_persistence_note(finding.self_persistence.as_ref())
.map(|note| format!(" {note}"))
.unwrap_or_default();
if let Some(item_error) = finding.item_error.as_deref().or(item_error) {
format!(
"{:?} role specialist completed, but the finding needs repair: {item_error}. Next safe move: {next}.{self_note}",
role_id
)
} else {
format!(
"{:?} role specialist completed. Next safe move: {next}.{self_note}",
role_id
)
}
} else {
format!(
"{:?} role specialist completed, but no structured result was recorded.",
role_id
)
}
}
ThreadEpiphanyRoleResultStatus::Failed => item_error
.map(|error| format!("{:?} role specialist failed: {error}", role_id))
.unwrap_or_else(|| format!("{:?} role specialist failed.", role_id)),
ThreadEpiphanyRoleResultStatus::Cancelled => {
format!(
"{:?} role specialist was cancelled before producing a result.",
role_id
)
}
ThreadEpiphanyRoleResultStatus::Running => {
format!("{:?} role specialist is still running.", role_id)
}
ThreadEpiphanyRoleResultStatus::Pending => {
format!(
"{:?} role specialist has not produced a result yet.",
role_id
)
}
ThreadEpiphanyRoleResultStatus::MissingState => {
"No authoritative Epiphany state exists for this thread.".to_string()
}
ThreadEpiphanyRoleResultStatus::MissingBinding => {
"No matching Epiphany role specialist binding exists.".to_string()
}
ThreadEpiphanyRoleResultStatus::BackendUnavailable => {
"The bound runtime backend is unavailable.".to_string()
}
ThreadEpiphanyRoleResultStatus::BackendMissing => {
"The bound runtime backend job or item is missing.".to_string()
}
}
}
pub fn render_core_role_result_note(
role_id: EpiphanyRoleResultRoleId,
status: CoreEpiphanyCoordinatorRoleResultStatus,
@ -275,71 +208,6 @@ fn render_core_self_persistence_note(
}
}
fn render_epiphany_self_persistence_note(
review: Option<&ThreadEpiphanyRoleSelfPersistenceReview>,
) -> Option<String> {
let review = review?;
match review.status {
ThreadEpiphanyRoleSelfPersistenceStatus::Missing => None,
ThreadEpiphanyRoleSelfPersistenceStatus::Accepted => Some(format!(
"Self persistence request is acceptable for {}.",
review
.target_agent_id
.as_deref()
.unwrap_or("the role memory file")
)),
ThreadEpiphanyRoleSelfPersistenceStatus::Rejected => {
let reasons = if review.reasons.is_empty() {
"no reason recorded".to_string()
} else {
review.reasons.join("; ")
};
Some(format!("Self persistence request was refused: {reasons}."))
}
}
}
pub fn render_epiphany_reorient_result_note(
status: ThreadEpiphanyReorientResultStatus,
finding: Option<&ThreadEpiphanyReorientFinding>,
item_error: Option<&str>,
) -> String {
match status {
ThreadEpiphanyReorientResultStatus::Completed => {
if let Some(finding) = finding {
let next = finding.next_safe_move.as_deref().unwrap_or("not supplied");
format!("Reorientation worker completed. Next safe move: {next}")
} else {
"Reorientation worker completed, but no structured result was recorded.".to_string()
}
}
ThreadEpiphanyReorientResultStatus::Failed => item_error
.map(|error| format!("Reorientation worker failed: {error}"))
.unwrap_or_else(|| "Reorientation worker failed.".to_string()),
ThreadEpiphanyReorientResultStatus::Cancelled => {
"Reorientation worker was cancelled before producing a result.".to_string()
}
ThreadEpiphanyReorientResultStatus::Running => {
"Reorientation worker is still running.".to_string()
}
ThreadEpiphanyReorientResultStatus::Pending => {
"Reorientation worker has not produced a result yet.".to_string()
}
ThreadEpiphanyReorientResultStatus::MissingState => {
"No authoritative Epiphany state exists for this thread.".to_string()
}
ThreadEpiphanyReorientResultStatus::MissingBinding => {
"No matching Epiphany reorientation worker binding exists.".to_string()
}
ThreadEpiphanyReorientResultStatus::BackendUnavailable => {
"The bound runtime backend is unavailable.".to_string()
}
ThreadEpiphanyReorientResultStatus::BackendMissing => {
"The bound runtime backend job or item is missing.".to_string()
}
}
}
pub fn render_core_reorient_result_note(
status: CoreEpiphanyCrrcResultStatus,
finding: Option<&EpiphanyReorientFindingInterpretation>,

View file

@ -27,24 +27,6 @@ use crate::results::map_protocol_role_finding;
use crate::results::render_core_reorient_result_note;
use crate::results::render_core_role_result_note;
pub fn role_finding_runtime_result_id(finding: &ThreadEpiphanyRoleFinding) -> Option<String> {
finding.runtime_result_id.clone()
}
pub fn role_finding_runtime_job_id(finding: &ThreadEpiphanyRoleFinding) -> Option<String> {
finding.runtime_job_id.clone()
}
pub fn reorient_finding_runtime_result_id(
finding: &ThreadEpiphanyReorientFinding,
) -> Option<String> {
finding.runtime_result_id.clone()
}
pub fn reorient_finding_runtime_job_id(finding: &ThreadEpiphanyReorientFinding) -> Option<String> {
finding.runtime_job_id.clone()
}
#[derive(Debug, Clone)]
pub struct EpiphanyRoleResultSnapshot {
pub status: CoreEpiphanyCoordinatorRoleResultStatus,
@ -386,16 +368,6 @@ pub async fn load_core_epiphany_role_result_snapshot(
}
}
pub fn load_completed_epiphany_role_finding(
runtime_store_path: Option<&Path>,
state: &EpiphanyThreadState,
role_id: ThreadEpiphanyRoleId,
binding_id: &str,
) -> BridgeResult<ThreadEpiphanyRoleFinding> {
load_completed_core_epiphany_role_finding(runtime_store_path, state, role_id, binding_id)
.map(|finding| map_protocol_role_finding(role_id, finding))
}
pub fn load_completed_core_epiphany_role_finding(
runtime_store_path: Option<&Path>,
state: &EpiphanyThreadState,
@ -494,15 +466,6 @@ pub async fn load_core_epiphany_reorient_result_snapshot(
}
}
pub fn load_completed_epiphany_reorient_finding(
runtime_store_path: Option<&Path>,
state: &EpiphanyThreadState,
binding_id: &str,
) -> BridgeResult<ThreadEpiphanyReorientFinding> {
load_completed_core_epiphany_reorient_finding(runtime_store_path, state, binding_id)
.map(map_protocol_reorient_finding)
}
pub fn load_completed_core_epiphany_reorient_finding(
runtime_store_path: Option<&Path>,
state: &EpiphanyThreadState,

View file

@ -53,6 +53,7 @@ remembers doctrine; the branch remembers the blade.
- Runtime-result loading now has core typed snapshot APIs for role and reorient worker results, with legacy protocol tuple wrappers layered over them. This intentionally creates temporary duplicate note rendering; the next cut should move coordinator and acceptance consumers to typed snapshots, then delete protocol-shaped result rendering instead of preserving both.
- Coordinator result gating now consumes typed runtime result snapshots and core finding interpretations directly. `ThreadEpiphanyRoleFinding` / `ThreadEpiphanyReorientFinding` remain in legacy runtime wrapper/view/mutation response paths; the next cut is acceptance/mutation so protocol findings stop being the accepted-result authority.
- Acceptance/mutation now builds role/reorient receipts, evidence, observations, scratch, and checkpoint updates from core typed finding interpretations. Protocol findings remain as legacy response payloads and helper residue; delete those wrappers once view/result responses are also typed internally.
- The old protocol-shaped result helper layer is deleted: no protocol finding runtime-id helpers, no protocol result-note renderers, and no dead protocol reorient scratch/checkpoint builders remain in the bridge. Legacy view/result/accept responses may still carry `ThreadEpiphany*Finding`, but they are projections, not bridge policy input.
- 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

@ -322,7 +322,8 @@ current_status:
result rendering once acceptance and view response edges finish moving off
protocol finding authority. Role/reorient acceptance now builds receipts
and evidence from core typed findings, mapping to protocol findings only for
legacy accept response cargo. The bridge still
legacy accept response cargo. The duplicate protocol-shaped result helper
layer has been deleted. 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.