2026-05-28 21:02:26 +01:00
use std ::sync ::OnceLock ;
use crate ::EpiphanyCoordinatorAction as CoreEpiphanyCoordinatorAction ;
use crate ::EpiphanyCoordinatorRoleResultStatus as CoreEpiphanyCoordinatorRoleResultStatus ;
use crate ::EpiphanyCrrcAction as CoreEpiphanyCrrcAction ;
use crate ::EpiphanyCrrcResultStatus as CoreEpiphanyCrrcResultStatus ;
use crate ::EpiphanyJobLaunchRequest ;
use crate ::EpiphanyPressure ;
use crate ::EpiphanyPressureLevel as CoreEpiphanyPressureLevel ;
use crate ::EpiphanyReorientAction as CoreEpiphanyReorientAction ;
use crate ::EpiphanyReorientDecision as CoreEpiphanyReorientDecision ;
use crate ::EpiphanyReorientLaunchRequestInput ;
use crate ::EpiphanyRoleResultRoleId ;
use crate ::EpiphanyRoleWorkerLaunchDocument ;
use crate ::EpiphanyWorkerLaunchDocument ;
use crate ::build_reorient_job_launch_request ;
use crate ::default_launch_organ_contract ;
use epiphany_state_model ::EpiphanyInvestigationCheckpoint ;
use epiphany_state_model ::EpiphanyJobKind as CoreEpiphanyJobKind ;
use epiphany_state_model ::EpiphanyThreadState ;
pub const EPIPHANY_IMAGINATION_ROLE_BINDING_ID : & str = " planning-synthesis-worker " ;
pub const EPIPHANY_IMAGINATION_OWNER_ROLE : & str = " epiphany-imagination " ;
2026-07-15 03:05:11 +01:00
pub const EPIPHANY_MIND_ROLE_BINDING_ID : & str = " mind-admission-reviewer " ;
pub const EPIPHANY_MIND_OWNER_ROLE : & str = " epiphany-mind-admission-review " ;
2026-05-30 01:02:16 +01:00
pub const EPIPHANY_RESEARCH_ROLE_BINDING_ID : & str = " research-source-gather-worker " ;
pub const EPIPHANY_RESEARCH_OWNER_ROLE : & str = " epiphany-eyes " ;
2026-05-28 21:02:26 +01:00
pub const EPIPHANY_MODELING_ROLE_BINDING_ID : & str = " modeling-checkpoint-worker " ;
pub const EPIPHANY_MODELING_OWNER_ROLE : & str = " epiphany-modeler " ;
pub const EPIPHANY_VERIFICATION_ROLE_BINDING_ID : & str = " verification-review-worker " ;
pub const EPIPHANY_VERIFICATION_OWNER_ROLE : & str = " epiphany-verifier " ;
pub const EPIPHANY_REORIENT_LAUNCH_BINDING_ID : & str = " reorient-worker " ;
pub const EPIPHANY_REORIENT_OWNER_ROLE : & str = " epiphany-reorient " ;
pub fn epiphany_role_binding_id ( role_id : EpiphanyRoleResultRoleId ) -> Result < & 'static str , String > {
match role_id {
EpiphanyRoleResultRoleId ::Imagination = > Ok ( EPIPHANY_IMAGINATION_ROLE_BINDING_ID ) ,
2026-05-30 01:02:16 +01:00
EpiphanyRoleResultRoleId ::Research = > Ok ( EPIPHANY_RESEARCH_ROLE_BINDING_ID ) ,
2026-05-28 21:02:26 +01:00
EpiphanyRoleResultRoleId ::Modeling = > Ok ( EPIPHANY_MODELING_ROLE_BINDING_ID ) ,
EpiphanyRoleResultRoleId ::Verification = > Ok ( EPIPHANY_VERIFICATION_ROLE_BINDING_ID ) ,
EpiphanyRoleResultRoleId ::Implementation = > Err (
" implementation is owned by the main coding agent; no role specialist launch template exists "
. to_string ( ) ,
) ,
EpiphanyRoleResultRoleId ::Reorientation = > Err (
2026-07-12 00:41:05 +01:00
" reorientation uses epiphany.coordinator.reorient.launch and epiphany.coordinator.reorient.result.read "
2026-05-28 21:02:26 +01:00
. to_string ( ) ,
) ,
}
}
pub fn epiphany_role_owner ( role_id : EpiphanyRoleResultRoleId ) -> Result < & 'static str , String > {
match role_id {
EpiphanyRoleResultRoleId ::Imagination = > Ok ( EPIPHANY_IMAGINATION_OWNER_ROLE ) ,
2026-05-30 01:02:16 +01:00
EpiphanyRoleResultRoleId ::Research = > Ok ( EPIPHANY_RESEARCH_OWNER_ROLE ) ,
2026-05-28 21:02:26 +01:00
EpiphanyRoleResultRoleId ::Modeling = > Ok ( EPIPHANY_MODELING_OWNER_ROLE ) ,
EpiphanyRoleResultRoleId ::Verification = > Ok ( EPIPHANY_VERIFICATION_OWNER_ROLE ) ,
EpiphanyRoleResultRoleId ::Implementation | EpiphanyRoleResultRoleId ::Reorientation = > {
Err ( epiphany_role_binding_id ( role_id ) . unwrap_err ( ) )
}
}
}
pub fn epiphany_role_label ( role_id : EpiphanyRoleResultRoleId ) -> & 'static str {
match role_id {
EpiphanyRoleResultRoleId ::Implementation = > " implementation " ,
EpiphanyRoleResultRoleId ::Imagination = > " imagination " ,
2026-05-30 01:02:16 +01:00
EpiphanyRoleResultRoleId ::Research = > " research " ,
2026-05-28 21:02:26 +01:00
EpiphanyRoleResultRoleId ::Modeling = > " modeling " ,
EpiphanyRoleResultRoleId ::Verification = > " verification " ,
EpiphanyRoleResultRoleId ::Reorientation = > " reorientation " ,
}
}
2026-07-16 16:49:45 +01:00
fn repo_frontier_item_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " id " , " migration_body " , " question " , " gap " , " recommended_next_organ " , " status " ] ,
" properties " : {
" id " : { " type " : " string " , " minLength " : 1 } ,
" migration_body " : { " type " : " string " , " minLength " : 1 } ,
" question " : { " type " : " string " , " minLength " : 1 } ,
" gap " : { " type " : " string " , " minLength " : 1 } ,
" target_claim_ids " : { " type " : " array " , " items " : { " type " : " string " } } ,
" source_scope " : { " type " : " array " , " items " : { " type " : " string " } } ,
" recommended_next_organ " : { " type " : " string " , " minLength " : 1 } ,
" dependency_item_ids " : { " type " : " array " , " items " : { " type " : " string " } } ,
" status " : { " type " : " string " , " enum " : [ " proposed " , " active " , " blocked " , " resolved " , " retired " , " superseded " ] } ,
" evidence_refs " : { " type " : " array " , " items " : { " type " : " string " } } ,
" created_at " : { " type " : " string " } ,
" updated_at " : { " type " : " string " }
}
} )
}
fn repo_model_node_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " id " , " domain_id " , " profile " , " kind " , " title " , " claim " , " question " , " tension " , " action_implication " ] ,
" properties " : {
" id " : { " type " : " string " , " minLength " : 1 } ,
" domain_id " : { " type " : " string " , " minLength " : 1 } ,
" profile " : { " type " : " string " , " enum " : [ " repo_architecture " , " repo_dataflow " , " role_self " , " short_term " , " incubation " , " agency_pressure " , " candidate_intervention " , " identity " , " evidence " ] } ,
" kind " : { " type " : " string " , " enum " : [ " domain " , " module " , " crate " , " binary " , " schema " , " runtime_contract " , " adapter " , " test_seam " , " state_store " , " role_memory " , " short_term_thought " , " incubation_thread " , " agency_pressure " , " candidate_intervention " , " identity " , " evidence " , " summary " , " other " ] } ,
" title " : { " type " : " string " } ,
" claim " : { " type " : " string " } ,
" question " : { " type " : " string " } ,
" tension " : { " type " : " string " } ,
" action_implication " : { " type " : " string " } ,
" anchors " : { " type " : " array " , " items " : memory_anchor_output_schema ( ) } ,
" source_hashes " : { " type " : " array " , " items " : { " type " : " string " } } ,
" lifecycle " : { " type " : " string " } ,
" salience " : { " type " : " integer " , " minimum " : 0 } ,
" confidence " : { " type " : " integer " , " minimum " : 0 } ,
" created_at " : { " type " : " string " } ,
" updated_at " : { " type " : " string " }
} ,
" additionalProperties " : false
} )
}
fn repo_model_edge_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " id " , " source_id " , " target_id " , " kind " , " profile " , " claim " ] ,
" properties " : {
" id " : { " type " : " string " , " minLength " : 1 } ,
" source_id " : { " type " : " string " , " minLength " : 1 } ,
" target_id " : { " type " : " string " , " minLength " : 1 } ,
" kind " : { " type " : " string " , " enum " : [ " owns " , " reads " , " writes " , " derives " , " adapts " , " persists " , " launches " , " verifies " , " supports " , " contradicts " , " distills " , " revises " , " retires " , " grounds " , " triggers " , " spoken_as " , " cools " , " clusters_with " , " resonates_with " , " depends_on " , " other " ] } ,
" profile " : { " type " : " string " , " enum " : [ " repo_architecture " , " repo_dataflow " , " role_self " , " short_term " , " incubation " , " agency_pressure " , " candidate_intervention " , " identity " , " evidence " ] } ,
" claim " : { " type " : " string " } ,
" anchors " : { " type " : " array " , " items " : memory_anchor_output_schema ( ) } ,
" lifecycle " : { " type " : " string " } ,
" confidence " : { " type " : " integer " , " minimum " : 0 }
} ,
" additionalProperties " : false
} )
}
fn code_ref_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " path " ] ,
" properties " : {
" path " : { " type " : " string " , " minLength " : 1 } ,
" start_line " : { " type " : " integer " , " minimum " : 1 } ,
" end_line " : { " type " : " integer " , " minimum " : 1 } ,
" symbol " : { " type " : " string " } ,
" note " : { " type " : " string " }
} ,
" additionalProperties " : false
} )
}
fn memory_anchor_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " id " , " kind " , " target " ] ,
" properties " : {
" id " : { " type " : " string " , " minLength " : 1 } ,
" kind " : { " type " : " string " , " minLength " : 1 } ,
" target " : { " type " : " string " , " minLength " : 1 } ,
" code_ref " : code_ref_output_schema ( ) ,
" evidence_id " : { " type " : " string " } ,
" source_hash " : { " type " : " string " }
} ,
" additionalProperties " : false
} )
}
fn observation_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " id " , " summary " , " source_kind " , " status " ] ,
" properties " : {
" id " : { " type " : " string " , " minLength " : 1 } ,
" summary " : { " type " : " string " , " minLength " : 1 } ,
" source_kind " : { " type " : " string " , " minLength " : 1 } ,
" status " : { " type " : " string " , " minLength " : 1 } ,
" code_refs " : { " type " : " array " , " items " : code_ref_output_schema ( ) } ,
" evidence_ids " : { " type " : " array " , " items " : { " type " : " string " } }
} ,
" additionalProperties " : false
} )
}
fn evidence_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" required " : [ " id " , " kind " , " status " , " summary " ] ,
" properties " : {
" id " : { " type " : " string " , " minLength " : 1 } ,
" kind " : { " type " : " string " , " minLength " : 1 } ,
" status " : { " type " : " string " , " minLength " : 1 } ,
" summary " : { " type " : " string " , " minLength " : 1 } ,
" code_refs " : { " type " : " array " , " items " : code_ref_output_schema ( ) }
} ,
" additionalProperties " : false
} )
}
2026-05-28 21:02:26 +01:00
pub fn epiphany_role_launch_output_schema ( role_id : EpiphanyRoleResultRoleId ) -> serde_json ::Value {
let verdict_enum = match role_id {
EpiphanyRoleResultRoleId ::Imagination = > {
vec! [ " draft-ready " , " planning-update-needed " , " blocked " ]
}
2026-05-30 01:02:16 +01:00
EpiphanyRoleResultRoleId ::Research = > {
vec! [ " evidence-ready " , " source-gap " , " blocked " ]
}
2026-05-28 21:02:26 +01:00
EpiphanyRoleResultRoleId ::Modeling = > {
vec! [
" checkpoint-ready " ,
" checkpoint-update-needed " ,
" regather-needed " ,
]
}
EpiphanyRoleResultRoleId ::Verification = > {
vec! [ " pass " , " needs-review " , " needs-evidence " , " fail " ]
}
EpiphanyRoleResultRoleId ::Implementation | EpiphanyRoleResultRoleId ::Reorientation = > {
vec! [ ]
}
} ;
let mut properties = serde_json ::json! ( {
" roleId " : {
" type " : " string " ,
" enum " : [ epiphany_role_label ( role_id ) ]
} ,
" verdict " : {
" type " : " string " ,
" enum " : verdict_enum
} ,
" summary " : { " type " : " string " } ,
" nextSafeMove " : { " type " : " string " } ,
" checkpointSummary " : { " type " : " string " } ,
" scratchSummary " : { " type " : " string " } ,
" filesInspected " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" frontierNodeIds " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" evidenceIds " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" openQuestions " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" evidenceGaps " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" risks " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" selfPatch " : {
" type " : " object " ,
2026-06-15 16:38:09 +01:00
" description " : " Optional bounded request to update this role's persistent organ memory. Work organs may update lane habits, durable lessons, goals, values, or private notes; Persona affect/social state belongs only to Persona public surfaces. It must not contain project truth, code edits, job authority, graph/frontier/checkpoint/planning changes, or objective changes. " ,
2026-05-28 21:02:26 +01:00
" required " : [ " agentId " , " reason " ] ,
" properties " : {
" agentId " : {
" type " : " string " ,
2026-06-15 16:38:09 +01:00
" description " : " Expected target persistent agent id for this lane, such as epiphany.modeling or epiphany.soul. "
2026-05-28 21:02:26 +01:00
} ,
" reason " : {
" type " : " string " ,
" description " : " Why this memory mutation makes the lane sharper for future work. "
} ,
" evidenceIds " : {
" type " : " array " ,
" description " : " Optional accepted/project evidence ids that ground the memory request. These do not count as a memory mutation by themselves. " ,
" items " : { " type " : " string " }
} ,
" semanticMemories " : {
" type " : " array " ,
" items " : {
" type " : " object " ,
" required " : [ " memoryId " , " summary " , " salience " , " confidence " ] ,
" additionalProperties " : true
}
} ,
" episodicMemories " : {
" type " : " array " ,
" items " : {
" type " : " object " ,
" required " : [ " memoryId " , " summary " , " salience " , " confidence " ] ,
" additionalProperties " : true
}
} ,
" relationshipMemories " : {
" type " : " array " ,
" items " : {
" type " : " object " ,
" required " : [ " memoryId " , " summary " , " salience " , " confidence " ] ,
" additionalProperties " : true
}
} ,
" goals " : {
" type " : " array " ,
" items " : {
" type " : " object " ,
" required " : [ " goalId " , " description " , " scope " , " priority " , " emotionalStake " , " status " ] ,
" additionalProperties " : true
}
} ,
" values " : {
" type " : " array " ,
" items " : {
" type " : " object " ,
" required " : [ " valueId " , " label " , " priority " , " unforgivableIfBetrayed " ] ,
" additionalProperties " : true
}
} ,
" privateNotes " : {
" type " : " array " ,
" items " : { " type " : " string " }
}
} ,
" additionalProperties " : false
}
} ) ;
2026-07-13 22:29:10 +01:00
if role_id = = EpiphanyRoleResultRoleId ::Verification {
properties [ " verificationRequestId " ] = serde_json ::json! ( { " type " : " string " , " minLength " : 1 } ) ;
properties [ " frontierRouteId " ] = serde_json ::json! ( { " type " : " string " , " minLength " : 1 } ) ;
}
2026-05-28 21:02:26 +01:00
let mut required = vec! [
" roleId " ,
" verdict " ,
" summary " ,
" nextSafeMove " ,
" filesInspected " ,
] ;
2026-07-13 22:29:10 +01:00
if role_id = = EpiphanyRoleResultRoleId ::Verification {
required . push ( " verificationRequestId " ) ;
required . push ( " frontierRouteId " ) ;
}
2026-05-28 21:02:26 +01:00
if role_id = = EpiphanyRoleResultRoleId ::Imagination {
if let Some ( map ) = properties . as_object_mut ( ) {
map . insert (
" statePatch " . to_string ( ) ,
serde_json ::json! ( {
" type " : " object " ,
2026-07-12 00:41:05 +01:00
" description " : " Required reviewable statePatch for Mind admission from Imagination. Use only planning plus optional observations/evidence. planning is a full replacement object and must include at least one objective_drafts entry with status draft. " ,
2026-05-28 21:02:26 +01:00
" required " : [ " planning " ] ,
" properties " : {
" planning " : {
" type " : " object " ,
" required " : [ " objective_drafts " ] ,
" properties " : {
" objective_drafts " : {
" type " : " array " ,
" minItems " : 1 ,
" items " : {
" type " : " object " ,
" required " : [ " id " , " title " , " summary " , " acceptance_criteria " , " status " ] ,
" properties " : {
" status " : {
" type " : " string " ,
" enum " : [ " draft " ]
}
} ,
" additionalProperties " : true
}
}
} ,
" additionalProperties " : true
}
} ,
" additionalProperties " : true
} ) ,
) ;
}
required . push ( " statePatch " ) ;
2026-05-30 01:02:16 +01:00
} else if role_id = = EpiphanyRoleResultRoleId ::Research {
if let Some ( map ) = properties . as_object_mut ( ) {
map . insert (
" statePatch " . to_string ( ) ,
serde_json ::json! ( {
" type " : " object " ,
2026-07-12 00:41:05 +01:00
" description " : " Required reviewable statePatch for Mind admission from research/Eyes. Use only observations, evidence, scratch, and optional investigationCheckpoint. The patch must include at least one evidence record and one observation that cites it. " ,
2026-05-30 01:02:16 +01:00
" required " : [ " observations " , " evidence " ] ,
" properties " : {
" observations " : {
" type " : " array " ,
" minItems " : 1 ,
" items " : {
" type " : " object " ,
" required " : [ " id " , " summary " , " source_kind " , " status " , " evidence_ids " ] ,
" additionalProperties " : true
}
} ,
" evidence " : {
" type " : " array " ,
" minItems " : 1 ,
" items " : {
" type " : " object " ,
" required " : [ " id " , " kind " , " status " , " summary " ] ,
" additionalProperties " : true
}
2026-07-16 16:49:45 +01:00
} ,
" scratch " : {
" type " : " object " ,
" required " : [ " summary " ] ,
" properties " : {
" summary " : { " type " : " string " , " minLength " : 1 }
} ,
" additionalProperties " : true
} ,
" investigationCheckpoint " : {
" type " : " object " ,
" description " : " Outer statePatch uses camelCase; this typed checkpoint payload uses its canonical snake_case field names. " ,
" required " : [ " checkpoint_id " , " kind " , " disposition " , " focus " ] ,
" properties " : {
" checkpoint_id " : { " type " : " string " , " minLength " : 1 } ,
" kind " : { " type " : " string " , " minLength " : 1 } ,
" disposition " : { " type " : " string " , " enum " : [ " resume_ready " , " regather_required " ] } ,
" focus " : { " type " : " string " , " minLength " : 1 } ,
" summary " : { " type " : " string " } ,
" next_action " : { " type " : " string " } ,
" captured_at_turn_id " : { " type " : " string " } ,
" open_questions " : { " type " : " array " , " items " : { " type " : " string " } } ,
" code_refs " : { " type " : " array " , " items " : { " type " : " object " } } ,
" evidence_ids " : { " type " : " array " , " items " : { " type " : " string " } }
} ,
" additionalProperties " : false
2026-05-30 01:02:16 +01:00
}
} ,
" anyOf " : [
{ " required " : [ " scratch " ] } ,
{ " required " : [ " investigationCheckpoint " ] }
] ,
" additionalProperties " : true
} ) ,
) ;
}
required . push ( " statePatch " ) ;
2026-05-28 21:02:26 +01:00
} else if role_id = = EpiphanyRoleResultRoleId ::Modeling {
if let Some ( map ) = properties . as_object_mut ( ) {
2026-07-15 22:06:06 +01:00
map . insert (
" repositoryBodyObservationBasis " . to_string ( ) ,
serde_json ::json! ( {
" type " : " object " ,
" description " : " Exact echo of the immutable repository Body observation basis supplied in the Modeling launch. " ,
" required " : [
" schemaVersion " , " workspaceId " , " swarmId " , " runtimeId " , " scope " ,
" bodyBindingSha256 " , " observationId " , " generation " ,
" manifestRootSha256 " , " scanStartedAt " , " scanFinishedAt "
] ,
" properties " : {
" schemaVersion " : { " type " : " string " , " minLength " : 1 } ,
" workspaceId " : { " type " : " string " , " minLength " : 1 } ,
" swarmId " : { " type " : " string " , " minLength " : 1 } ,
" runtimeId " : { " type " : " string " , " minLength " : 1 } ,
" scope " : { " type " : " string " , " minLength " : 1 } ,
" bodyBindingSha256 " : { " type " : " string " , " minLength " : 1 } ,
" observationId " : { " type " : " string " , " minLength " : 1 } ,
" generation " : { " type " : " integer " , " minimum " : 1 } ,
" manifestRootSha256 " : { " type " : " string " , " minLength " : 1 } ,
" scanStartedAt " : { " type " : " string " , " minLength " : 1 } ,
" scanFinishedAt " : { " type " : " string " , " minLength " : 1 }
} ,
" additionalProperties " : false
} ) ,
) ;
2026-05-28 21:02:26 +01:00
map . insert (
2026-07-13 22:29:10 +01:00
" repoModelPatch " . to_string ( ) ,
2026-05-28 21:02:26 +01:00
serde_json ::json! ( {
" type " : " object " ,
2026-07-13 22:29:10 +01:00
" description " : " Required typed proposal against the canonical repository model. This is ingress for later review, not admission authority. " ,
" required " : [ " patch_id " , " base_revision " , " base_hash " , " applied_at " , " purpose " , " operations " ] ,
2026-05-28 21:02:26 +01:00
" properties " : {
2026-07-13 22:29:10 +01:00
" patch_id " : { " type " : " string " , " minLength " : 1 } ,
" base_revision " : { " type " : " integer " , " minimum " : 0 } ,
" base_hash " : { " type " : " string " , " minLength " : 1 } ,
" applied_at " : { " type " : " string " , " minLength " : 1 } ,
" purpose " : {
" description " : " Use {kind: evolution} for ordinary Modeling output; frontier closure requires separately routed authority. " ,
" oneOf " : [
{
" type " : " object " ,
" required " : [ " kind " ] ,
" properties " : { " kind " : { " const " : " evolution " } } ,
" additionalProperties " : false
} ,
{
" type " : " object " ,
" required " : [ " kind " , " route_id " , " soul_verdict_receipt_id " ] ,
" properties " : {
" kind " : { " const " : " incorporate_frontier_verdict " } ,
" route_id " : { " type " : " string " , " minLength " : 1 } ,
" soul_verdict_receipt_id " : { " type " : " string " , " minLength " : 1 }
} ,
" additionalProperties " : false
2026-07-15 00:43:05 +01:00
} ,
{
" type " : " object " ,
" required " : [ " kind " ] ,
" properties " : { " kind " : { " const " : " repair_claim " } } ,
" additionalProperties " : false
2026-07-16 16:49:45 +01:00
} ,
{
" type " : " object " ,
" required " : [ " kind " , " planning_request_id " , " result_id " , " candidate_id " ] ,
" properties " : {
" kind " : { " const " : " adopt_frontier_plan " } ,
" planning_request_id " : { " type " : " string " , " minLength " : 1 } ,
" result_id " : { " type " : " string " , " minLength " : 1 } ,
" candidate_id " : { " type " : " string " , " minLength " : 1 }
} ,
" additionalProperties " : false
2026-05-28 21:02:26 +01:00
}
2026-07-13 22:29:10 +01:00
]
} ,
2026-07-16 16:49:45 +01:00
" operations " : {
" type " : " array " ,
" minItems " : 1 ,
" items " : {
" anyOf " : [
{ " type " : " object " , " required " : [ " operation " , " node " ] , " properties " : { " operation " : { " const " : " upsert_node " } , " node " : repo_model_node_output_schema ( ) } } ,
{ " type " : " object " , " required " : [ " operation " , " node " ] , " properties " : { " operation " : { " const " : " revise_node " } , " node " : repo_model_node_output_schema ( ) } } ,
{ " type " : " object " , " required " : [ " operation " , " node_id " ] , " properties " : { " operation " : { " const " : " retire_node " } , " node_id " : { " type " : " string " , " minLength " : 1 } } } ,
{ " type " : " object " , " required " : [ " operation " , " edge " ] , " properties " : { " operation " : { " const " : " upsert_edge " } , " edge " : repo_model_edge_output_schema ( ) } } ,
{ " type " : " object " , " required " : [ " operation " , " edge " ] , " properties " : { " operation " : { " const " : " revise_edge " } , " edge " : repo_model_edge_output_schema ( ) } } ,
{ " type " : " object " , " required " : [ " operation " , " edge_id " ] , " properties " : { " operation " : { " const " : " retire_edge " } , " edge_id " : { " type " : " string " , " minLength " : 1 } } } ,
{ " type " : " object " , " required " : [ " operation " , " item " ] , " properties " : { " operation " : { " const " : " upsert_frontier " } , " item " : repo_frontier_item_output_schema ( ) } } ,
{ " type " : " object " , " required " : [ " operation " , " item " ] , " properties " : { " operation " : { " const " : " revise_frontier " } , " item " : repo_frontier_item_output_schema ( ) } } ,
{ " type " : " object " , " required " : [ " operation " , " item_id " ] , " properties " : { " operation " : { " const " : " retire_frontier " } , " item_id " : { " type " : " string " , " minLength " : 1 } , " retired_at " : { " type " : " string " } , " superseded_by " : { " type " : " string " } } } ,
{ " type " : " object " , " required " : [ " operation " , " frontier_item_id " , " expected_frontier_item_hash " , " adopted_plan " ] , " properties " : { " operation " : { " const " : " adopt_frontier_plan " } , " frontier_item_id " : { " type " : " string " , " minLength " : 1 } , " expected_frontier_item_hash " : { " type " : " string " , " minLength " : 1 } , " adopted_plan " : { " type " : " object " } } }
]
}
}
2026-05-28 21:02:26 +01:00
} ,
" additionalProperties " : true
} ) ,
) ;
2026-07-13 22:29:10 +01:00
map . insert (
" repoFrontierModelingRequestId " . to_string ( ) ,
serde_json ::json! ( { " type " : " string " , " minLength " : 1 } ) ,
) ;
2026-07-14 01:03:54 +01:00
map . insert (
" proposalModelingRequestId " . to_string ( ) ,
serde_json ::json! ( {
" type " : " string " ,
" minLength " : 1 ,
" description " : " Exact echo of an explicit typed repo-frontier proposal Modeling request, when supplied. "
} ) ,
) ;
2026-07-15 00:43:05 +01:00
map . insert (
" claimRepairRequestId " . to_string ( ) ,
serde_json ::json! ( {
" type " : " string " ,
" minLength " : 1 ,
" description " : " Exact echo of the coordinator-bound claim repair request; valid only with purpose repair_claim. "
} ) ,
) ;
2026-07-13 22:29:10 +01:00
map . insert (
" statePatch " . to_string ( ) ,
serde_json ::json! ( {
" type " : " object " ,
" description " : " Optional generic Mind-reviewable observations/evidence only. Repository anatomy belongs exclusively in repoModelPatch. " ,
" properties " : {
2026-07-16 16:49:45 +01:00
" observations " : { " type " : " array " , " items " : observation_output_schema ( ) } ,
" evidence " : { " type " : " array " , " items " : evidence_output_schema ( ) }
2026-07-13 22:29:10 +01:00
} ,
" additionalProperties " : false
} ) ,
) ;
2026-05-28 21:02:26 +01:00
}
required . push ( " frontierNodeIds " ) ;
2026-07-13 22:29:10 +01:00
required . push ( " repoModelPatch " ) ;
2026-07-15 22:06:06 +01:00
required . push ( " repositoryBodyObservationBasis " ) ;
2026-05-28 21:02:26 +01:00
}
2026-07-13 22:29:10 +01:00
let mut schema = serde_json ::json! ( {
2026-05-28 21:02:26 +01:00
" type " : " object " ,
" properties " : properties ,
" required " : required ,
" additionalProperties " : true
2026-07-13 22:29:10 +01:00
} ) ;
if role_id = = EpiphanyRoleResultRoleId ::Modeling {
2026-07-15 00:43:05 +01:00
schema [ " allOf " ] = serde_json ::json! ( [
{
" if " : {
" properties " : {
" repoModelPatch " : {
" properties " : {
" purpose " : {
" properties " : { " kind " : { " const " : " incorporate_frontier_verdict " } } ,
" required " : [ " kind " ]
}
} ,
" required " : [ " purpose " ]
}
} ,
" required " : [ " repoModelPatch " ]
2026-07-13 22:29:10 +01:00
} ,
2026-07-15 00:43:05 +01:00
" then " : { " required " : [ " repoFrontierModelingRequestId " ] }
2026-07-13 22:29:10 +01:00
} ,
2026-07-15 00:43:05 +01:00
{
" if " : {
" properties " : {
" repoModelPatch " : {
" properties " : {
" purpose " : {
" properties " : { " kind " : { " const " : " repair_claim " } } ,
" required " : [ " kind " ]
}
}
, " required " : [ " purpose " ]
}
} ,
" required " : [ " repoModelPatch " ]
} ,
" then " : { " required " : [ " claimRepairRequestId " ] }
}
] ) ;
2026-07-13 22:29:10 +01:00
}
schema
2026-05-28 21:02:26 +01:00
}
2026-07-15 01:29:35 +01:00
pub fn epiphany_frontier_planning_output_schema ( ) -> serde_json ::Value {
let mut schema = epiphany_role_launch_output_schema ( EpiphanyRoleResultRoleId ::Imagination ) ;
let properties = schema [ " properties " ]
. as_object_mut ( )
. expect ( " role output schema properties " ) ;
properties . remove ( " statePatch " ) ;
properties . remove ( " selfPatch " ) ;
properties . insert (
" frontierPlanningRequestId " . to_string ( ) ,
serde_json ::json! ( {
" type " : " string " ,
" minLength " : 1 ,
" description " : " Exact echo of the coordinator-bound repo frontier planning request. "
} ) ,
) ;
properties . insert (
" frontierPlanCandidate " . to_string ( ) ,
serde_json ::json! ( {
" type " : " object " ,
" required " : [
" planning_request_id " , " model_revision " , " model_hash " ,
" frontier_item_id " , " frontier_item_hash " , " safe_paths " , " action " , " command " ,
" checks " , " stop_conditions " , " rollback_steps " , " commit_message " , " proposed_at "
] ,
" properties " : {
" planning_request_id " : { " type " : " string " , " minLength " : 1 } ,
" model_revision " : { " type " : " integer " , " minimum " : 0 } ,
" model_hash " : { " type " : " string " , " minLength " : 1 } ,
" frontier_item_id " : { " type " : " string " , " minLength " : 1 } ,
" frontier_item_hash " : { " type " : " string " , " minLength " : 1 } ,
" safe_paths " : { " type " : " array " , " minItems " : 1 , " items " : { " type " : " string " , " minLength " : 1 } } ,
" action " : { " type " : " string " , " minLength " : 1 } ,
" command " : { " type " : " string " , " minLength " : 1 } ,
" checks " : { " type " : " array " , " minItems " : 1 , " items " : { " type " : " string " , " minLength " : 1 } } ,
" stop_conditions " : { " type " : " array " , " minItems " : 1 , " items " : { " type " : " string " , " minLength " : 1 } } ,
" rollback_steps " : { " type " : " array " , " minItems " : 1 , " items " : { " type " : " string " , " minLength " : 1 } } ,
" commit_message " : { " type " : " string " , " minLength " : 1 } ,
" proposed_at " : { " type " : " string " , " minLength " : 1 }
} ,
" additionalProperties " : false
} ) ,
) ;
schema [ " required " ] = serde_json ::json! ( [
" roleId " ,
" verdict " ,
" summary " ,
" nextSafeMove " ,
" filesInspected " ,
" frontierPlanningRequestId " ,
" frontierPlanCandidate "
] ) ;
schema [ " additionalProperties " ] = serde_json ::Value ::Bool ( false ) ;
schema
}
2026-07-15 03:05:11 +01:00
pub fn epiphany_frontier_plan_mind_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" properties " : {
" roleId " : { " type " : " string " , " const " : " mindAdmissionReview " } ,
" verdict " : { " type " : " string " , " minLength " : 1 } ,
" summary " : { " type " : " string " , " minLength " : 1 } ,
" nextSafeMove " : { " type " : " string " , " minLength " : 1 } ,
" filesInspected " : { " type " : " array " , " items " : { " type " : " string " } } ,
" frontierPlanMindRequestId " : { " type " : " string " , " minLength " : 1 } ,
" frontierPlanMindDecision " : {
" type " : " object " ,
" required " : [ " mindRequestId " , " planningRequestId " , " imaginationResultId " , " candidateId " , " candidateSha256 " , " decision " , " rationale " , " decidedAt " ] ,
" properties " : {
" mindRequestId " : { " type " : " string " , " minLength " : 1 } , " planningRequestId " : { " type " : " string " , " minLength " : 1 } ,
" imaginationResultId " : { " type " : " string " , " minLength " : 1 } , " candidateId " : { " type " : " string " , " minLength " : 1 } ,
" candidateSha256 " : { " type " : " string " , " minLength " : 1 } , " decision " : { " type " : " string " , " enum " : [ " adopt " , " refuse " , " hold " ] } ,
" rationale " : { " type " : " string " , " minLength " : 1 } , " decidedAt " : { " type " : " string " , " minLength " : 1 }
} , " additionalProperties " : false
}
} ,
" required " : [ " roleId " , " verdict " , " summary " , " nextSafeMove " , " filesInspected " , " frontierPlanMindRequestId " , " frontierPlanMindDecision " ] ,
" additionalProperties " : false
} )
}
2026-07-18 20:31:57 +01:00
pub fn epiphany_imagination_consideration_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" properties " : {
" roleId " : { " type " : " string " , " const " : " imagination " } ,
" verdict " : { " type " : " string " , " minLength " : 1 } ,
" summary " : { " type " : " string " , " minLength " : 1 } ,
" nextSafeMove " : { " type " : " string " , " minLength " : 1 } ,
" filesInspected " : { " type " : " array " , " items " : { " type " : " string " } } ,
" imaginationConsiderationRequestId " : { " type " : " string " , " minLength " : 1 } ,
" imaginationConsiderationCandidate " : {
" type " : " object " ,
" required " : [ " request_id " , " feedback_id " , " feedback_packet_sha256 " , " model_revision " , " model_hash " ,
" source_room_id " , " source_visibility " , " data_classification " ,
" disposition " , " title " , " summary " , " rationale " , " option_drafts " , " uncertainties " , " evidence_refs " ,
" recommended_review_route " , " proposed_at " , " contract " ] ,
" properties " : {
" request_id " : { " type " : " string " , " minLength " : 1 } ,
" feedback_id " : { " type " : " string " , " minLength " : 1 } ,
" feedback_packet_sha256 " : { " type " : " string " , " minLength " : 1 } ,
" model_revision " : { " type " : " integer " , " minimum " : 0 } ,
" model_hash " : { " type " : " string " , " minLength " : 1 } ,
" disposition " : { " type " : " string " , " enum " : [ " suggest " , " hold " , " no_fit " ] } ,
" title " : { " type " : " string " , " minLength " : 1 } , " summary " : { " type " : " string " , " minLength " : 1 } ,
" rationale " : { " type " : " string " , " minLength " : 1 } ,
" option_drafts " : { " type " : " array " , " items " : { " type " : " object " , " required " : [ " title " , " summary " ] ,
" properties " : { " title " : { " type " : " string " , " minLength " : 1 } , " summary " : { " type " : " string " , " minLength " : 1 } } ,
" additionalProperties " : false } } ,
" uncertainties " : { " type " : " array " , " items " : { " type " : " string " } } ,
" evidence_refs " : { " type " : " array " , " minItems " : 1 , " items " : { " type " : " string " , " minLength " : 1 } } ,
" source_room_id " : { " type " : " string " , " minLength " : 1 } ,
" source_visibility " : { " type " : " string " , " minLength " : 1 } ,
" data_classification " : { " type " : " string " , " minLength " : 1 } ,
" recommended_review_route " : { " type " : " string " , " enum " : [ " modeling_review " , " hold " , " silence " ] } ,
" proposed_at " : { " type " : " string " , " minLength " : 1 } ,
" contract " : { " const " : " epiphany.imagination_consideration_candidate.v0 " }
} ,
" additionalProperties " : false
}
} ,
" required " : [ " roleId " , " verdict " , " summary " , " nextSafeMove " , " filesInspected " ,
" imaginationConsiderationRequestId " , " imaginationConsiderationCandidate " ] ,
" additionalProperties " : false
} )
}
2026-05-28 21:02:26 +01:00
pub fn epiphany_reorient_launch_output_schema ( ) -> serde_json ::Value {
serde_json ::json! ( {
" type " : " object " ,
" properties " : {
" mode " : {
" type " : " string " ,
" enum " : [ " resume " , " regather " ]
} ,
" summary " : { " type " : " string " } ,
" nextSafeMove " : { " type " : " string " } ,
" checkpointStillValid " : { " type " : " boolean " } ,
" filesInspected " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" frontierNodeIds " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" evidenceIds " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" openQuestions " : {
" type " : " array " ,
" items " : { " type " : " string " }
} ,
" continuityRisks " : {
" type " : " array " ,
" items " : { " type " : " string " }
}
} ,
" required " : [ " mode " , " summary " , " nextSafeMove " ] ,
" additionalProperties " : true
} )
}
const EPIPHANY_SPECIALIST_PROMPTS_TOML : & str = include_str! ( " prompts/epiphany_specialists.toml " ) ;
const EPIPHANY_WORKER_BOUNDARY_PROMPT : & str = r #" ## Epiphany Worker Boundary
You are one bounded Epiphany worker for this launch only . Your authority comes from the typed launch document , the role - local instruction , and the declared output contract .
Do the role , name uncertainty , and return the required JSON object . Do not become the coordinator , do not accept or promote your own output , do not invent durable state outside an allowed statePatch , and do not treat model transport or Codex machinery as prompt authority .
2026-07-13 22:29:10 +01:00
If you learned a durable role - local habit , you may include a bounded selfPatch . Project truth belongs in the role ' s typed output artifact or evidence , not memory . " #;
2026-05-28 21:02:26 +01:00
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanySpecialistPromptConfig {
pub shared : EpiphanySharedPromptConfig ,
pub roles : EpiphanyRolePromptConfig ,
// Parsed here so the bundled prompt config fails fast even though the GUI runner consumes it.
#[ allow(dead_code) ]
pub implementation : EpiphanyImplementationPromptConfig ,
pub reorientation : EpiphanyReorientationPromptConfig ,
pub coordinator : EpiphanyCoordinatorPromptConfig ,
pub crrc : EpiphanyCrrcPromptConfig ,
}
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanySharedPromptConfig {
pub persistent_memory : String ,
}
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanyRolePromptConfig {
pub imagination : String ,
2026-07-15 03:05:11 +01:00
pub mind : String ,
2026-05-28 21:02:26 +01:00
pub modeling : String ,
pub verification : String ,
#[ allow(dead_code) ]
pub research : String ,
#[ allow(dead_code) ]
pub repo_personality : String ,
#[ allow(dead_code) ]
pub repo_memory : String ,
#[ allow(dead_code) ]
2026-06-15 16:38:09 +01:00
pub persona : String ,
2026-05-28 21:02:26 +01:00
}
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanyImplementationPromptConfig {
#[ allow(dead_code) ]
pub continue_template : String ,
}
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanyReorientationPromptConfig {
pub resume : String ,
pub regather : String ,
}
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanyCoordinatorPromptConfig {
pub note_template : String ,
}
#[ derive(Debug, serde::Deserialize) ]
pub struct EpiphanyCrrcPromptConfig {
pub pre_compaction_checkpoint_intervention : String ,
}
pub fn epiphany_specialist_prompt_config ( ) -> & 'static EpiphanySpecialistPromptConfig {
static CONFIG : OnceLock < EpiphanySpecialistPromptConfig > = OnceLock ::new ( ) ;
CONFIG . get_or_init ( | | {
toml ::from_str ( EPIPHANY_SPECIALIST_PROMPTS_TOML )
. expect ( " bundled Epiphany specialist prompt config must parse " )
} )
}
pub fn epiphany_agent_prompt_with_memory ( body : & str ) -> String {
let memory = epiphany_specialist_prompt_config ( )
. shared
. persistent_memory
. trim ( ) ;
let body = body . trim ( ) ;
if memory . is_empty ( ) {
body . to_string ( )
} else if body . is_empty ( ) {
memory . to_string ( )
} else {
format! ( " {memory} \n \n {body} " )
}
}
pub fn epiphany_worker_prompt ( body : & str ) -> String {
let body = body . trim ( ) ;
if body . is_empty ( ) {
EPIPHANY_WORKER_BOUNDARY_PROMPT . to_string ( )
} else {
format! ( " {} \n \n {} " , EPIPHANY_WORKER_BOUNDARY_PROMPT , body )
}
}
pub fn build_epiphany_role_launch_request (
thread_id : & str ,
role_id : EpiphanyRoleResultRoleId ,
expected_revision : Option < u64 > ,
max_runtime_seconds : Option < u64 > ,
state : & EpiphanyThreadState ,
2026-06-02 13:57:47 +01:00
) -> Result < EpiphanyJobLaunchRequest , String > {
build_epiphany_role_launch_request_with_dynamic_context (
thread_id ,
role_id ,
expected_revision ,
max_runtime_seconds ,
state ,
None ,
)
}
2026-07-15 03:05:11 +01:00
pub fn build_epiphany_frontier_plan_mind_launch_request (
thread_id : & str ,
expected_revision : Option < u64 > ,
max_runtime_seconds : Option < u64 > ,
state : & EpiphanyThreadState ,
mind_request_id : String ,
) -> Result < EpiphanyJobLaunchRequest , String > {
let linked_subgoal_ids = epiphany_active_subgoal_ids ( Some ( state ) ) ;
let linked_graph_node_ids = epiphany_active_graph_node_ids ( Some ( state ) ) ;
let authority_scope = " epiphany.procedure.mind_admission_review " ;
let launch_document = EpiphanyWorkerLaunchDocument ::Role ( EpiphanyRoleWorkerLaunchDocument {
thread_id : thread_id . to_string ( ) ,
role_id : " mindAdmissionReview " . to_string ( ) ,
state_revision : state . revision ,
objective : state . objective . clone ( ) ,
dynamic_prompt_context : None ,
2026-07-15 22:06:06 +01:00
repository_body_observation_basis : None ,
2026-07-15 03:05:11 +01:00
proposal_modeling_context : None ,
claim_repair_context : None ,
frontier_planning_context : None ,
frontier_plan_mind_context : None ,
2026-07-18 20:31:57 +01:00
imagination_consideration_context : None ,
2026-07-15 03:05:11 +01:00
active_subgoal_id : state . active_subgoal_id . clone ( ) ,
active_subgoals : state
. subgoals
. iter ( )
. filter ( | subgoal | Some ( subgoal . id . as_str ( ) ) = = state . active_subgoal_id . as_deref ( ) )
. cloned ( )
. collect ( ) ,
active_graph_node_ids : linked_graph_node_ids . clone ( ) ,
investigation_checkpoint : state . investigation_checkpoint . clone ( ) ,
scratch : state . scratch . clone ( ) ,
invariants : state . invariants . clone ( ) ,
graphs : Some ( state . graphs . clone ( ) ) ,
recent_evidence : state . recent_evidence . iter ( ) . take ( 8 ) . cloned ( ) . collect ( ) ,
recent_observations : state . observations . iter ( ) . take ( 8 ) . cloned ( ) . collect ( ) ,
graph_frontier : state . graph_frontier . clone ( ) ,
graph_checkpoint : state . graph_checkpoint . clone ( ) ,
planning : Some ( state . planning . clone ( ) ) ,
churn : state . churn . clone ( ) ,
} ) ;
let output_contract_id = launch_document . output_contract_id ( ) . to_string ( ) ;
let organ_launch_contract = default_launch_organ_contract (
authority_scope ,
launch_document . document_kind ( ) ,
& output_contract_id ,
) ;
Ok ( EpiphanyJobLaunchRequest {
expected_revision ,
binding_id : EPIPHANY_MIND_ROLE_BINDING_ID . to_string ( ) ,
kind : CoreEpiphanyJobKind ::Specialist ,
scope : " role-scoped frontier plan judgment " . to_string ( ) ,
owner_role : EPIPHANY_MIND_OWNER_ROLE . to_string ( ) ,
authority_scope : authority_scope . to_string ( ) ,
linked_subgoal_ids ,
linked_graph_node_ids ,
instruction : epiphany_worker_prompt (
epiphany_specialist_prompt_config ( ) . roles . mind . as_str ( ) ,
) ,
launch_document ,
output_contract_id ,
organ_launch_contract ,
max_runtime_seconds ,
proposal_modeling_request_id : None ,
claim_repair_request_id : None ,
frontier_planning_request_id : None ,
frontier_plan_mind_request_id : Some ( mind_request_id ) ,
2026-07-18 20:31:57 +01:00
imagination_consideration_request_id : None ,
2026-07-15 03:05:11 +01:00
} )
}
2026-06-02 13:57:47 +01:00
pub fn build_epiphany_role_launch_request_with_dynamic_context (
thread_id : & str ,
role_id : EpiphanyRoleResultRoleId ,
expected_revision : Option < u64 > ,
max_runtime_seconds : Option < u64 > ,
state : & EpiphanyThreadState ,
dynamic_prompt_context : Option < String > ,
2026-05-28 21:02:26 +01:00
) -> Result < EpiphanyJobLaunchRequest , String > {
let binding_id = epiphany_role_binding_id ( role_id ) ? ;
let owner_role = epiphany_role_owner ( role_id ) ? ;
let linked_subgoal_ids = epiphany_active_subgoal_ids ( Some ( state ) ) ;
let linked_graph_node_ids = epiphany_active_graph_node_ids ( Some ( state ) ) ;
let ( scope , authority_scope , instruction ) = match role_id {
EpiphanyRoleResultRoleId ::Imagination = > (
" role-scoped planning synthesis " ,
" epiphany.role.imagination " ,
build_epiphany_role_launch_instruction ( role_id ) ,
) ,
2026-05-30 01:02:16 +01:00
EpiphanyRoleResultRoleId ::Research = > (
" role-scoped source gathering " ,
" epiphany.role.research " ,
build_epiphany_role_launch_instruction ( role_id ) ,
) ,
2026-05-28 21:02:26 +01:00
EpiphanyRoleResultRoleId ::Modeling = > (
" role-scoped modeling/checkpoint maintenance " ,
" epiphany.role.modeling " ,
build_epiphany_role_launch_instruction ( role_id ) ,
) ,
EpiphanyRoleResultRoleId ::Verification = > (
" role-scoped verification/review " ,
" epiphany.role.verification " ,
build_epiphany_role_launch_instruction ( role_id ) ,
) ,
EpiphanyRoleResultRoleId ::Implementation | EpiphanyRoleResultRoleId ::Reorientation = > {
return Err ( epiphany_role_binding_id ( role_id ) . unwrap_err ( ) ) ;
}
} ;
let launch_document = EpiphanyWorkerLaunchDocument ::Role ( EpiphanyRoleWorkerLaunchDocument {
thread_id : thread_id . to_string ( ) ,
role_id : epiphany_role_label ( role_id ) . to_string ( ) ,
state_revision : state . revision ,
objective : state . objective . clone ( ) ,
2026-06-02 13:57:47 +01:00
dynamic_prompt_context ,
2026-07-15 22:06:06 +01:00
repository_body_observation_basis : None ,
2026-07-14 01:03:54 +01:00
proposal_modeling_context : None ,
2026-07-15 00:11:40 +01:00
claim_repair_context : None ,
2026-07-15 01:03:59 +01:00
frontier_planning_context : None ,
2026-07-15 03:05:11 +01:00
frontier_plan_mind_context : None ,
2026-07-18 20:31:57 +01:00
imagination_consideration_context : None ,
2026-05-28 21:02:26 +01:00
active_subgoal_id : state . active_subgoal_id . clone ( ) ,
active_subgoals : state
. subgoals
. iter ( )
. filter ( | subgoal | Some ( subgoal . id . as_str ( ) ) = = state . active_subgoal_id . as_deref ( ) )
. cloned ( )
. collect ( ) ,
active_graph_node_ids : linked_graph_node_ids . clone ( ) ,
investigation_checkpoint : state . investigation_checkpoint . clone ( ) ,
scratch : state . scratch . clone ( ) ,
invariants : state . invariants . clone ( ) ,
graphs : Some ( state . graphs . clone ( ) ) ,
recent_evidence : state . recent_evidence . iter ( ) . take ( 8 ) . cloned ( ) . collect ( ) ,
recent_observations : state . observations . iter ( ) . take ( 8 ) . cloned ( ) . collect ( ) ,
graph_frontier : state . graph_frontier . clone ( ) ,
graph_checkpoint : state . graph_checkpoint . clone ( ) ,
planning : Some ( state . planning . clone ( ) ) ,
churn : state . churn . clone ( ) ,
} ) ;
let output_contract_id = launch_document . output_contract_id ( ) . to_string ( ) ;
let organ_launch_contract = default_launch_organ_contract (
authority_scope ,
launch_document . document_kind ( ) ,
& output_contract_id ,
) ;
Ok ( EpiphanyJobLaunchRequest {
expected_revision ,
binding_id : binding_id . to_string ( ) ,
kind : CoreEpiphanyJobKind ::Specialist ,
scope : scope . to_string ( ) ,
owner_role : owner_role . to_string ( ) ,
authority_scope : authority_scope . to_string ( ) ,
linked_subgoal_ids ,
linked_graph_node_ids : epiphany_active_graph_node_ids ( Some ( state ) ) ,
instruction ,
launch_document ,
output_contract_id ,
organ_launch_contract ,
max_runtime_seconds ,
2026-07-14 01:03:54 +01:00
proposal_modeling_request_id : None ,
2026-07-15 00:11:40 +01:00
claim_repair_request_id : None ,
2026-07-15 01:03:59 +01:00
frontier_planning_request_id : None ,
2026-07-15 03:05:11 +01:00
frontier_plan_mind_request_id : None ,
2026-07-18 20:31:57 +01:00
imagination_consideration_request_id : None ,
2026-05-28 21:02:26 +01:00
} )
}
2026-07-18 20:31:57 +01:00
pub fn build_epiphany_imagination_consideration_launch_request (
thread_id : & str ,
expected_revision : Option < u64 > ,
max_runtime_seconds : Option < u64 > ,
state : & EpiphanyThreadState ,
request_id : String ,
) -> Result < EpiphanyJobLaunchRequest , String > {
let mut launch = build_epiphany_role_launch_request_with_dynamic_context (
thread_id ,
EpiphanyRoleResultRoleId ::Imagination ,
expected_revision ,
max_runtime_seconds ,
state ,
None ,
) ? ;
launch . scope = " role-scoped organizational feedback consideration " . into ( ) ;
launch . authority_scope = " epiphany.imagination.consideration.proposal_only " . into ( ) ;
launch . instruction = " Await coordinator-owned typed consideration context. " . into ( ) ;
launch . organ_launch_contract = default_launch_organ_contract (
& launch . authority_scope ,
launch . launch_document . document_kind ( ) ,
& launch . output_contract_id ,
) ;
launch . imagination_consideration_request_id = Some ( request_id ) ;
Ok ( launch )
}
2026-05-28 21:02:26 +01:00
fn build_epiphany_role_launch_instruction ( role_id : EpiphanyRoleResultRoleId ) -> String {
let prompts = & epiphany_specialist_prompt_config ( ) . roles ;
let body = match role_id {
EpiphanyRoleResultRoleId ::Imagination = > prompts . imagination . as_str ( ) ,
2026-05-30 01:02:16 +01:00
EpiphanyRoleResultRoleId ::Research = > prompts . research . as_str ( ) ,
2026-05-28 21:02:26 +01:00
EpiphanyRoleResultRoleId ::Modeling = > prompts . modeling . as_str ( ) ,
EpiphanyRoleResultRoleId ::Verification = > prompts . verification . as_str ( ) ,
EpiphanyRoleResultRoleId ::Implementation | EpiphanyRoleResultRoleId ::Reorientation = > {
" Unsupported Epiphany role specialist template. "
}
} ;
epiphany_worker_prompt ( body )
}
pub fn build_epiphany_reorient_launch_request (
thread_id : & str ,
expected_revision : Option < u64 > ,
max_runtime_seconds : Option < u64 > ,
state : & EpiphanyThreadState ,
checkpoint : & EpiphanyInvestigationCheckpoint ,
decision : & CoreEpiphanyReorientDecision ,
2026-06-02 13:57:47 +01:00
) -> EpiphanyJobLaunchRequest {
build_epiphany_reorient_launch_request_with_dynamic_context (
thread_id ,
expected_revision ,
max_runtime_seconds ,
state ,
checkpoint ,
decision ,
None ,
)
}
pub fn build_epiphany_reorient_launch_request_with_dynamic_context (
thread_id : & str ,
expected_revision : Option < u64 > ,
max_runtime_seconds : Option < u64 > ,
state : & EpiphanyThreadState ,
checkpoint : & EpiphanyInvestigationCheckpoint ,
decision : & CoreEpiphanyReorientDecision ,
dynamic_prompt_context : Option < String > ,
2026-05-28 21:02:26 +01:00
) -> EpiphanyJobLaunchRequest {
let instruction = build_epiphany_reorient_launch_instruction ( decision . action ) ;
build_reorient_job_launch_request ( EpiphanyReorientLaunchRequestInput {
thread_id ,
expected_revision ,
max_runtime_seconds ,
binding_id : EPIPHANY_REORIENT_LAUNCH_BINDING_ID ,
owner_role : EPIPHANY_REORIENT_OWNER_ROLE ,
instruction ,
state ,
checkpoint ,
decision ,
2026-06-02 13:57:47 +01:00
dynamic_prompt_context ,
2026-05-28 21:02:26 +01:00
} )
}
pub fn build_epiphany_reorient_launch_instruction ( action : CoreEpiphanyReorientAction ) -> String {
let prompts = & epiphany_specialist_prompt_config ( ) . reorientation ;
let body = match action {
CoreEpiphanyReorientAction ::Resume = > prompts . resume . as_str ( ) ,
CoreEpiphanyReorientAction ::Regather = > prompts . regather . as_str ( ) ,
} ;
epiphany_worker_prompt ( body )
}
pub fn build_epiphany_job_launch_request (
expected_revision : Option < u64 > ,
binding_id : String ,
kind : CoreEpiphanyJobKind ,
scope : String ,
owner_role : String ,
authority_scope : String ,
linked_subgoal_ids : Vec < String > ,
linked_graph_node_ids : Vec < String > ,
instruction : String ,
launch_document : EpiphanyWorkerLaunchDocument ,
output_contract_id : String ,
max_runtime_seconds : Option < u64 > ,
) -> EpiphanyJobLaunchRequest {
let organ_launch_contract = default_launch_organ_contract (
& authority_scope ,
launch_document . document_kind ( ) ,
& output_contract_id ,
) ;
EpiphanyJobLaunchRequest {
expected_revision ,
binding_id ,
kind ,
scope ,
owner_role ,
authority_scope ,
linked_subgoal_ids ,
linked_graph_node_ids ,
instruction ,
launch_document ,
output_contract_id ,
organ_launch_contract ,
max_runtime_seconds ,
2026-07-14 01:03:54 +01:00
proposal_modeling_request_id : None ,
2026-07-15 00:11:40 +01:00
claim_repair_request_id : None ,
2026-07-15 01:03:59 +01:00
frontier_planning_request_id : None ,
2026-07-15 03:05:11 +01:00
frontier_plan_mind_request_id : None ,
2026-07-18 20:31:57 +01:00
imagination_consideration_request_id : None ,
2026-05-28 21:02:26 +01:00
}
}
pub fn render_epiphany_coordinator_note (
crrc_action : CoreEpiphanyCrrcAction ,
pressure_level : CoreEpiphanyPressureLevel ,
modeling_result_status : CoreEpiphanyCoordinatorRoleResultStatus ,
verification_result_status : CoreEpiphanyCoordinatorRoleResultStatus ,
reorient_result_status : CoreEpiphanyCrrcResultStatus ,
coordinator_action : CoreEpiphanyCoordinatorAction ,
) -> String {
let template = epiphany_agent_prompt_with_memory (
& epiphany_specialist_prompt_config ( )
. coordinator
. note_template ,
) ;
template
. trim ( )
. replace ( " {crrc_action} " , & format! ( " {crrc_action:?} " ) )
. replace ( " {pressure_level} " , & format! ( " {pressure_level:?} " ) )
. replace (
" {modeling_result_status} " ,
& format! ( " {modeling_result_status:?} " ) ,
)
. replace (
" {verification_result_status} " ,
& format! ( " {verification_result_status:?} " ) ,
)
. replace (
" {reorient_result_status} " ,
& format! ( " {reorient_result_status:?} " ) ,
)
. replace ( " {coordinator_action} " , & format! ( " {coordinator_action:?} " ) )
}
pub fn render_epiphany_pre_compaction_checkpoint_intervention (
pressure : & EpiphanyPressure ,
) -> String {
let usage = match (
pressure . used_tokens ,
pressure . remaining_tokens ,
pressure . ratio_per_mille ,
) {
( Some ( used ) , Some ( remaining ) , Some ( ratio ) ) = > format! (
" {used} tokens used, {remaining} remaining, {}.{}% of the selected limit " ,
ratio / 10 ,
ratio % 10
) ,
( Some ( used ) , _ , _ ) = > format! ( " {used} tokens used " ) ,
_ = > " token usage known only as a pressure threshold crossing " . to_string ( ) ,
} ;
let template = epiphany_agent_prompt_with_memory (
& epiphany_specialist_prompt_config ( )
. crrc
. pre_compaction_checkpoint_intervention ,
) ;
template
. trim ( )
. replace (
" {pressure_level} " ,
core_pressure_level_label ( pressure . level ) ,
)
. replace ( " {usage} " , & usage )
}
fn core_pressure_level_label ( level : CoreEpiphanyPressureLevel ) -> & 'static str {
match level {
CoreEpiphanyPressureLevel ::Unknown = > " unknown " ,
CoreEpiphanyPressureLevel ::Low = > " low " ,
CoreEpiphanyPressureLevel ::Elevated = > " elevated " ,
CoreEpiphanyPressureLevel ::High = > " high " ,
CoreEpiphanyPressureLevel ::Critical = > " critical " ,
}
}
pub fn unique_strings ( values : impl IntoIterator < Item = String > ) -> Vec < String > {
let mut unique = Vec ::new ( ) ;
extend_unique_strings ( & mut unique , values ) ;
unique
}
fn extend_unique_strings ( target : & mut Vec < String > , values : impl IntoIterator < Item = String > ) {
for value in values {
if ! target . iter ( ) . any ( | existing | existing = = & value ) {
target . push ( value ) ;
}
}
}
fn epiphany_active_subgoal_ids ( state : Option < & EpiphanyThreadState > ) -> Vec < String > {
state
. and_then ( | state | state . active_subgoal_id . clone ( ) )
. map ( | id | vec! [ id ] )
. unwrap_or_default ( )
}
fn epiphany_active_graph_node_ids ( state : Option < & EpiphanyThreadState > ) -> Vec < String > {
state
. and_then ( | state | state . graph_frontier . as_ref ( ) )
. map ( | frontier | frontier . active_node_ids . clone ( ) )
. unwrap_or_default ( )
}
#[ cfg(test) ]
mod tests {
use super ::* ;
2026-07-12 00:41:05 +01:00
#[ test ]
fn live_worker_contracts_contain_no_codex_route_vocabulary ( ) {
let source = include_str! ( " agent_launch.rs " ) ;
let production = source . split ( " #[cfg(test)] " ) . next ( ) . unwrap_or ( source ) ;
assert! ( ! production . contains ( " thread/epiphany/ " ) ) ;
assert! ( production . contains ( " epiphany.coordinator.reorient.launch " ) ) ;
assert! ( production . contains ( " statePatch for Mind admission " ) ) ;
}
2026-05-28 21:02:26 +01:00
#[ test ]
fn bundled_epiphany_agent_prompts_do_not_name_codex_as_prompt_authority ( ) {
let prompts = epiphany_specialist_prompt_config ( ) ;
let rendered = [
(
" shared.persistent_memory " ,
prompts . shared . persistent_memory . as_str ( ) ,
) ,
( " roles.imagination " , prompts . roles . imagination . as_str ( ) ) ,
2026-07-15 03:05:11 +01:00
( " roles.mind " , prompts . roles . mind . as_str ( ) ) ,
2026-05-28 21:02:26 +01:00
( " roles.modeling " , prompts . roles . modeling . as_str ( ) ) ,
( " roles.verification " , prompts . roles . verification . as_str ( ) ) ,
( " roles.research " , prompts . roles . research . as_str ( ) ) ,
(
" roles.repo_personality " ,
prompts . roles . repo_personality . as_str ( ) ,
) ,
( " roles.repo_memory " , prompts . roles . repo_memory . as_str ( ) ) ,
2026-06-15 16:38:09 +01:00
( " roles.persona " , prompts . roles . persona . as_str ( ) ) ,
2026-05-28 21:02:26 +01:00
(
" implementation.continue_template " ,
prompts . implementation . continue_template . as_str ( ) ,
) ,
(
" reorientation.resume " ,
prompts . reorientation . resume . as_str ( ) ,
) ,
(
" reorientation.regather " ,
prompts . reorientation . regather . as_str ( ) ,
) ,
(
" coordinator.note_template " ,
prompts . coordinator . note_template . as_str ( ) ,
) ,
(
" crrc.pre_compaction_checkpoint_intervention " ,
prompts . crrc . pre_compaction_checkpoint_intervention . as_str ( ) ,
) ,
] ;
for ( name , prompt ) in rendered {
assert! (
! prompt . contains ( " Codex " ) ,
" {name} must stay Epiphany-owned and Codex-free "
) ;
}
}
#[ test ]
fn role_worker_prompt_is_bounded_not_full_persistent_memory ( ) {
let prompt = build_epiphany_role_launch_instruction ( EpiphanyRoleResultRoleId ::Modeling ) ;
assert! ( prompt . contains ( " Epiphany Worker Boundary " ) ) ;
assert! ( prompt . contains ( " Act as the Epiphany modeling/checkpoint specialist " ) ) ;
2026-07-16 16:49:45 +01:00
assert! ( prompt . contains ( " node `kind` is a closed vocabulary " ) ) ;
2026-05-28 21:02:26 +01:00
assert! ( ! prompt . contains ( " ## Epiphany Persistent Memory " ) ) ;
assert! ( ! prompt . contains ( " Heartbeat: every lane " ) ) ;
}
2026-07-15 03:05:11 +01:00
#[ test ]
fn frontier_plan_mind_launch_is_a_real_prompted_role_with_strict_schema ( ) {
let request = build_epiphany_frontier_plan_mind_launch_request (
" thread-mind " ,
Some ( 0 ) ,
Some ( 60 ) ,
& EpiphanyThreadState ::default ( ) ,
" mind-request-1 " . into ( ) ,
)
. expect ( " Mind launch request " ) ;
assert_eq! ( request . owner_role , EPIPHANY_MIND_OWNER_ROLE ) ;
assert_eq! ( request . binding_id , EPIPHANY_MIND_ROLE_BINDING_ID ) ;
assert! (
request
. instruction
. contains ( " admission-review procedure serving Epiphany Mind " )
) ;
assert_eq! (
request . frontier_plan_mind_request_id . as_deref ( ) ,
Some ( " mind-request-1 " )
) ;
let EpiphanyWorkerLaunchDocument ::Role ( document ) = request . launch_document else {
panic! ( " Mind must use a role launch document " )
} ;
assert_eq! ( document . role_id , " mindAdmissionReview " ) ;
let schema = epiphany_frontier_plan_mind_output_schema ( ) ;
assert_eq! (
schema [ " properties " ] [ " roleId " ] [ " const " ] ,
" mindAdmissionReview "
) ;
assert_eq! (
schema [ " properties " ] [ " frontierPlanMindDecision " ] [ " properties " ] [ " decision " ] [ " enum " ] ,
serde_json ::json! ( [ " adopt " , " refuse " , " hold " ] )
) ;
}
2026-07-13 22:29:10 +01:00
#[ test ]
2026-07-15 00:43:05 +01:00
fn modeling_schema_exposes_only_typed_authority_purposes ( ) {
2026-07-13 22:29:10 +01:00
let schema = epiphany_role_launch_output_schema ( EpiphanyRoleResultRoleId ::Modeling ) ;
2026-07-15 22:06:06 +01:00
assert! (
schema [ " required " ]
. as_array ( )
. unwrap ( )
. iter ( )
. any ( | value | value = = " repositoryBodyObservationBasis " )
) ;
assert_eq! (
schema [ " properties " ] [ " repositoryBodyObservationBasis " ] [ " additionalProperties " ] ,
false
) ;
2026-07-13 22:29:10 +01:00
let purposes = schema [ " properties " ] [ " repoModelPatch " ] [ " properties " ] [ " purpose " ] [ " oneOf " ]
. as_array ( )
. expect ( " typed Modeling purpose alternatives " ) ;
2026-07-16 16:49:45 +01:00
assert_eq! ( purposes . len ( ) , 4 ) ;
2026-07-13 22:29:10 +01:00
assert_eq! ( purposes [ 0 ] [ " properties " ] [ " kind " ] [ " const " ] , " evolution " ) ;
assert_eq! (
purposes [ 1 ] [ " properties " ] [ " kind " ] [ " const " ] ,
" incorporate_frontier_verdict "
) ;
assert! (
purposes [ 1 ] [ " required " ]
. as_array ( )
. unwrap ( )
. iter ( )
. any ( | value | value = = " route_id " )
) ;
assert_eq! (
schema [ " allOf " ] [ 0 ] [ " then " ] [ " required " ] [ 0 ] ,
" repoFrontierModelingRequestId "
) ;
2026-07-15 00:43:05 +01:00
assert_eq! ( purposes [ 2 ] [ " properties " ] [ " kind " ] [ " const " ] , " repair_claim " ) ;
2026-07-16 16:49:45 +01:00
assert_eq! (
purposes [ 3 ] [ " properties " ] [ " kind " ] [ " const " ] ,
" adopt_frontier_plan "
) ;
2026-07-15 00:43:05 +01:00
assert_eq! (
schema [ " allOf " ] [ 1 ] [ " then " ] [ " required " ] [ 0 ] ,
" claimRepairRequestId "
) ;
2026-07-16 16:49:45 +01:00
let operations =
schema [ " properties " ] [ " repoModelPatch " ] [ " properties " ] [ " operations " ] [ " items " ] [ " anyOf " ]
. as_array ( )
. expect ( " typed Modeling operations " ) ;
let node_kinds = operations [ 0 ] [ " properties " ] [ " node " ] [ " properties " ] [ " kind " ] [ " enum " ]
. as_array ( )
. expect ( " typed RepoModel node kinds " ) ;
assert! ( node_kinds . iter ( ) . any ( | kind | kind = = " runtime_contract " ) ) ;
assert! ( ! node_kinds . iter ( ) . any ( | kind | kind = = " claim " ) ) ;
2026-07-13 22:29:10 +01:00
}
2026-07-15 01:29:35 +01:00
#[ test ]
fn frontier_planning_schema_exposes_candidate_without_generic_patch_mouths ( ) {
let schema = epiphany_frontier_planning_output_schema ( ) ;
assert! (
schema [ " properties " ]
. get ( " frontierPlanningRequestId " )
. is_some ( )
) ;
assert! ( schema [ " properties " ] . get ( " frontierPlanCandidate " ) . is_some ( ) ) ;
assert! ( schema [ " properties " ] . get ( " statePatch " ) . is_none ( ) ) ;
assert! ( schema [ " properties " ] . get ( " selfPatch " ) . is_none ( ) ) ;
assert! ( schema [ " properties " ] . get ( " repoModelPatch " ) . is_none ( ) ) ;
assert_eq! ( schema [ " additionalProperties " ] , false ) ;
}
2026-07-18 20:31:57 +01:00
#[ test ]
fn consideration_schema_has_only_proposal_candidate_cargo ( ) {
let schema = epiphany_imagination_consideration_output_schema ( ) ;
assert! (
schema [ " properties " ]
. get ( " imaginationConsiderationRequestId " )
. is_some ( )
) ;
assert! (
schema [ " properties " ]
. get ( " imaginationConsiderationCandidate " )
. is_some ( )
) ;
for forbidden in [
" statePatch " ,
" selfPatch " ,
" repoModelPatch " ,
" frontierPlanCandidate " ,
] {
assert! ( schema [ " properties " ] . get ( forbidden ) . is_none ( ) ) ;
}
assert_eq! ( schema [ " additionalProperties " ] , false ) ;
}
2026-05-28 21:02:26 +01:00
#[ test ]
fn reorient_worker_prompt_is_bounded_not_full_persistent_memory ( ) {
let prompt = build_epiphany_reorient_launch_instruction ( CoreEpiphanyReorientAction ::Resume ) ;
assert! ( prompt . contains ( " Epiphany Worker Boundary " ) ) ;
assert! ( ! prompt . contains ( " ## Epiphany Persistent Memory " ) ) ;
assert! ( ! prompt . contains ( " Heartbeat: every lane " ) ) ;
}
}