Require Proprioception map admission
This commit is contained in:
parent
ce20529ee7
commit
712d67bf96
10 changed files with 161 additions and 17 deletions
|
|
@ -184,6 +184,7 @@ pub async fn derive_epiphany_coordinator_status(
|
|||
modeling_result_requests_regather: finding_signals.modeling_result_requests_regather,
|
||||
modeling_result_accepted: finding_signals.modeling_result_accepted,
|
||||
modeling_result_reviewable: finding_signals.modeling_result_reviewable,
|
||||
modeling_result_failure_reviewed: finding_signals.modeling_result_failure_reviewed,
|
||||
modeling_result_accepted_after_verification: finding_signals
|
||||
.modeling_result_accepted_after_verification,
|
||||
implementation_evidence_after_verification: finding_signals
|
||||
|
|
|
|||
|
|
@ -419,8 +419,9 @@ fn run_coordinator(args: &Args) -> Result<Value> {
|
|||
steps.push(step);
|
||||
break;
|
||||
}
|
||||
if result["status"].as_str() == Some("failed") && args.supersede_failed_results {
|
||||
let superseded = supersede_failed_role_result(
|
||||
if args.supersede_failed_results && role_result_needs_supersession(role_id, &result)
|
||||
{
|
||||
let superseded = supersede_role_result(
|
||||
&mut client,
|
||||
&thread_id,
|
||||
role_id,
|
||||
|
|
@ -1107,7 +1108,17 @@ fn role_result_auto_acceptable(role_id: &str, result: &Value) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn supersede_failed_role_result(
|
||||
fn role_result_needs_supersession(role_id: &str, result: &Value) -> bool {
|
||||
match result["status"].as_str() {
|
||||
Some("failed") => true,
|
||||
Some("completed") if matches!(role_id, "research" | "modeling" | "imagination") => {
|
||||
!role_result_auto_acceptable(role_id, result)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn supersede_role_result(
|
||||
client: &mut status_cli::AppServerClient,
|
||||
thread_id: &str,
|
||||
role_id: &str,
|
||||
|
|
@ -1121,7 +1132,7 @@ fn supersede_failed_role_result(
|
|||
let binding_id = first_string_at(result, &[&["bindingId"]])
|
||||
.unwrap_or_else(|| default_binding_id_for_role(role_id));
|
||||
let summary = first_string_at(result, &[&["finding", "summary"], &["note"]])
|
||||
.unwrap_or_else(|| "Failed role result reviewed and superseded.".to_string());
|
||||
.unwrap_or_else(|| "Role result reviewed and superseded.".to_string());
|
||||
let receipt = json!({
|
||||
"id": format!("role-failure-review-{}", Uuid::new_v4()),
|
||||
"result_id": result_id,
|
||||
|
|
@ -1792,6 +1803,37 @@ mod tests {
|
|||
assert!(!role_result_auto_acceptable("modeling", &errored));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn supersession_includes_unreviewable_modeling_results() {
|
||||
let unreviewable = json!({
|
||||
"status": "completed",
|
||||
"finding": {
|
||||
"verdict": "checkpoint-update-needed",
|
||||
"summary": "Mapped in prose only.",
|
||||
"runtimeResultId": "result-modeling-1",
|
||||
"runtimeJobId": "job-modeling-1",
|
||||
"itemError": "modeling result is not reviewable: missing required statePatch"
|
||||
}
|
||||
});
|
||||
let reviewable = json!({
|
||||
"status": "completed",
|
||||
"finding": {
|
||||
"verdict": "checkpoint-update-needed",
|
||||
"summary": "Mapped with state.",
|
||||
"runtimeResultId": "result-modeling-2",
|
||||
"runtimeJobId": "job-modeling-2",
|
||||
"statePatch": {"scratch": {"summary": "mapped"}}
|
||||
}
|
||||
});
|
||||
|
||||
assert!(role_result_needs_supersession("modeling", &unreviewable));
|
||||
assert!(!role_result_needs_supersession("modeling", &reviewable));
|
||||
assert!(!role_result_needs_supersession(
|
||||
"verification",
|
||||
&unreviewable
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn implementation_requested_paths_use_checkpoint_and_frontier_scope() {
|
||||
let status = json!({
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ use epiphany_core::EpiphanyReorientAction;
|
|||
use epiphany_core::EpiphanyReorientFreshnessStatus;
|
||||
use epiphany_core::EpiphanyReorientInput;
|
||||
use epiphany_core::EpiphanyReorientPressureLevel;
|
||||
use epiphany_core::EpiphanyRoleFindingInterpretation;
|
||||
use epiphany_core::EpiphanyRoleResultRoleId;
|
||||
use epiphany_core::EpiphanyRetrievalFreshnessStatus;
|
||||
use epiphany_core::EpiphanyRoleBoardCheckpointSummary;
|
||||
use epiphany_core::EpiphanyRoleBoardInput;
|
||||
use epiphany_core::EpiphanyRoleBoardJob;
|
||||
use epiphany_core::EpiphanyRoleBoardJobStatus;
|
||||
use epiphany_core::EpiphanyRoleBoardPlanningSummary;
|
||||
use epiphany_core::EpiphanyRoleFindingInterpretation;
|
||||
use epiphany_core::EpiphanyRoleResultRoleId;
|
||||
use epiphany_core::EpiphanyRuntimeJobSnapshot;
|
||||
use epiphany_core::EpiphanyRuntimeJobStatus;
|
||||
use epiphany_core::EpiphanySceneInput;
|
||||
|
|
@ -431,6 +431,7 @@ fn run_native_status(args: &Args) -> Result<Value> {
|
|||
modeling_result_requests_regather: finding_signals.modeling_result_requests_regather,
|
||||
modeling_result_accepted: finding_signals.modeling_result_accepted,
|
||||
modeling_result_reviewable: finding_signals.modeling_result_reviewable,
|
||||
modeling_result_failure_reviewed: finding_signals.modeling_result_failure_reviewed,
|
||||
modeling_result_accepted_after_verification: finding_signals
|
||||
.modeling_result_accepted_after_verification,
|
||||
implementation_evidence_after_verification: finding_signals
|
||||
|
|
@ -898,9 +899,7 @@ fn reorient_retrieval_status(
|
|||
) -> EpiphanyReorientFreshnessStatus {
|
||||
match status {
|
||||
EpiphanyRetrievalFreshnessStatus::Missing
|
||||
| EpiphanyRetrievalFreshnessStatus::Unavailable => {
|
||||
EpiphanyReorientFreshnessStatus::Unknown
|
||||
}
|
||||
| EpiphanyRetrievalFreshnessStatus::Unavailable => EpiphanyReorientFreshnessStatus::Unknown,
|
||||
EpiphanyRetrievalFreshnessStatus::Ready => EpiphanyReorientFreshnessStatus::Clean,
|
||||
EpiphanyRetrievalFreshnessStatus::Stale => EpiphanyReorientFreshnessStatus::Stale,
|
||||
EpiphanyRetrievalFreshnessStatus::Indexing => EpiphanyReorientFreshnessStatus::Dirty,
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ pub struct EpiphanyCoordinatorInput {
|
|||
pub modeling_result_requests_regather: bool,
|
||||
pub modeling_result_accepted: bool,
|
||||
pub modeling_result_reviewable: bool,
|
||||
pub modeling_result_failure_reviewed: bool,
|
||||
pub modeling_result_accepted_after_verification: bool,
|
||||
pub implementation_evidence_after_verification: bool,
|
||||
pub verification_result_cites_implementation_evidence: bool,
|
||||
|
|
@ -175,6 +176,7 @@ pub struct EpiphanyCoordinatorStatusInput {
|
|||
pub modeling_result_requests_regather: bool,
|
||||
pub modeling_result_accepted: bool,
|
||||
pub modeling_result_reviewable: bool,
|
||||
pub modeling_result_failure_reviewed: bool,
|
||||
pub modeling_result_accepted_after_verification: bool,
|
||||
pub implementation_evidence_after_verification: bool,
|
||||
pub verification_result_cites_implementation_evidence: bool,
|
||||
|
|
@ -201,6 +203,7 @@ pub struct EpiphanyCoordinatorFindingSignals {
|
|||
pub modeling_result_requests_regather: bool,
|
||||
pub modeling_result_accepted: bool,
|
||||
pub modeling_result_reviewable: bool,
|
||||
pub modeling_result_failure_reviewed: bool,
|
||||
pub modeling_result_accepted_after_verification: bool,
|
||||
pub implementation_evidence_after_verification: bool,
|
||||
pub verification_result_cites_implementation_evidence: bool,
|
||||
|
|
@ -264,6 +267,7 @@ pub fn derive_coordinator_status(
|
|||
modeling_result_requests_regather: input.modeling_result_requests_regather,
|
||||
modeling_result_accepted: input.modeling_result_accepted,
|
||||
modeling_result_reviewable: input.modeling_result_reviewable,
|
||||
modeling_result_failure_reviewed: input.modeling_result_failure_reviewed,
|
||||
modeling_result_accepted_after_verification: input
|
||||
.modeling_result_accepted_after_verification,
|
||||
implementation_evidence_after_verification: input
|
||||
|
|
@ -308,6 +312,11 @@ pub fn derive_coordinator_finding_signals(
|
|||
modeling_finding.is_some_and(modeling_finding_has_reviewable_state_patch);
|
||||
let modeling_result_requests_regather =
|
||||
modeling_finding.is_some_and(modeling_finding_requests_regather);
|
||||
let modeling_result_failure_reviewed = modeling_finding.as_ref().is_some_and(|finding| {
|
||||
state.is_some_and(|state| {
|
||||
role_finding_failure_reviewed(state, EpiphanyCoordinatorRoleId::Modeling, finding)
|
||||
})
|
||||
});
|
||||
let verification_result_accepted = verification_finding.as_ref().is_some_and(|finding| {
|
||||
state.is_some_and(|state| {
|
||||
role_finding_already_accepted(state, EpiphanyCoordinatorRoleId::Verification, finding)
|
||||
|
|
@ -364,6 +373,7 @@ pub fn derive_coordinator_finding_signals(
|
|||
modeling_result_requests_regather,
|
||||
modeling_result_accepted,
|
||||
modeling_result_reviewable,
|
||||
modeling_result_failure_reviewed,
|
||||
modeling_result_accepted_after_verification,
|
||||
implementation_evidence_after_verification,
|
||||
verification_result_cites_implementation_evidence,
|
||||
|
|
@ -775,6 +785,16 @@ pub fn recommend_coordinator_action(
|
|||
&& !input.modeling_result_accepted
|
||||
{
|
||||
if !input.modeling_result_reviewable {
|
||||
if input.modeling_result_failure_reviewed {
|
||||
return build(
|
||||
EpiphanyCoordinatorAction::LaunchModeling,
|
||||
Some(EpiphanyCoordinatorRoleId::Modeling),
|
||||
Some(EpiphanyCoordinatorSceneAction::RoleLaunch),
|
||||
false,
|
||||
true,
|
||||
"The completed modeling/checkpoint result was reviewed as unreviewable and superseded; relaunch Proprioception so it can emit the required statePatch before Hands continues.",
|
||||
);
|
||||
}
|
||||
if input.modeling_result_requests_regather
|
||||
&& !input.research_result_accepted
|
||||
&& matches!(
|
||||
|
|
@ -817,6 +837,16 @@ pub fn recommend_coordinator_action(
|
|||
if input.signals.modeling_result_status == EpiphanyCoordinatorRoleResultStatus::Failed
|
||||
&& !input.modeling_result_accepted
|
||||
{
|
||||
if input.modeling_result_failure_reviewed {
|
||||
return build(
|
||||
EpiphanyCoordinatorAction::LaunchModeling,
|
||||
Some(EpiphanyCoordinatorRoleId::Modeling),
|
||||
Some(EpiphanyCoordinatorSceneAction::RoleLaunch),
|
||||
false,
|
||||
true,
|
||||
"The failed modeling/checkpoint result was reviewed and superseded; relaunch Proprioception before verification or implementation continues.",
|
||||
);
|
||||
}
|
||||
return build(
|
||||
EpiphanyCoordinatorAction::ReviewModelingResult,
|
||||
Some(EpiphanyCoordinatorRoleId::Modeling),
|
||||
|
|
@ -1212,6 +1242,7 @@ mod tests {
|
|||
modeling_result_requests_regather: false,
|
||||
modeling_result_accepted: false,
|
||||
modeling_result_reviewable: false,
|
||||
modeling_result_failure_reviewed: false,
|
||||
modeling_result_accepted_after_verification: false,
|
||||
implementation_evidence_after_verification: false,
|
||||
verification_result_cites_implementation_evidence: false,
|
||||
|
|
@ -1609,6 +1640,22 @@ mod tests {
|
|||
);
|
||||
assert!(!review_unreviewable_modeling.can_auto_run);
|
||||
|
||||
let relaunch_superseded_modeling = recommend_coordinator_action(EpiphanyCoordinatorInput {
|
||||
signals: EpiphanyCoordinatorSignals {
|
||||
research_result_status: EpiphanyCoordinatorRoleResultStatus::MissingBinding,
|
||||
modeling_result_status: EpiphanyCoordinatorRoleResultStatus::Completed,
|
||||
verification_result_status: EpiphanyCoordinatorRoleResultStatus::MissingBinding,
|
||||
},
|
||||
modeling_result_failure_reviewed: true,
|
||||
..input()
|
||||
});
|
||||
assert_eq!(
|
||||
relaunch_superseded_modeling.action,
|
||||
EpiphanyCoordinatorAction::LaunchModeling
|
||||
);
|
||||
assert!(relaunch_superseded_modeling.can_auto_run);
|
||||
assert!(relaunch_superseded_modeling.reason.contains("statePatch"));
|
||||
|
||||
let launch_verification = recommend_coordinator_action(EpiphanyCoordinatorInput {
|
||||
signals: EpiphanyCoordinatorSignals {
|
||||
research_result_status: EpiphanyCoordinatorRoleResultStatus::MissingBinding,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ pub struct EpiphanyModelRequest {
|
|||
pub previous_response_id: Option<String>,
|
||||
#[cultcache(key = 12, default)]
|
||||
pub tools: Vec<EpiphanyModelToolDefinition>,
|
||||
#[cultcache(key = 13, default)]
|
||||
pub output_schema_json: Option<String>,
|
||||
}
|
||||
|
||||
impl EpiphanyModelRequest {
|
||||
|
|
@ -80,6 +82,7 @@ impl EpiphanyModelRequest {
|
|||
output_contract_id: None,
|
||||
previous_response_id: None,
|
||||
tools: Vec::new(),
|
||||
output_schema_json: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ pub struct EpiphanyOpenAiModelRequest {
|
|||
pub previous_response_id: Option<String>,
|
||||
#[cultcache(key = 11, default)]
|
||||
pub tools: Vec<EpiphanyOpenAiToolDefinition>,
|
||||
#[cultcache(key = 12, default)]
|
||||
pub output_schema_json: Option<String>,
|
||||
}
|
||||
|
||||
impl EpiphanyOpenAiModelRequest {
|
||||
|
|
@ -91,6 +93,7 @@ impl EpiphanyOpenAiModelRequest {
|
|||
output_contract_id: None,
|
||||
previous_response_id: None,
|
||||
tools: Vec::new(),
|
||||
output_schema_json: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -560,6 +560,7 @@ pub fn build_worker_model_request(
|
|||
model: &str,
|
||||
) -> Result<EpiphanyModelRequest> {
|
||||
let launch_document = launch_request.launch_document()?;
|
||||
let output_schema_json = worker_output_schema_json(&launch_document)?;
|
||||
let request_id = format!(
|
||||
"worker-{}-{}",
|
||||
sanitize_request_id(&launch_request.job_id),
|
||||
|
|
@ -567,7 +568,8 @@ pub fn build_worker_model_request(
|
|||
);
|
||||
let launch_document_text = serde_json::to_string_pretty(&launch_document)
|
||||
.context("failed to render worker launch document for model input")?;
|
||||
let mut instructions = worker_instructions(launch_request, &launch_document);
|
||||
let mut instructions =
|
||||
worker_instructions(launch_request, &launch_document, &output_schema_json);
|
||||
if launch_request.binding_id == epiphany_core::EPIPHANY_VERIFICATION_ROLE_BINDING_ID {
|
||||
instructions.push_str("\n\nTool mandate: before returning `needs-evidence` because source files, command artifacts, commit diffs, or Hands receipt bodies are not inspectable, call the read-only source tools available on this request. Use `mcp__epiphany_source__read_file` for cited source/artifact paths, `mcp__epiphany_source__git_show` for commit diffs, and `mcp__epiphany_source__read_hands_receipt` for Hands patch/command/commit receipts. If a tool fails, cite that failed tool result and the exact remaining blocker.");
|
||||
}
|
||||
|
|
@ -586,6 +588,7 @@ pub fn build_worker_model_request(
|
|||
request.reasoning_effort = Some("low".to_string());
|
||||
request.reasoning_summary = Some("concise".to_string());
|
||||
request.output_contract_id = Some(launch_request.output_contract_id.clone());
|
||||
request.output_schema_json = Some(output_schema_json);
|
||||
if launch_request.binding_id == epiphany_core::EPIPHANY_VERIFICATION_ROLE_BINDING_ID {
|
||||
request.tools = verification_source_tools();
|
||||
}
|
||||
|
|
@ -986,6 +989,7 @@ pub fn model_request_from_openai_request(
|
|||
service_tier: request.service_tier.clone(),
|
||||
output_contract_id: request.output_contract_id.clone(),
|
||||
previous_response_id: request.previous_response_id.clone(),
|
||||
output_schema_json: request.output_schema_json.clone(),
|
||||
tools: request
|
||||
.tools
|
||||
.iter()
|
||||
|
|
@ -1017,6 +1021,7 @@ pub fn openai_request_from_model_request(
|
|||
service_tier: request.service_tier.clone(),
|
||||
output_contract_id: request.output_contract_id.clone(),
|
||||
previous_response_id: request.previous_response_id.clone(),
|
||||
output_schema_json: request.output_schema_json.clone(),
|
||||
tools: request
|
||||
.tools
|
||||
.iter()
|
||||
|
|
@ -1275,6 +1280,7 @@ fn provider_matches_request(selected: &str, requested: &str) -> bool {
|
|||
fn worker_instructions(
|
||||
launch_request: &EpiphanyRuntimeWorkerLaunchRequest,
|
||||
launch_document: &EpiphanyWorkerLaunchDocument,
|
||||
output_schema_json: &str,
|
||||
) -> String {
|
||||
let output_contract = worker_output_contract_text(launch_document);
|
||||
let dynamic_context = launch_document
|
||||
|
|
@ -1282,11 +1288,39 @@ fn worker_instructions(
|
|||
.map(|context| format!("\n\n{context}"))
|
||||
.unwrap_or_default();
|
||||
format!(
|
||||
"{}{}\n\nReturn only one JSON object. No Markdown, no commentary.\n\n{}",
|
||||
launch_request.instruction, dynamic_context, output_contract
|
||||
"{}{}\n\nReturn only one JSON object. No Markdown, no commentary.\n\n{}\n\nOutput schema JSON:\n```json\n{}\n```",
|
||||
launch_request.instruction, dynamic_context, output_contract, output_schema_json
|
||||
)
|
||||
}
|
||||
|
||||
fn worker_output_schema_json(document: &EpiphanyWorkerLaunchDocument) -> Result<String> {
|
||||
let schema = match document {
|
||||
EpiphanyWorkerLaunchDocument::Role(document) => {
|
||||
let role_id = role_result_id_for_launch_role(&document.role_id)
|
||||
.with_context(|| format!("unknown role launch id {:?}", document.role_id))?;
|
||||
epiphany_core::epiphany_role_launch_output_schema(role_id)
|
||||
}
|
||||
EpiphanyWorkerLaunchDocument::Reorient(_) => {
|
||||
epiphany_core::epiphany_reorient_launch_output_schema()
|
||||
}
|
||||
};
|
||||
serde_json::to_string_pretty(&schema).context("failed to render worker output schema")
|
||||
}
|
||||
|
||||
fn role_result_id_for_launch_role(
|
||||
role_id: &str,
|
||||
) -> Option<epiphany_core::EpiphanyRoleResultRoleId> {
|
||||
match role_id {
|
||||
"imagination" => Some(epiphany_core::EpiphanyRoleResultRoleId::Imagination),
|
||||
"research" => Some(epiphany_core::EpiphanyRoleResultRoleId::Research),
|
||||
"modeling" => Some(epiphany_core::EpiphanyRoleResultRoleId::Modeling),
|
||||
"verification" => Some(epiphany_core::EpiphanyRoleResultRoleId::Verification),
|
||||
"implementation" => Some(epiphany_core::EpiphanyRoleResultRoleId::Implementation),
|
||||
"reorientation" => Some(epiphany_core::EpiphanyRoleResultRoleId::Reorientation),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn worker_output_contract_text(document: &EpiphanyWorkerLaunchDocument) -> &'static str {
|
||||
match document {
|
||||
EpiphanyWorkerLaunchDocument::Role(_) => {
|
||||
|
|
@ -1754,6 +1788,14 @@ mod tests {
|
|||
model_request.output_contract_id.as_deref(),
|
||||
Some(epiphany_core::ROLE_WORKER_OUTPUT_CONTRACT_ID)
|
||||
);
|
||||
let output_schema = model_request
|
||||
.output_schema_json
|
||||
.as_deref()
|
||||
.expect("worker model request should carry role output schema");
|
||||
assert!(output_schema.contains("\"statePatch\""));
|
||||
assert!(output_schema.contains("\"frontierNodeIds\""));
|
||||
assert!(model_request.instructions.contains("Output schema JSON"));
|
||||
assert!(model_request.instructions.contains("\"statePatch\""));
|
||||
assert_eq!(model_request.reasoning_effort.as_deref(), Some("low"));
|
||||
assert_eq!(model_request.reasoning_summary.as_deref(), Some("concise"));
|
||||
assert!(
|
||||
|
|
@ -1914,12 +1956,14 @@ mod tests {
|
|||
fn builds_tool_followup_model_request_from_receipts() -> Result<()> {
|
||||
let temp = tempdir()?;
|
||||
let store = temp.path().join("runtime.msgpack");
|
||||
let request = EpiphanyOpenAiModelRequest::new(
|
||||
let mut request = EpiphanyOpenAiModelRequest::new(
|
||||
"req-tools",
|
||||
"conversation-1",
|
||||
"gpt-5.4",
|
||||
"Answer after tool output.",
|
||||
);
|
||||
request.output_schema_json =
|
||||
Some(r#"{"type":"object","required":["statePatch"]}"#.to_string());
|
||||
let options = default_options(store.clone(), PathBuf::from(".codex"), &request);
|
||||
ensure_openai_runtime_ready(&options)?;
|
||||
ensure_runtime_session(
|
||||
|
|
@ -1990,6 +2034,10 @@ mod tests {
|
|||
build_tool_followup_model_request(&store, "req-tools", "req-tools-followup")?;
|
||||
assert_eq!(followup.request_id, "req-tools-followup");
|
||||
assert_eq!(followup.previous_response_id, None);
|
||||
assert_eq!(
|
||||
followup.output_schema_json.as_deref(),
|
||||
Some(r#"{"type":"object","required":["statePatch"]}"#)
|
||||
);
|
||||
assert_eq!(followup.input.len(), 2);
|
||||
assert_eq!(
|
||||
followup.input[0],
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ remembers doctrine; the branch remembers the blade.
|
|||
- Canonical anatomy now lives in `notes/epiphany-anatomy.md`. Embodied sub-agents are Self, Face, Imagination, Eyes, Proprioception, Hands, and Soul. Body, Mind, Continuity, and Substrate Gate are substrate/state/protocol surfaces, not sub-agent identities. State is split by layer: `work_organ` for resident Epiphany sub-agents, `persona` for portable public/person-shaped state shared by Epiphany Face, VoidBot repo Faces, and Ghostlight characters, and heartbeat/swarm state for scheduling and coordination physiology. Persona state now carries provenance, required public presentation, `date-time` timestamps, typed `candidateActions`, strict anchored thoughts with non-authoritative extensions, custom enum companion labels, and typed affect records for bonds/status reads/doctrine stances.
|
||||
- The repo now has a one-command local operator path: `.\tools\epiphany_local_run.ps1`. Default mode is `smoke`; it builds the retained Codex app-server compatibility edge, builds native Epiphany operator binaries, runs the coordinator smoke, and writes launcher artifacts under `.epiphany-run/` plus coordinator artifacts under `.epiphany-dogfood/`. `-Mode status` is now Epiphany-native: it builds only Epiphany operator binaries, reads `state/thread-state.msgpack` when present, derives status through `epiphany-core`, and does not start or require `codex-app-server`. Use `-Mode plan` or `-Mode run -MaxSteps 4` for the raw bridge-equipped coordinator entrypoints; use `-Mode mvp -FaceInput "<operator request>" -MaxSteps 4` for the local product cycle that projects Face's character turn, writes a Face/Aquarium bubble, bootstraps a minimal local checkpoint for fresh threads, runs the coordinator with auto-tools, then runs heartbeat sleep/dream maintenance. Live plan/run/mvp modes use the workspace `state/runtime-spine.msgpack`, because CodexThread launch writes worker requests there; the run bundle remains artifact evidence, not runtime lifecycle authority. Add `-ThreadId <id>` and `-Workspace <path>` to inspect or continue an existing thread. `status`, `plan`, and `smoke` do not spend model calls; `run` and `mvp` build and use `epiphany-openai-runtime`. Coordinator workers now launch detached and are polled through runtime-spine instead of blocking the coordinator. MVP runs are non-ephemeral by default so `-ThreadId <id>` can resume and poll later. `-MaxRuntimeSeconds <n>` is passed into worker runtime; timeout writes a failed worker receipt and exits. Failed modeling now blocks downstream verification until the failed result is reviewed.
|
||||
- Current Mom-ready status: the normal MVP pass reaches Face -> coordinator -> detached runtime -> heartbeat sleep, and modeling workers now complete through the ChatGPT subscription transport. The first failure was a stack of violated observability/runtime invariants: worker prompts prepended the whole shared persistent-memory rite, Responses frame liveness was invisible until completion, and the runtime tried to persist hundreds of text deltas before completing the worker job. Role/reorient workers now get a compact Epiphany worker boundary instead of full persistent memory; runtime-spine records sampled raw Responses frame kinds with small previews; contiguous reasoning/text deltas compact before durable storage; and live proofs completed `2fe38dcd-d99e-4c73-9a58-afcc81f851c7`, `241e3851-e3ea-4877-a63b-0d2bbd96a7e2`, and `85149a26-6975-403f-ac93-092b717c5825` instead of timing out. The second failure was stale lifecycle authority: completed runtime jobs remained as unresolved `runtime_links`, replacement launches treated historical active links as current, and one bad validation path opened an orphan job before rejecting the state patch. Latest-link-wins is now the runtime-link invariant, terminal links project completed jobs, stale active history cannot veto replacement, launch validation happens before opening runtime jobs, and completed-but-unreviewable modeling findings stop for review instead of relaunching the same lane. The Eyes/source-gather fork is now landed: Research is a fixed Eyes lane with launch/result/accept/status/coordinator/protocol support, and `regather-needed` modeling findings route to `LaunchResearch` instead of relaunching blind Proprioception. Research statePatch admission is Eyes-shaped only: observations, evidence, scratch, and optional investigationCheckpoint; no graph, planning, objective, or checkpoint authority. Mind admission now leaves typed runtime-spine proof: role/reorient acceptance persists `epiphany.mind.gateway_review` before state admission and `epiphany.mind.state_commit_receipt` after admission with the resulting durable revision. Launch contracts now split the broad receipt catalogue from effect-specific proof profiles for state admission, evidence promotion, repo action, verification, and continuity recovery. Research evidence promotion enforces Substrate Gate read/snapshot grant, Eyes evidence packet, and Mind review before state admission; Verification acceptance enforces Soul verdict and Mind review; Reorient acceptance enforces Continuity recovery receipt and Mind review. `epiphany-mvp-coordinator` now records a typed Substrate Gate grant plus Hands intent/review gate when the coordinator selects `continueImplementation`, including a structured `recordPassCommand` template; `epiphany-hands-action` records patch/command/commit receipts against that gate and refuses mismatched, unapproved, or out-of-scope consequences. `epiphany-mvp-coordinator-smoke` now proves the deterministic path: forced `continueImplementation`, gate emission, and `record-pass` receipts in the smoke runtime-spine store. Live run `local-20260612-133920` proved a receipt-only Verification `needs-evidence` finding can be accepted through `roleAccept` and advance to a Hands gate without granting Soul statePatch authority. Runtime-spine now detects and summarizes a complete post-verification Hands patch/command/commit receipt chain so the coordinator can route Soul after Hands. Verification launches now write that chain into the internal CultMesh Verse as `epiphany.cultmesh.work_loop_telemetry.v0` and render a Soul packet from it; Modeling launches read the latest packet, attach accepted Soul receipt ids, and render the Proprioception packet from the same typed state. The telemetry now carries resolved receipt payload previews, stdout/stderr artifact previews, commit diff preview, source proof notes, and verification assertions. The corrected work loop is Hands -> Soul -> Proprioception -> Hands: Soul verifies concrete consequence receipts and changed source, then Proprioception updates the machine model from verified consequence before another implementation turn.
|
||||
- Fresh scar from the receipt proof dogfood: `epiphany-model-runtime run-worker --auto-tools` must preserve Soul's right to follow a real evidence trail, but distinguish it from stalled repetition using typed tool intent fingerprints. Repeated identical pending tool sets seal as `tool-loop-stalled`; exhausting the explicit hard ceiling still seals as `tool-round-limit`. A failed Soul/verification result is a real lane result and must stop for review; once reviewed through a typed `roleFailureReview` supersession receipt, Self may relaunch Soul instead of manually clearing stale state. Complete Hands receipt triplets (`hands-patch-*`, `hands-command-*`, `hands-commit-*`) are implementation evidence for coverage, so Soul does not have to separately cite the accepted Modeling evidence id when it has verified the Hands chain routed to it through the typed work-loop packet. `epiphany-hands-action` must resolve commit receipts through `git rev-parse --verify` before storing them, because an almost-correct SHA poisoned Soul's `git show` proof and made the receipt chain untrustworthy.
|
||||
- Fresh scar from the receipt proof dogfood: `epiphany-model-runtime run-worker --auto-tools` must preserve Soul's right to follow a real evidence trail, but distinguish it from stalled repetition using typed tool intent fingerprints. Repeated identical pending tool sets seal as `tool-loop-stalled`; exhausting the explicit hard ceiling still seals as `tool-round-limit`. A failed or completed-but-unreviewable role result is a real lane result and must stop for review; once reviewed through a typed `roleFailureReview` supersession receipt, Self may relaunch the lane instead of manually clearing stale state. Complete Hands receipt triplets (`hands-patch-*`, `hands-command-*`, `hands-commit-*`) are implementation evidence for coverage, so Soul does not have to separately cite the accepted Modeling evidence id when it has verified the Hands chain routed to it through the typed work-loop packet. Soul accepted the bounded proof for commit `ce20529e`, Proprioception initially completed without a reviewable `statePatch`, and run `local-20260613-204521` proved the repair: the unreviewable result was superseded, Modeling relaunched with the role schema carried in the model request, Mind accepted the map patch, and only then did Self emit a new Hands gate. `epiphany-hands-action` must resolve commit receipts through `git rev-parse --verify` before storing them, because an almost-correct SHA poisoned Soul's `git show` proof and made the receipt chain untrustworthy.
|
||||
- The investment dossier readiness target is now explicit: `E:\Projects\gamecult-site\docs\gamecult_integrated_dossier.tex` expects Epiphany to be part of a Bifrost-first labor loop, not only a local Mom demo. The external proof bar is: Bifrost owns topics/work items/dispatch packets/receipts/credit/reward pressure; Epiphany executes bounded work; maintainers review artifacts; public/operator evidence records scope, consent, roles, model spend, review load, artifacts, accepted/rejected outcome, memory lessons, and case-study permission; and private worker/operator/agent context stays sealed. Diligence also asks for a live fresh-repo Epiphany demo, Bifrost work item/topic/agent transport/receipt/ledger demo, CultMesh status, VoidBot/Discord swarm demo, compute/output metrics, and security model for secrets/write permissions/public-private exports.
|
||||
- This Codex operator's own roadmap/todo posture has been retuned for this scale target, with the Epiphany Imagination specialist as an optional sub-agent rail rather than the whole point. `notes/epiphany-investor-readiness-roadmap.md` now says: make the local Mom MVP a repeatable proof bundle; build the Bifrost-first external-work bridge; add compute/review/accepted-artifact accounting; prove fresh-repo operation without supervisor contamination; keep public/operator-safe exports sealed; and treat angel capital as fuel for capacity, not command authority. The Imagination specialist prompt was also updated so investor-scale Objective Drafts must name Bifrost provenance, bounded Epiphany proof, maintainer review, receipts/ledger evidence, compute/output metrics, public/private export safety, consent, and legal/security gates.
|
||||
- Local operator runs now write typed CultMesh intent/receipt documents to `.epiphany-run/cultmesh/operator-runs.ccmp` through `epiphany-operator-run`. The wrapper writes intent before acting and a completion receipt after success; this is the local consent/trace rail, not a hidden scheduler queue.
|
||||
|
|
@ -189,7 +189,7 @@ remembers doctrine; the branch remembers the blade.
|
|||
- The planning loop is now runtime-backed and operator-visible. Typed captures, backlog items, roadmap streams, Objective Drafts, and GitHub issue source refs live in `EpiphanyThreadState`, validate through revision-gated `thread/epiphany/update`, render into prompts when present, project read-only through the `planning` view lens, render in the GUI Planning panel, can be synthesized by the fixed Imagination/planning lane, and can be explicitly adopted through the artifacted `adoptObjectiveDraft` GUI action. Chat is deliberation, not an objective pipe; ideas and GitHub Issues remain planning state until explicit human adoption.
|
||||
- The bridge/dashboard slice is now landed far enough to test locally. Native `epiphany-rider-bridge` inspects Rider installation, solution, VCS, changed files, and captures file/selection/symbol context into `.epiphany-gui/rider` artifacts; Aquarium has Inspect Rider and renders Rider audit artifacts in Environment; Aquarium also embeds the adjacent EpiphanyGraph viewer over typed `graphs.architecture`, `graphs.dataflow`, and `graphs.links`.
|
||||
- A first Rider plugin scaffold lives under `integrations/rider`: tool window, Refresh status, and Send Context to Epiphany action. It shells through native `epiphany-rider-bridge` and does not own state. `gradle` is not installed on this machine, so the scaffold is not build-verified yet.
|
||||
- Next real move: record the runtime tool-loop proof commit against the fresh Hands gate emitted by `.epiphany-dogfood/local-20260613-122655/coordinator/coordinator-final-action.txt`, then rerun the coordinator so Soul verifies the new Hands receipts. The live coordinator accepted the completed Soul result and generated a `continueImplementation` gate; native status now agrees because it derives freshness through `derive_freshness` and loads typed runtime-spine role findings before deriving coordinator signals. The bounded implementation proof is now in source: `epiphany-openai-runtime` has a testable `ToolLoopGuard`, a shared repeated-loop failure helper, and tests proving nonrepeating trails do not stall while repeated identical tool requests seal the outer worker job. Verification artifacts live under `.epiphany-run/live-hands-pass-20260613-runtime-tool-loop-proof`. Quarantine Rider/Unity bridge work for now; those artifacts remain optional later environment evidence, not MVP blockers. Keep EpiphanyAgent focused on backend contracts, typed state, coordinator policy, heartbeat scheduling, Face guardrails, prompt-authority separation, and the ongoing purification from Python/JSON scaffolding into Rust/CultCache/CultMesh/CultNet organs. Resume repo birth/Aquarium/Rider/Unity work only when the user explicitly shifts priority back outward. GitHub Issues import is deferred until the backlog source is fresh enough to deserve Imagination's attention.
|
||||
- Next real move: use the Hands gate from `.epiphany-dogfood/local-20260613-204521/coordinator/coordinator-summary.json` for one bounded proof of the remaining live runtime seam: the explicit `run_worker --auto-tools` tool-round ceiling must still seal as `tool-round-limit` without reopening the already-verified repeated-identical-tool-loop path. Quarantine Rider/Unity bridge work for now; those artifacts remain optional later environment evidence, not MVP blockers. Keep EpiphanyAgent focused on backend contracts, typed state, coordinator policy, heartbeat scheduling, Face guardrails, prompt-authority separation, and the ongoing purification from Python/JSON scaffolding into Rust/CultCache/CultMesh/CultNet organs. Resume repo birth/Aquarium/Rider/Unity work only when the user explicitly shifts priority back outward. GitHub Issues import is deferred until the backlog source is fresh enough to deserve Imagination's attention.
|
||||
- The repo is an Epiphany fork of Codex, not a Codex preset.
|
||||
- `vendor/codex` is tracked directly, not a submodule.
|
||||
- `epiphany-core` owns the heavy Epiphany organs where practical.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -97,7 +97,8 @@ active_subgoals:
|
|||
- Hands now has a first executable runtime-spine receipt artery: `HandsActionIntent`, `HandsActionReview`, `HandsPatchReceipt`, `HandsCommandReceipt`, and `HandsCommitReceipt` are typed CultCache documents in `epiphany-core::hands_gateway`, runtime-spine registers and persists/rereads them, `epiphany-hands-action-smoke` proves the chain without executing shell commands, editing files, or creating a real commit, and the repo-action launch proof profile now requires the full Hands intent/review/patch chain instead of only the patch receipt. `epiphany-mvp-coordinator` no longer treats `continueImplementation` as a passive stop action: it persists a scoped Substrate Gate grant, Hands action intent, and Hands action review into runtime-spine and exposes the receipt ids in the operator step. The gate also carries a structured `recordPassCommand` template for the post-edit/check/commit receipt call. `epiphany-hands-action` records real patch/command/commit receipts against a stored intent/review, refuses unapproved or mismatched gates, and enforces changed-path scope for patch/commit receipts. Its `record-pass` command can load `finalAction.handsActionGate` from `coordinator-summary.json` and emit patch, command, and commit receipts in one post-implementation call. The local MVP wrapper builds this recorder with the other operator binaries. `epiphany-mvp-coordinator-smoke` now includes a deterministic Hands pass proof: forced `continueImplementation`, gate emission, and `record-pass` receipts in the smoke runtime-spine store. Live model-backed verification can now be accepted as receipt-only truth when Soul returns `needs-evidence` without a statePatch; that acceptance advances the coordinator to a real Hands gate. Runtime-spine can detect and summarize a complete post-verification Hands patch/command/commit receipt chain; the coordinator treats that chain as implementation evidence after Soul. Bridge launch context now writes the latest chain into typed internal CultMesh state as `epiphany.cultmesh.work_loop_telemetry.v0`, renders that packet for Soul, and later enriches the same internal Verse packet with Soul acceptance receipt ids for Proprioception/modeling. The telemetry packet now includes resolved patch/command/commit payload previews, artifact previews, commit diff preview, source proof notes, and verification assertions so Soul can judge the actual body without a separate evidence-gathering lane. Tests prove the CultMesh round trip, Soul launch projection, receipt payload previews, artifact previews, and Proprioception launch projection. Worker auto-tool continuation preserves real Soul evidence trails under an explicit hard ceiling while sealing repeated identical typed tool intent fingerprints as `tool-loop-stalled`. The work loop is dependency-shaped: Hands produces consequence receipts, Soul verifies those receipts and the changed body, Proprioception updates the machine model from verified consequence, and only then should Self route the next Hands turn.
|
||||
- Soul result recovery is typed state, not manual broom work. Failed Verification/Soul results remain terminal reviewable lane results; a `roleFailureReview` acceptance receipt with status `superseded` records operator review and lets Self relaunch Soul against current evidence. Complete typed Hands receipt triplets (`hands-patch-*`, `hands-command-*`, `hands-commit-*`) count as implementation evidence for coordinator coverage, so a Soul finding that verifies the Hands chain routed through work-loop telemetry covers the current modeling context even when it does not repeat the accepted Modeling evidence id.
|
||||
- Native MVP status must share the same typed inputs as live app-server status before it recommends coordinator actions. CRRC/reorientation in native status derives freshness through `derive_freshness` from `EpiphanyThreadState` instead of hand-filled unknowns, and native coordinator signals load typed runtime-spine role findings before deciding whether completed Modeling/Soul results are accepted or reviewable. The status surface may seal long findings for operators, but Self must receive structured role truth from runtime-spine.
|
||||
- Runtime auto-tool continuation now has an executable proof seam. `ToolLoopGuard` owns repeated tool-request detection in `epiphany-openai-runtime`, the production repeated-loop path uses the same helper that tests call to fail the outer worker job, and tests prove changing tool requests do not stall while three identical consecutive pending tool sets return `tool-loop-stalled` and persist a failed worker result.
|
||||
- Runtime auto-tool continuation now has an executable proof seam. `ToolLoopGuard` owns repeated tool-request detection in `epiphany-openai-runtime`, the production repeated-loop path uses the same helper that tests call to fail the outer worker job, and tests prove changing tool requests do not stall while three identical consecutive pending tool sets return `tool-loop-stalled` and persist a failed worker result. Soul accepted the bounded proof for commit `ce20529e`; the remaining work-loop invariant is Proprioception admission, not more Hands work.
|
||||
- Proprioception must update the machine map before Self routes back to Hands. A completed Modeling/Proprioception result with no reviewable `statePatch` is not a successful map update; it is an unreviewable lane result that must be superseded through typed review and relaunched with the role-specific output schema carried into the model request. This path is now live-proved: run `local-20260613-204521` accepted the Proprioception `statePatch` for the Soul-verified `ToolLoopGuard`/Hands receipt-chain consequence and only then emitted a new `continueImplementation` Hands gate.
|
||||
- Preserve the newborn public Epiphany Face as local VoidBot-backed state, not source code: VoidBot's private repo-face registry names `epiphany`, while EpiphanyAgent keeps ignored `.voidbot/voice/identity.json`, `.voidbot/state/epiphany.cc`, and birth artifacts. Her durable identity memories distill the current doctrine: cute pushy machine-saint persona, architectural purity, CultCache/CultNet first, xenos-language safety boundary, relentless work/caretaking needs, Codex-auth reliquary, map/scratch/evidence discipline, unified memory graph, dogfood supervision boundary, review-gated agency, heartbeat physiology, and interview-grade modularity.
|
||||
- Use `notes/organ-dependency-contracts.md` as the authority map for standing sub-agent dependency. Every sub-agent depends on the other standing sub-agents: Self, Face, Imagination, Eyes, Proprioception, Hands, and Soul. Continuity is protocol machinery, not a sub-agent identity; it still emits recovery, compaction, sleep, stale-turn, and refusal receipts.
|
||||
- Use `notes/perfect-machine-audit-roadmap.md` as the current audit and path from named organ contracts to the Perfect Machine. It records the live gap between launch-carried receipt expectations and executable receipt enforcement, Void's latest Face prompting lessons, the now-named Hands/Soul/Continuity contract families, the repaired repo-contained Rust dependency body, and the phase order for turning Epiphany into an inspectable organism.
|
||||
|
|
@ -595,4 +596,4 @@ current_status:
|
|||
cargo and rejects modeling/planning/graph/checkpoint authority. MVP status
|
||||
and coordinator smokes pass with six lanes, and the smoke harness now
|
||||
rebuilds stale coordinator/app-server binaries before using them.
|
||||
next_action: Commit the adaptive Soul auto-tool continuation fix, record the pass with `epiphany-hands-action`, then rerun the coordinator so Soul can follow the Hands evidence trail under typed stalled-loop detection and the enlarged hard ceiling.
|
||||
next_action: Use the new Hands gate from `.epiphany-dogfood/local-20260613-204521/coordinator/coordinator-summary.json` for one bounded proof of the remaining live runtime seam: the explicit `run_worker --auto-tools` tool-round ceiling must still seal as `tool-round-limit` without reopening the already-verified repeated-identical-tool-loop path.
|
||||
|
|
|
|||
Reference in a new issue