Delete counterfeit proposal intake authority
This commit is contained in:
parent
e7c1166b30
commit
6e600e8d64
8 changed files with 168 additions and 360 deletions
|
|
@ -526,17 +526,7 @@ pub fn epiphany_role_launch_output_schema(role_id: EpiphanyRoleResultRoleId) ->
|
|||
schema
|
||||
}
|
||||
|
||||
pub fn epiphany_proposal_modeling_output_schema(
|
||||
source_kind: crate::RepoFrontierProposalSourceKind,
|
||||
) -> serde_json::Value {
|
||||
let recommended_organs = match source_kind {
|
||||
crate::RepoFrontierProposalSourceKind::Imagination => vec!["Eyes", "Imagination"],
|
||||
crate::RepoFrontierProposalSourceKind::User
|
||||
| crate::RepoFrontierProposalSourceKind::Persona
|
||||
| crate::RepoFrontierProposalSourceKind::Bifrost => {
|
||||
vec!["Hands", "Eyes", "Imagination"]
|
||||
}
|
||||
};
|
||||
pub fn epiphany_proposal_modeling_output_schema() -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
@ -571,7 +561,7 @@ pub fn epiphany_proposal_modeling_output_schema(
|
|||
"description": "A strict lexicographically sorted, duplicate-free repository-relative path ceiling for this wound. Include intended outputs that downstream Planning may authorize Hands to change; do not substitute files inspected as evidence.",
|
||||
"items": {"type": "string", "minLength": 1}
|
||||
},
|
||||
"recommendedNextOrgan": {"type": "string", "enum": recommended_organs},
|
||||
"recommendedNextOrgan": {"type": "string", "enum": ["Eyes", "Imagination"]},
|
||||
"dependencyItemIds": {"type": "array", "items": {"type": "string"}},
|
||||
"evidenceRefs": {"type": "array", "items": {"type": "string"}}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3186,9 +3186,7 @@ pub fn launch_current_proposal_modeling_work(
|
|||
.get::<crate::RepoFrontierWorkProposal>(&request.proposal_id)?
|
||||
.ok_or_else(|| anyhow!("proposal Modeling launch lost its proposal"))?;
|
||||
crate::runtime_spine::validate_repo_frontier_work_proposal(&proposal)?;
|
||||
if proposal.source_kind == crate::RepoFrontierProposalSourceKind::Imagination {
|
||||
crate::runtime_spine::validate_autonomous_proposal_binding(&cache, &proposal)?;
|
||||
}
|
||||
crate::runtime_spine::validate_autonomous_proposal_binding(&cache, &proposal)?;
|
||||
let identity = cache
|
||||
.get::<crate::EpiphanyRuntimeIdentity>(crate::RUNTIME_IDENTITY_KEY)?
|
||||
.ok_or_else(|| anyhow!("proposal Modeling launch requires runtime identity"))?;
|
||||
|
|
@ -3518,17 +3516,12 @@ fn build_proposal_modeling_context_projection(
|
|||
thread_id: request.thread_id.clone(),
|
||||
repository: request.repository.clone(),
|
||||
workspace: request.workspace.clone(),
|
||||
source_kind: proposal.source_kind,
|
||||
source_actor: proposal.source_actor.clone(),
|
||||
source_ref: proposal.source_ref.clone(),
|
||||
title: proposal.title.clone(),
|
||||
body: proposal.body.clone(),
|
||||
desired_outcome: proposal.desired_outcome.clone(),
|
||||
constraints: proposal.constraints.clone(),
|
||||
scope_hints: proposal.scope_hints.clone(),
|
||||
evidence_refs: proposal.evidence_refs.clone(),
|
||||
public_source_refs: proposal.public_source_refs.clone(),
|
||||
private_state_included: proposal.private_state_included,
|
||||
model_projection_digest: model.projection_digest.clone(),
|
||||
model_source_documents: model.source_documents.clone(),
|
||||
prior_admission_refusals,
|
||||
|
|
@ -4129,32 +4122,141 @@ mod tests {
|
|||
assert_eq!(crate::repository_body_read_counters(), (0, 0));
|
||||
assert_current_work_reentry_is_read_only(&store, &completed_work)?;
|
||||
|
||||
let proposal = crate::intake_user_repo_frontier_proposal(
|
||||
let route = crate::runtime_repository_body_store_binding(&store)?
|
||||
.expect("runtime Body route remains bound");
|
||||
let (body_binding, _) =
|
||||
crate::load_repository_body_status(std::path::Path::new(&route.body_store_path))?
|
||||
.expect("runtime Body store remains authenticated");
|
||||
crate::bind_runtime_repository_domain(
|
||||
&store,
|
||||
crate::RepoFrontierUserProposalInput {
|
||||
proposal_id: "proposal-1".into(),
|
||||
source_actor: "operator".into(),
|
||||
source_ref: "operator://proposal-1".into(),
|
||||
repository: "epiphany".into(),
|
||||
workspace: "workspace".into(),
|
||||
thread_id: "creation-provenance-only".into(),
|
||||
runtime_id: "runtime".into(),
|
||||
"GameCult/Epiphany",
|
||||
"2026-08-17T00:00:05.100Z",
|
||||
)?;
|
||||
let direction_request = crate::commit_admitted_model_direction_consideration_request(
|
||||
&store,
|
||||
"2026-08-17T00:00:05.200Z",
|
||||
)?
|
||||
.expect("current keyed model produces one direction obligation");
|
||||
let direction_job_id = launch_current_admitted_model_direction_consideration_work(
|
||||
&store,
|
||||
&direction_request.request_id,
|
||||
"2026-08-17T00:00:05.300Z",
|
||||
)?;
|
||||
let mut direction_cache = crate::runtime_spine_cache(&store)?;
|
||||
direction_cache.pull_all_backing_stores()?;
|
||||
let direction_launch = direction_cache
|
||||
.get::<crate::EpiphanyRuntimeWorkerLaunchRequest>(&direction_job_id)?
|
||||
.expect("direction launch remains exact");
|
||||
drop(direction_cache);
|
||||
let direction_basis = crate::worker_reasoning_basis(&store, &direction_launch)?;
|
||||
crate::put_reasoning_basis(&store, &direction_basis)?;
|
||||
let mut direction_native = epiphany_model_adapter::EpiphanyModelRequest::new(
|
||||
"direction-request",
|
||||
"direction-conversation",
|
||||
"openai-codex",
|
||||
"gpt-test",
|
||||
"model",
|
||||
);
|
||||
direction_native.reasoning_basis_id = Some(direction_basis.basis_id.clone());
|
||||
direction_native.source_worker_job_id = Some(direction_job_id.clone());
|
||||
let direction_context =
|
||||
crate::EpiphanyDecisionContext::new(&direction_basis, direction_native, Vec::new())?;
|
||||
let mut direction_cache = crate::runtime_spine_cache(&store)?;
|
||||
direction_cache.pull_all_backing_stores()?;
|
||||
direction_cache.put(&direction_context.context_id, &direction_context)?;
|
||||
let direction_result = crate::AdmittedModelDirectionConsiderationResult {
|
||||
schema_version: crate::admitted_model_direction_consideration::RESULT_SCHEMA.into(),
|
||||
result_id: crate::admitted_model_direction_consideration_result_id_for_launch(
|
||||
&direction_request.request_id,
|
||||
&direction_job_id,
|
||||
),
|
||||
request_id: direction_request.request_id.clone(),
|
||||
runtime_id: direction_request.runtime_id.clone(),
|
||||
thread_id: direction_request.thread_id.clone(),
|
||||
model_projection_digest: direction_request.model_projection_digest.clone(),
|
||||
model_source_documents: direction_request.model_source_documents.clone(),
|
||||
disposition: crate::AdmittedModelDirectionDisposition::Suggest,
|
||||
summary: "Model one proposal".into(),
|
||||
option_drafts: vec![crate::ImaginationOptionDraft {
|
||||
title: "Model one proposal".into(),
|
||||
body: "Add one typed frontier without touching unrelated Mind state.".into(),
|
||||
desired_outcome: "One inspectable frontier".into(),
|
||||
constraints: Vec::new(),
|
||||
scope_hints: vec!["epiphany-core/src".into()],
|
||||
summary: "Add one typed frontier without touching unrelated Mind state.".into(),
|
||||
}],
|
||||
uncertainties: Vec::new(),
|
||||
evidence_refs: Vec::new(),
|
||||
proposed_at: "2026-08-17T00:00:05.400Z".into(),
|
||||
contract: crate::admitted_model_direction_consideration::RESULT_CONTRACT.into(),
|
||||
proposal_only: true,
|
||||
terminal: true,
|
||||
};
|
||||
let direction_worker_result = crate::EpiphanyRuntimeRoleWorkerResult {
|
||||
schema_version: crate::RUNTIME_ROLE_WORKER_RESULT_SCHEMA_VERSION.into(),
|
||||
result_id: "direction-worker-result".into(),
|
||||
job_id: direction_job_id.clone(),
|
||||
role_id: "imagination".into(),
|
||||
verdict: "suggest".into(),
|
||||
summary: direction_result.summary.clone(),
|
||||
next_safe_move: "Promote through the exact proposal owner.".into(),
|
||||
checkpoint_summary: None,
|
||||
scratch_summary: None,
|
||||
files_inspected: Vec::new(),
|
||||
frontier_node_ids: Vec::new(),
|
||||
evidence_ids: Vec::new(),
|
||||
artifact_refs: Vec::new(),
|
||||
open_questions: Vec::new(),
|
||||
evidence_gaps: Vec::new(),
|
||||
risks: Vec::new(),
|
||||
research_decision_msgpack: None,
|
||||
item_error: None,
|
||||
metadata: Default::default(),
|
||||
repo_model_mutation_proposal_msgpack: None,
|
||||
verification_request_id: None,
|
||||
frontier_route_id: None,
|
||||
repo_frontier_modeling_request_id: None,
|
||||
proposal_modeling_request_id: None,
|
||||
repo_frontier_research_request_id: None,
|
||||
frontier_planning_request_id: None,
|
||||
frontier_plan_candidate_msgpack: None,
|
||||
frontier_plan_mind_request_id: None,
|
||||
frontier_plan_mind_decision_msgpack: None,
|
||||
repository_body_observation_basis: None,
|
||||
imagination_consideration_request_id: None,
|
||||
imagination_consideration_candidate_msgpack: None,
|
||||
admitted_model_direction_consideration_request_id: Some(
|
||||
direction_request.request_id.clone(),
|
||||
),
|
||||
admitted_model_direction_consideration_result_msgpack: Some(rmp_serde::to_vec_named(
|
||||
&direction_result,
|
||||
)?),
|
||||
decision_context_id: direction_context.context_id.clone(),
|
||||
};
|
||||
crate::put_runtime_role_worker_result(&store, &direction_worker_result)?;
|
||||
crate::complete_runtime_job(
|
||||
&store,
|
||||
crate::RuntimeSpineJobResultOptions {
|
||||
result_id: "direction-runtime-result".into(),
|
||||
job_id: direction_job_id,
|
||||
completed_at: "2026-08-17T00:00:05.500Z".into(),
|
||||
verdict: "suggest".into(),
|
||||
summary: direction_result.summary,
|
||||
next_safe_move: "Promote through the exact proposal owner.".into(),
|
||||
evidence_refs: Vec::new(),
|
||||
public_source_refs: Vec::new(),
|
||||
proposed_at: "2026-08-17T00:00:06Z".into(),
|
||||
private_state_included: false,
|
||||
artifact_refs: Vec::new(),
|
||||
decision_context_id: Some(direction_context.context_id),
|
||||
},
|
||||
)?;
|
||||
let request = crate::select_repo_frontier_work_proposal_for_modeling(
|
||||
let mut promoted = crate::promote_autonomous_direction_options_for_modeling(
|
||||
&store,
|
||||
&proposal.proposal_id,
|
||||
"2026-08-17T00:00:07Z",
|
||||
"GameCult/Epiphany",
|
||||
&body_binding.git_top_level,
|
||||
"2026-08-17T00:00:06Z",
|
||||
)?;
|
||||
assert_eq!(promoted.len(), 1);
|
||||
let request = promoted.remove(0);
|
||||
let mut proposal_cache = crate::runtime_spine_cache(&store)?;
|
||||
proposal_cache.pull_all_backing_stores()?;
|
||||
let proposal = proposal_cache
|
||||
.get::<crate::RepoFrontierWorkProposal>(&request.proposal_id)?
|
||||
.expect("promotion atomically persists its proposal");
|
||||
let proposal_initial_projection = project_current_work(&store)?;
|
||||
let proposal_work = proposal_initial_projection
|
||||
.proposal_modeling
|
||||
|
|
|
|||
|
|
@ -305,7 +305,6 @@ pub use runtime_spine::create_runtime_session;
|
|||
pub use runtime_spine::ensure_runtime_session;
|
||||
pub use runtime_spine::finalize_coordinator_run;
|
||||
pub use runtime_spine::initialize_runtime_spine;
|
||||
pub use runtime_spine::intake_user_repo_frontier_proposal;
|
||||
pub use runtime_spine::model_pass_failure_for_request;
|
||||
pub use runtime_spine::open_coordinator_run;
|
||||
pub use runtime_spine::open_runtime_model_execution;
|
||||
|
|
@ -317,7 +316,6 @@ pub use runtime_spine::put_hands_command_receipt;
|
|||
pub use runtime_spine::put_hands_commit_receipt;
|
||||
pub use runtime_spine::put_hands_patch_receipt;
|
||||
pub use runtime_spine::put_repo_frontier_hands_authority;
|
||||
pub use runtime_spine::put_repo_frontier_work_proposal;
|
||||
pub use runtime_spine::put_runtime_reorient_worker_result;
|
||||
pub use runtime_spine::put_runtime_requested_public_source_intents;
|
||||
pub use runtime_spine::put_runtime_role_worker_result;
|
||||
|
|
@ -351,7 +349,6 @@ pub use runtime_spine::runtime_worker_process_claims;
|
|||
pub use runtime_spine::select_and_commit_repo_frontier_planning_request;
|
||||
pub use runtime_spine::select_and_commit_repo_frontier_research_request;
|
||||
pub use runtime_spine::select_and_commit_repo_frontier_route;
|
||||
pub use runtime_spine::select_repo_frontier_work_proposal_for_modeling;
|
||||
pub use runtime_spine::terminalize_model_pass_failure_session;
|
||||
pub use runtime_worker_attempt::{RuntimeTypedRequestRef, WorkerProcessStatus};
|
||||
pub use soul_gateway::*;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use sha2::{Digest, Sha256};
|
|||
|
||||
use crate::{EpiphanyMindDocumentVersion, runtime_spine_cache};
|
||||
|
||||
pub const MIND_SCHEMA_EPOCH: &str = "epiphany.mind.epoch.v4";
|
||||
pub const MIND_SCHEMA_EPOCH: &str = "epiphany.mind.epoch.v5";
|
||||
pub const MIND_OBJECTIVE_KEY: &str = "objective";
|
||||
pub const MIND_FOCUS_KEY: &str = "focus";
|
||||
pub const MIND_MODE_KEY: &str = "mode";
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ pub const REPO_FRONTIER_MODELING_REQUEST_SCHEMA_VERSION: &str =
|
|||
pub const REPO_FRONTIER_MODELING_REQUEST_CONTRACT: &str =
|
||||
"epiphany.repo_frontier_verdict_modeling_request.v1";
|
||||
pub const REPO_FRONTIER_WORK_PROPOSAL_SCHEMA_VERSION: &str =
|
||||
"epiphany.repo_frontier_work_proposal.v0";
|
||||
"epiphany.repo_frontier_work_proposal.v1";
|
||||
pub const REPO_FRONTIER_PLANNING_REQUEST_SCHEMA_VERSION: &str =
|
||||
"epiphany.self.repo_frontier_planning_request.v4";
|
||||
pub const REPO_FRONTIER_PLAN_CANDIDATE_SCHEMA_VERSION: &str =
|
||||
|
|
@ -60,7 +60,7 @@ pub const REPO_FRONTIER_RESEARCH_REQUEST_SCHEMA_VERSION: &str =
|
|||
pub const REPO_FRONTIER_RESEARCH_REQUEST_CONTRACT: &str =
|
||||
"epiphany.repo_frontier_research_request.v3";
|
||||
pub const REPO_FRONTIER_WORK_PROPOSAL_CONTRACT: &str =
|
||||
"epiphany.repo_frontier_work_proposal.inert.v0";
|
||||
"epiphany.repo_frontier_work_proposal.inert.v1";
|
||||
pub const REPO_FRONTIER_AUTONOMOUS_PROPOSAL_BINDING_SCHEMA_VERSION: &str =
|
||||
"epiphany.self.repo_frontier_autonomous_proposal_binding.v1";
|
||||
pub const REPO_FRONTIER_AUTONOMOUS_PROPOSAL_BINDING_CONTRACT: &str =
|
||||
|
|
@ -143,35 +143,6 @@ pub struct RepoModelClaimChallenge {
|
|||
pub contract: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum RepoFrontierProposalSourceKind {
|
||||
User,
|
||||
Persona,
|
||||
Bifrost,
|
||||
Imagination,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RepoFrontierUserProposalInput {
|
||||
pub proposal_id: String,
|
||||
pub source_actor: String,
|
||||
pub source_ref: String,
|
||||
pub repository: String,
|
||||
pub workspace: String,
|
||||
pub thread_id: String,
|
||||
pub runtime_id: String,
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub desired_outcome: String,
|
||||
pub constraints: Vec<String>,
|
||||
pub scope_hints: Vec<String>,
|
||||
pub evidence_refs: Vec<String>,
|
||||
pub public_source_refs: Vec<String>,
|
||||
pub proposed_at: String,
|
||||
pub private_state_included: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, DatabaseEntry)]
|
||||
#[cultcache(
|
||||
type = "epiphany.evidence.repo_frontier_work_proposal",
|
||||
|
|
@ -183,41 +154,31 @@ pub struct RepoFrontierWorkProposal {
|
|||
#[cultcache(key = 1)]
|
||||
pub proposal_id: String,
|
||||
#[cultcache(key = 2)]
|
||||
pub source_kind: RepoFrontierProposalSourceKind,
|
||||
#[cultcache(key = 3)]
|
||||
pub source_actor: String,
|
||||
#[cultcache(key = 4)]
|
||||
pub source_ref: String,
|
||||
#[cultcache(key = 5)]
|
||||
pub repository: String,
|
||||
#[cultcache(key = 6)]
|
||||
#[cultcache(key = 3)]
|
||||
pub workspace: String,
|
||||
#[cultcache(key = 7)]
|
||||
#[cultcache(key = 4)]
|
||||
pub thread_id: String,
|
||||
#[cultcache(key = 8)]
|
||||
#[cultcache(key = 5)]
|
||||
pub runtime_id: String,
|
||||
#[cultcache(key = 9)]
|
||||
#[cultcache(key = 6)]
|
||||
pub payload_sha256: String,
|
||||
#[cultcache(key = 10)]
|
||||
#[cultcache(key = 7)]
|
||||
pub title: String,
|
||||
#[cultcache(key = 11)]
|
||||
#[cultcache(key = 8)]
|
||||
pub body: String,
|
||||
#[cultcache(key = 12)]
|
||||
#[cultcache(key = 9)]
|
||||
pub desired_outcome: String,
|
||||
#[cultcache(key = 13)]
|
||||
#[cultcache(key = 10)]
|
||||
pub constraints: Vec<String>,
|
||||
#[cultcache(key = 14)]
|
||||
#[cultcache(key = 11)]
|
||||
pub scope_hints: Vec<String>,
|
||||
#[cultcache(key = 15)]
|
||||
#[cultcache(key = 12)]
|
||||
pub evidence_refs: Vec<String>,
|
||||
#[cultcache(key = 16)]
|
||||
pub private_state_included: bool,
|
||||
#[cultcache(key = 17)]
|
||||
#[cultcache(key = 13)]
|
||||
pub proposed_at: String,
|
||||
#[cultcache(key = 18)]
|
||||
#[cultcache(key = 14)]
|
||||
pub contract: String,
|
||||
#[cultcache(key = 19, default)]
|
||||
pub public_source_refs: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn repo_frontier_proposal_payload_sha256(
|
||||
|
|
@ -227,29 +188,15 @@ pub fn repo_frontier_proposal_payload_sha256(
|
|||
constraints: &[String],
|
||||
scope_hints: &[String],
|
||||
evidence_refs: &[String],
|
||||
public_source_refs: &[String],
|
||||
) -> Result<String> {
|
||||
let content = if public_source_refs.is_empty() {
|
||||
// Preserve the exact identity of pre-public-source v0 proposals.
|
||||
rmp_serde::to_vec_named(&(
|
||||
title,
|
||||
body,
|
||||
desired_outcome,
|
||||
constraints,
|
||||
scope_hints,
|
||||
evidence_refs,
|
||||
))?
|
||||
} else {
|
||||
rmp_serde::to_vec_named(&(
|
||||
title,
|
||||
body,
|
||||
desired_outcome,
|
||||
constraints,
|
||||
scope_hints,
|
||||
evidence_refs,
|
||||
public_source_refs,
|
||||
))?
|
||||
};
|
||||
let content = rmp_serde::to_vec_named(&(
|
||||
title,
|
||||
body,
|
||||
desired_outcome,
|
||||
constraints,
|
||||
scope_hints,
|
||||
evidence_refs,
|
||||
))?;
|
||||
Ok(format!("{:x}", Sha256::digest(content)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ pub const COORDINATOR_RUN_RECEIPT_TYPE: &str = "epiphany.coordinator_run_receipt
|
|||
pub const RUNTIME_IDENTITY_KEY: &str = "self";
|
||||
pub const RUNTIME_SWARM_BINDING_KEY: &str = "runtime-swarm-binding";
|
||||
pub const RUNTIME_SWARM_BINDING_SCHEMA_VERSION: &str = "epiphany.runtime.swarm_binding.v1";
|
||||
pub const RUNTIME_SPINE_SCHEMA_VERSION: &str = "epiphany.runtime_spine.v7";
|
||||
pub const RUNTIME_SPINE_SCHEMA_VERSION: &str = "epiphany.runtime_spine.v8";
|
||||
pub const EPIPHANY_RUNTIME_ROOT_SESSION_ID: &str = "epiphany-main";
|
||||
pub const RUNTIME_MODEL_EXECUTION_BINDING_SCHEMA_VERSION: &str =
|
||||
"epiphany.runtime.model_execution_binding.v0";
|
||||
|
|
@ -4839,9 +4839,7 @@ fn validated_proposal_modeling_worker_fulfillment(
|
|||
.get::<RepoFrontierWorkProposal>(&request.proposal_id)?
|
||||
.ok_or_else(|| anyhow!("proposal Modeling fulfillment proposal is missing"))?;
|
||||
validate_repo_frontier_work_proposal(&proposal)?;
|
||||
if proposal.source_kind == crate::RepoFrontierProposalSourceKind::Imagination {
|
||||
validate_autonomous_proposal_origin_binding(cache, &proposal)?;
|
||||
}
|
||||
validate_autonomous_proposal_origin_binding(cache, &proposal)?;
|
||||
let bindings = cache
|
||||
.get_all::<RepoFrontierProposalModelingLaunchBinding>()?
|
||||
.into_iter()
|
||||
|
|
@ -4869,7 +4867,6 @@ fn validated_proposal_modeling_worker_fulfillment(
|
|||
&proposal.constraints,
|
||||
&proposal.scope_hints,
|
||||
&proposal.evidence_refs,
|
||||
&proposal.public_source_refs,
|
||||
)?;
|
||||
let attempt_ordinal =
|
||||
crate::current_work::proposal_modeling_attempt_ordinal(request_id, &result.job_id)?;
|
||||
|
|
@ -4889,17 +4886,12 @@ fn validated_proposal_modeling_worker_fulfillment(
|
|||
thread_id: request.thread_id.clone(),
|
||||
repository: request.repository.clone(),
|
||||
workspace: request.workspace.clone(),
|
||||
source_kind: proposal.source_kind,
|
||||
source_actor: proposal.source_actor.clone(),
|
||||
source_ref: proposal.source_ref.clone(),
|
||||
title: proposal.title.clone(),
|
||||
body: proposal.body.clone(),
|
||||
desired_outcome: proposal.desired_outcome.clone(),
|
||||
constraints: proposal.constraints.clone(),
|
||||
scope_hints: proposal.scope_hints.clone(),
|
||||
evidence_refs: proposal.evidence_refs.clone(),
|
||||
public_source_refs: proposal.public_source_refs.clone(),
|
||||
private_state_included: proposal.private_state_included,
|
||||
model_projection_digest: projection.model_projection_digest.clone(),
|
||||
model_source_documents: projection.model_source_documents.clone(),
|
||||
prior_admission_refusals: prior_admission_refusals.clone(),
|
||||
|
|
@ -5045,19 +5037,13 @@ pub(crate) fn validate_proposal_modeling_worker_admission(
|
|||
.iter()
|
||||
.any(|id| id == &proposal.proposal_id)
|
||||
|| !crate::memory_graph::frontier_item_has_routeable_repository_scope(upserts[0])
|
||||
|| upserts[0].public_source_refs
|
||||
!= if upserts[0].recommended_next_organ == "Eyes" {
|
||||
proposal.public_source_refs.clone()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
|| !upserts[0].public_source_refs.is_empty()
|
||||
|| upserts[0].status != crate::RepoFrontierStatus::Active
|
||||
|| !matches!(
|
||||
upserts[0].recommended_next_organ.as_str(),
|
||||
"Hands" | "Eyes" | "Imagination"
|
||||
"Eyes" | "Imagination"
|
||||
)
|
||||
|| (proposal.source_kind == crate::RepoFrontierProposalSourceKind::Imagination
|
||||
&& (upserts[0].recommended_next_organ == "Hands" || upserts[0].adopted_plan.is_some()))
|
||||
|| upserts[0].adopted_plan.is_some()
|
||||
{
|
||||
return Err(anyhow!(
|
||||
"proposal Modeling fulfillment result is not one safe proposal-citing routeable frontier"
|
||||
|
|
@ -5224,42 +5210,12 @@ pub fn runtime_typed_request_fulfillment(
|
|||
}))
|
||||
}
|
||||
|
||||
fn put_immutable_planning_entry<T: cultcache_rs::DatabaseEntry + PartialEq + Clone>(
|
||||
store_path: &Path,
|
||||
key: &str,
|
||||
value: &T,
|
||||
) -> Result<()> {
|
||||
let mut cache = runtime_spine_cache(store_path)?;
|
||||
cache.pull_all_backing_stores()?;
|
||||
require_identity(&cache)?;
|
||||
if let Some(existing) = cache.get::<T>(key)? {
|
||||
return if existing == *value {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!("planning document ids are immutable"))
|
||||
};
|
||||
}
|
||||
let (envelope, _) = cache.prepare_entry(key, value)?;
|
||||
let backing = SingleFileMessagePackBackingStore::new(store_path);
|
||||
if backing.compare_and_swap_batch(&[], vec![envelope])? {
|
||||
return Ok(());
|
||||
}
|
||||
let mut reloaded = runtime_spine_cache(store_path)?;
|
||||
reloaded.pull_all_backing_stores()?;
|
||||
match reloaded.get::<T>(key)? {
|
||||
Some(existing) if existing == *value => Ok(()),
|
||||
_ => Err(anyhow!("planning document CAS collision")),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate_repo_frontier_work_proposal(
|
||||
proposal: &RepoFrontierWorkProposal,
|
||||
) -> Result<()> {
|
||||
if proposal.schema_version != REPO_FRONTIER_WORK_PROPOSAL_SCHEMA_VERSION
|
||||
|| proposal.contract != REPO_FRONTIER_WORK_PROPOSAL_CONTRACT
|
||||
|| proposal.proposal_id.trim().is_empty()
|
||||
|| proposal.source_actor.trim().is_empty()
|
||||
|| proposal.source_ref.trim().is_empty()
|
||||
|| proposal.repository.trim().is_empty()
|
||||
|| proposal.workspace.trim().is_empty()
|
||||
|| proposal.thread_id.trim().is_empty()
|
||||
|
|
@ -5267,17 +5223,10 @@ pub(crate) fn validate_repo_frontier_work_proposal(
|
|||
|| proposal.title.trim().is_empty()
|
||||
|| proposal.body.trim().is_empty()
|
||||
|| proposal.desired_outcome.trim().is_empty()
|
||||
|| proposal.private_state_included
|
||||
|| chrono::DateTime::parse_from_rfc3339(&proposal.proposed_at).is_err()
|
||||
{
|
||||
return Err(anyhow!("invalid inert repo frontier work proposal"));
|
||||
}
|
||||
let canonical_public_sources = crate::ImmutableGithubSource::canonicalize_set(
|
||||
proposal.public_source_refs.iter().map(String::as_str),
|
||||
)?;
|
||||
if canonical_public_sources != proposal.public_source_refs {
|
||||
return Err(anyhow!("proposal public source set is not canonical"));
|
||||
}
|
||||
let expected_payload_sha256 = crate::repo_frontier_proposal_payload_sha256(
|
||||
&proposal.title,
|
||||
&proposal.body,
|
||||
|
|
@ -5285,7 +5234,6 @@ pub(crate) fn validate_repo_frontier_work_proposal(
|
|||
&proposal.constraints,
|
||||
&proposal.scope_hints,
|
||||
&proposal.evidence_refs,
|
||||
&proposal.public_source_refs,
|
||||
)?;
|
||||
if proposal.payload_sha256 != expected_payload_sha256 {
|
||||
return Err(anyhow!("proposal content hash mismatch"));
|
||||
|
|
@ -5297,11 +5245,6 @@ fn validate_autonomous_proposal_origin_binding(
|
|||
cache: &CultCache,
|
||||
proposal: &RepoFrontierWorkProposal,
|
||||
) -> Result<RepoFrontierAutonomousProposalBinding> {
|
||||
if proposal.source_kind != crate::RepoFrontierProposalSourceKind::Imagination {
|
||||
return Err(anyhow!(
|
||||
"autonomous binding requires an Imagination proposal"
|
||||
));
|
||||
}
|
||||
let binding_id = format!("autonomous-proposal-binding-{}", proposal.proposal_id);
|
||||
let binding = cache
|
||||
.get::<RepoFrontierAutonomousProposalBinding>(&binding_id)?
|
||||
|
|
@ -5437,8 +5380,6 @@ fn validate_autonomous_proposal_origin_binding(
|
|||
|| domain.workspace_id != route.workspace_id
|
||||
|| domain.body_binding_sha256 != route.body_binding_sha256
|
||||
|| chrono::DateTime::parse_from_rfc3339(&binding.created_at).is_err()
|
||||
|| proposal.source_actor != EPIPHANY_IMAGINATION_OWNER_ROLE
|
||||
|| proposal.source_ref != result.result_id
|
||||
|| proposal.title != option.title
|
||||
|| proposal.body != option.summary
|
||||
{
|
||||
|
|
@ -5490,71 +5431,6 @@ pub(crate) fn validate_repo_frontier_proposal_modeling_request(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn put_repo_frontier_work_proposal(
|
||||
store_path: impl AsRef<Path>,
|
||||
proposal: &RepoFrontierWorkProposal,
|
||||
) -> Result<()> {
|
||||
validate_repo_frontier_work_proposal(proposal)?;
|
||||
if proposal.source_kind == crate::RepoFrontierProposalSourceKind::Imagination {
|
||||
return Err(anyhow!(
|
||||
"generic proposal intake cannot author Imagination provenance"
|
||||
));
|
||||
}
|
||||
let mut cache = runtime_spine_cache(store_path.as_ref())?;
|
||||
cache.pull_all_backing_stores()?;
|
||||
let identity = require_identity(&cache)?;
|
||||
if identity.runtime_id != proposal.runtime_id {
|
||||
return Err(anyhow!("proposal runtime identity mismatch"));
|
||||
}
|
||||
// The proposal's thread is immutable creation provenance. Runtime identity
|
||||
// owns intake; no mutable coordinator incarnation may admit or reject the
|
||||
// same semantic proposal.
|
||||
put_immutable_planning_entry(store_path.as_ref(), &proposal.proposal_id, proposal)
|
||||
}
|
||||
|
||||
pub fn intake_user_repo_frontier_proposal(
|
||||
store_path: impl AsRef<Path>,
|
||||
input: crate::RepoFrontierUserProposalInput,
|
||||
) -> Result<RepoFrontierWorkProposal> {
|
||||
let public_source_refs = crate::ImmutableGithubSource::canonicalize_set(
|
||||
input.public_source_refs.iter().map(String::as_str),
|
||||
)?;
|
||||
let payload_sha256 = crate::repo_frontier_proposal_payload_sha256(
|
||||
&input.title,
|
||||
&input.body,
|
||||
&input.desired_outcome,
|
||||
&input.constraints,
|
||||
&input.scope_hints,
|
||||
&input.evidence_refs,
|
||||
&public_source_refs,
|
||||
)?;
|
||||
let proposal = RepoFrontierWorkProposal {
|
||||
schema_version: REPO_FRONTIER_WORK_PROPOSAL_SCHEMA_VERSION.into(),
|
||||
proposal_id: input.proposal_id,
|
||||
source_kind: crate::RepoFrontierProposalSourceKind::User,
|
||||
source_actor: input.source_actor,
|
||||
source_ref: input.source_ref,
|
||||
repository: input.repository,
|
||||
workspace: input.workspace,
|
||||
thread_id: input.thread_id,
|
||||
runtime_id: input.runtime_id,
|
||||
payload_sha256,
|
||||
title: input.title,
|
||||
body: input.body,
|
||||
desired_outcome: input.desired_outcome,
|
||||
constraints: input.constraints,
|
||||
scope_hints: input.scope_hints,
|
||||
evidence_refs: input.evidence_refs,
|
||||
public_source_refs,
|
||||
private_state_included: input.private_state_included,
|
||||
proposed_at: input.proposed_at,
|
||||
contract: REPO_FRONTIER_WORK_PROPOSAL_CONTRACT.into(),
|
||||
};
|
||||
put_repo_frontier_work_proposal(store_path, &proposal)?;
|
||||
Ok(proposal)
|
||||
}
|
||||
|
||||
|
||||
pub fn bind_runtime_repository_domain(
|
||||
runtime_store: impl AsRef<Path>,
|
||||
repository_full_name: &str,
|
||||
|
|
@ -5774,14 +5650,10 @@ pub fn promote_autonomous_direction_options_for_modeling(
|
|||
&result.uncertainties,
|
||||
&[],
|
||||
&evidence_refs,
|
||||
&[],
|
||||
)?;
|
||||
let proposal = RepoFrontierWorkProposal {
|
||||
schema_version: REPO_FRONTIER_WORK_PROPOSAL_SCHEMA_VERSION.into(),
|
||||
proposal_id: proposal_id.clone(),
|
||||
source_kind: crate::RepoFrontierProposalSourceKind::Imagination,
|
||||
source_actor: EPIPHANY_IMAGINATION_OWNER_ROLE.into(),
|
||||
source_ref: result.result_id.clone(),
|
||||
repository: repository.into(),
|
||||
workspace: body_binding.git_top_level.clone(),
|
||||
thread_id: request.thread_id.clone(),
|
||||
|
|
@ -5793,8 +5665,6 @@ pub fn promote_autonomous_direction_options_for_modeling(
|
|||
constraints: result.uncertainties.clone(),
|
||||
scope_hints: Vec::new(),
|
||||
evidence_refs,
|
||||
public_source_refs: Vec::new(),
|
||||
private_state_included: false,
|
||||
proposed_at: result.proposed_at.clone(),
|
||||
contract: REPO_FRONTIER_WORK_PROPOSAL_CONTRACT.into(),
|
||||
};
|
||||
|
|
@ -5984,73 +5854,6 @@ fn keyed_repo_model_basis_envelopes(
|
|||
}
|
||||
|
||||
|
||||
pub fn select_repo_frontier_work_proposal_for_modeling(
|
||||
store_path: impl AsRef<Path>,
|
||||
proposal_id: &str,
|
||||
selected_at: &str,
|
||||
) -> Result<RepoFrontierProposalModelingRequest> {
|
||||
chrono::DateTime::parse_from_rfc3339(selected_at)
|
||||
.map_err(|_| anyhow!("proposal selection timestamp must be RFC3339"))?;
|
||||
let store_path = store_path.as_ref();
|
||||
let mut cache = runtime_spine_cache(store_path)?;
|
||||
cache.pull_all_backing_stores()?;
|
||||
let identity = require_identity(&cache)?;
|
||||
let proposal = cache
|
||||
.get::<RepoFrontierWorkProposal>(proposal_id)?
|
||||
.ok_or_else(|| anyhow!("proposal selection requires exact persisted proposal"))?;
|
||||
validate_repo_frontier_work_proposal(&proposal)?;
|
||||
if proposal.source_kind == crate::RepoFrontierProposalSourceKind::Imagination {
|
||||
validate_autonomous_proposal_binding(&cache, &proposal)?;
|
||||
}
|
||||
if proposal.runtime_id != identity.runtime_id {
|
||||
return Err(anyhow!("proposal selection provenance mismatch"));
|
||||
}
|
||||
let existing_requests = cache.get_all::<RepoFrontierProposalModelingRequest>()?;
|
||||
let request_id = crate::proposal_modeling_request_id(
|
||||
&proposal.runtime_id,
|
||||
&proposal.proposal_id,
|
||||
&proposal.payload_sha256,
|
||||
);
|
||||
let request = RepoFrontierProposalModelingRequest {
|
||||
schema_version: REPO_FRONTIER_PROPOSAL_MODELING_REQUEST_SCHEMA_VERSION.into(),
|
||||
request_id: request_id.clone(),
|
||||
proposal_id: proposal.proposal_id.clone(),
|
||||
proposal_payload_sha256: proposal.payload_sha256.clone(),
|
||||
runtime_id: proposal.runtime_id.clone(),
|
||||
thread_id: proposal.thread_id.clone(),
|
||||
repository: proposal.repository.clone(),
|
||||
workspace: proposal.workspace.clone(),
|
||||
selected_at: selected_at.into(),
|
||||
contract: REPO_FRONTIER_PROPOSAL_MODELING_REQUEST_CONTRACT.into(),
|
||||
};
|
||||
if let Some(existing) = existing_requests
|
||||
.into_iter()
|
||||
.find(|r| r.proposal_id == proposal_id)
|
||||
{
|
||||
validate_repo_frontier_proposal_modeling_request(&existing)?;
|
||||
return if existing == request {
|
||||
Ok(existing)
|
||||
} else {
|
||||
Err(anyhow!("proposal selection identity conflict"))
|
||||
};
|
||||
}
|
||||
match put_immutable_planning_entry(store_path, &request_id, &request) {
|
||||
Ok(()) => Ok(request),
|
||||
Err(error) => {
|
||||
let mut reloaded = runtime_spine_cache(store_path)?;
|
||||
reloaded.pull_all_backing_stores()?;
|
||||
if let Some(existing) =
|
||||
reloaded.get::<RepoFrontierProposalModelingRequest>(&request_id)?
|
||||
{
|
||||
if existing == request {
|
||||
return Ok(existing);
|
||||
}
|
||||
}
|
||||
Err(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_and_commit_repo_frontier_planning_request(
|
||||
runtime_store: impl AsRef<Path>,
|
||||
at: &str,
|
||||
|
|
@ -9336,6 +9139,7 @@ fn validate_archivable_typed_worker_launch(
|
|||
.get::<RepoFrontierWorkProposal>(&request.proposal_id)?
|
||||
.ok_or_else(|| anyhow!("archived proposal Modeling launch lost its proposal"))?;
|
||||
validate_repo_frontier_work_proposal(&proposal)?;
|
||||
validate_autonomous_proposal_origin_binding(cache, &proposal)?;
|
||||
let bindings = cache
|
||||
.get_all::<RepoFrontierProposalModelingLaunchBinding>()?
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ use serde::Serialize;
|
|||
pub const ROLE_WORKER_OUTPUT_CONTRACT_ID: &str = "epiphany.worker.role_result.v4";
|
||||
pub const REORIENT_WORKER_OUTPUT_CONTRACT_ID: &str = "epiphany.worker.reorient_result.v0";
|
||||
pub const REPO_FRONTIER_PROPOSAL_MODELING_CONTEXT_SCHEMA_VERSION: &str =
|
||||
"epiphany.worker.repo_frontier_proposal_modeling_context.v2";
|
||||
"epiphany.worker.repo_frontier_proposal_modeling_context.v3";
|
||||
pub const REPO_FRONTIER_PROPOSAL_MODELING_CONTEXT_CONTRACT: &str =
|
||||
"epiphany.repo_frontier_proposal_modeling_context.v2";
|
||||
"epiphany.repo_frontier_proposal_modeling_context.v3";
|
||||
pub const REPO_FRONTIER_PLANNING_CONTEXT_SCHEMA_VERSION: &str =
|
||||
"epiphany.worker.repo_frontier_planning_context.v2";
|
||||
pub const REPO_FRONTIER_PLANNING_CONTEXT_CONTRACT: &str =
|
||||
|
|
@ -192,9 +192,6 @@ pub struct RepoFrontierProposalModelingContextProjection {
|
|||
pub thread_id: String,
|
||||
pub repository: String,
|
||||
pub workspace: String,
|
||||
pub source_kind: crate::RepoFrontierProposalSourceKind,
|
||||
pub source_actor: String,
|
||||
pub source_ref: String,
|
||||
pub title: String,
|
||||
pub body: String,
|
||||
pub desired_outcome: String,
|
||||
|
|
@ -204,9 +201,6 @@ pub struct RepoFrontierProposalModelingContextProjection {
|
|||
pub scope_hints: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub evidence_refs: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub public_source_refs: Vec<String>,
|
||||
pub private_state_included: bool,
|
||||
pub model_projection_digest: String,
|
||||
pub model_source_documents: Vec<crate::EpiphanyMindDocumentVersion>,
|
||||
pub prior_admission_refusals: Vec<crate::EpiphanyAgentPassAdmissionRefusal>,
|
||||
|
|
|
|||
|
|
@ -1446,8 +1446,8 @@ fn worker_output_schema_json(
|
|||
epiphany_core::epiphany_admitted_model_direction_consideration_output_schema()
|
||||
} else if document.imagination_consideration_context.is_some() {
|
||||
epiphany_core::epiphany_imagination_consideration_output_schema()
|
||||
} else if let Some(context) = document.proposal_modeling_context.as_ref() {
|
||||
epiphany_core::epiphany_proposal_modeling_output_schema(context.source_kind)
|
||||
} else if document.proposal_modeling_context.is_some() {
|
||||
epiphany_core::epiphany_proposal_modeling_output_schema()
|
||||
} else if role_id == epiphany_core::EpiphanyRoleResultRoleId::Modeling
|
||||
&& launch_request.repo_frontier_modeling_request_id.is_some()
|
||||
{
|
||||
|
|
@ -1818,11 +1818,7 @@ fn role_worker_result_from_ingress(
|
|||
dependency_item_ids,
|
||||
status: epiphany_core::RepoFrontierStatus::Active,
|
||||
evidence_refs,
|
||||
public_source_refs: if draft.recommended_next_organ.trim() == "Eyes" {
|
||||
context.public_source_refs.clone()
|
||||
} else {
|
||||
Vec::new()
|
||||
},
|
||||
public_source_refs: Vec::new(),
|
||||
created_at: Some(completed_at.to_string()),
|
||||
updated_at: Some(completed_at.to_string()),
|
||||
retired_at: None,
|
||||
|
|
@ -2603,7 +2599,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn every_static_worker_contract_projects_to_one_strict_provider_shape() -> Result<()> {
|
||||
let mut schemas = vec![
|
||||
let schemas = vec![
|
||||
epiphany_core::epiphany_role_launch_output_schema(
|
||||
epiphany_core::EpiphanyRoleResultRoleId::Imagination,
|
||||
),
|
||||
|
|
@ -2620,18 +2616,9 @@ mod tests {
|
|||
epiphany_core::epiphany_frontier_plan_mind_output_schema(),
|
||||
epiphany_core::epiphany_imagination_consideration_output_schema(),
|
||||
epiphany_core::epiphany_admitted_model_direction_consideration_output_schema(),
|
||||
epiphany_core::epiphany_proposal_modeling_output_schema(),
|
||||
epiphany_core::epiphany_reorient_launch_output_schema(),
|
||||
];
|
||||
for source_kind in [
|
||||
epiphany_core::RepoFrontierProposalSourceKind::User,
|
||||
epiphany_core::RepoFrontierProposalSourceKind::Persona,
|
||||
epiphany_core::RepoFrontierProposalSourceKind::Bifrost,
|
||||
epiphany_core::RepoFrontierProposalSourceKind::Imagination,
|
||||
] {
|
||||
schemas.push(epiphany_core::epiphany_proposal_modeling_output_schema(
|
||||
source_kind,
|
||||
));
|
||||
}
|
||||
|
||||
for (index, schema) in schemas.into_iter().enumerate() {
|
||||
let mut request = EpiphanyOpenAiModelRequest::new(
|
||||
|
|
@ -2735,20 +2722,12 @@ mod tests {
|
|||
thread_id: "thread-1".into(),
|
||||
repository: "GameCult/Epiphany".into(),
|
||||
workspace: "/workspace".into(),
|
||||
source_kind: epiphany_core::RepoFrontierProposalSourceKind::User,
|
||||
source_actor: "operator".into(),
|
||||
source_ref: "operator://proposal".into(),
|
||||
title: "Map lifecycle".into(),
|
||||
body: "Inspect typed state".into(),
|
||||
desired_outcome: "One bounded frontier".into(),
|
||||
constraints: Vec::new(),
|
||||
scope_hints: vec!["epiphany-core/src/resident_self.rs".into()],
|
||||
evidence_refs: vec!["git:source".into()],
|
||||
public_source_refs: vec![
|
||||
"github://GameCult/Epiphany@0123456789abcdef0123456789abcdef01234567/README.md"
|
||||
.into(),
|
||||
],
|
||||
private_state_included: false,
|
||||
model_projection_digest: "model-projection-41".into(),
|
||||
model_source_documents: Vec::new(),
|
||||
prior_admission_refusals: Vec::new(),
|
||||
|
|
@ -2816,7 +2795,7 @@ mod tests {
|
|||
assert_eq!(item.status, epiphany_core::RepoFrontierStatus::Active);
|
||||
assert!(item.adopted_plan.is_none());
|
||||
assert!(item.evidence_refs.contains(&"proposal-1".to_string()));
|
||||
assert_eq!(item.public_source_refs, context.public_source_refs);
|
||||
assert!(item.public_source_refs.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -2950,17 +2929,12 @@ mod tests {
|
|||
thread_id: "thread-1".into(),
|
||||
repository: "GameCult/Epiphany".into(),
|
||||
workspace: "/workspace".into(),
|
||||
source_kind: epiphany_core::RepoFrontierProposalSourceKind::User,
|
||||
source_actor: "operator".into(),
|
||||
source_ref: "operator://proposal".into(),
|
||||
title: "Map lifecycle".into(),
|
||||
body: "Inspect typed state".into(),
|
||||
desired_outcome: "One bounded frontier".into(),
|
||||
constraints: Vec::new(),
|
||||
scope_hints: vec!["epiphany-core/src/resident_self.rs".into()],
|
||||
evidence_refs: vec!["git:source".into()],
|
||||
public_source_refs: Vec::new(),
|
||||
private_state_included: false,
|
||||
model_projection_digest: "model-projection-41".into(),
|
||||
model_source_documents: Vec::new(),
|
||||
prior_admission_refusals: Vec::new(),
|
||||
|
|
|
|||
Reference in a new issue