Preserve fulfillment through worker archival

This commit is contained in:
Meta Vens 2026-08-10 17:43:38 +01:00
commit bb263e9331
7 changed files with 266 additions and 27 deletions

View file

@ -18,7 +18,7 @@ use epiphany_core::{
resident_self_local_provider_status,
retain_completed_runtime_sessions,
retain_coordinator_run_receipts, retain_failed_runtime_worker_attempts,
retain_resident_self_lifecycles,
retain_fulfilled_runtime_worker_attempts, retain_resident_self_lifecycles,
settle_resident_self_exited_coordinator,
settle_resident_self_receipt_free_dead_coordinator, terminate_process_instance,
validate_persona_feedback_store_separation,
@ -161,11 +161,19 @@ fn retain_runtime_receipts(args: &Args, state: &ResidentSelfState) -> Result<()>
}
fn retain_runtime_worker_attempts(args: &Args) -> Result<()> {
let live_request_ids = live_resident_self_typed_request_ids(&args.state_store)?;
let archived_at = Utc::now().to_rfc3339();
retain_failed_runtime_worker_attempts(
&args.policy.runtime_store,
args.retained_failed_runtime_worker_attempts,
&live_resident_self_typed_request_ids(&args.state_store)?,
&Utc::now().to_rfc3339(),
args.retained_runtime_worker_attempts,
&live_request_ids,
&archived_at,
)?;
retain_fulfilled_runtime_worker_attempts(
&args.policy.runtime_store,
args.retained_runtime_worker_attempts,
&live_request_ids,
&archived_at,
)?;
Ok(())
}
@ -459,7 +467,7 @@ struct Args {
retained_closed_lifecycles: usize,
retained_coordinator_receipts: usize,
retained_completed_runtime_sessions: usize,
retained_failed_runtime_worker_attempts: usize,
retained_runtime_worker_attempts: usize,
persona_feedback_source_store: PathBuf,
persona_feedback_store: PathBuf,
bifrost_feedback_trust_anchor: PathBuf,
@ -573,12 +581,12 @@ impl Args {
)?
.try_into()
.context("--retained-completed-runtime-sessions exceeds platform size")?,
retained_failed_runtime_worker_attempts: u64v(
"--retained-failed-runtime-worker-attempts",
retained_runtime_worker_attempts: u64v(
"--retained-runtime-worker-attempts",
256,
)?
.try_into()
.context("--retained-failed-runtime-worker-attempts exceeds platform size")?,
.context("--retained-runtime-worker-attempts exceeds platform size")?,
persona_feedback_source_store: path("--persona-feedback-source-store")?,
persona_feedback_store: path("--persona-feedback-store")?,
bifrost_feedback_trust_anchor: path("--bifrost-feedback-trust-anchor")?,

View file

@ -1052,6 +1052,7 @@ pub use runtime_spine::activate_runtime_worker_process;
pub use runtime_spine::archive_completed_coordinator_session;
pub use runtime_spine::archive_completed_model_session;
pub use runtime_spine::archive_failed_runtime_worker_attempt;
pub use runtime_spine::archive_fulfilled_runtime_worker_attempt;
pub use runtime_spine::bind_runtime_repository_domain;
pub use runtime_spine::bind_runtime_to_agent_memory_swarm;
pub use runtime_spine::canonical_repo_frontier_plan_candidate_id;
@ -1113,6 +1114,7 @@ pub use runtime_spine::require_runtime_tool_execution_binding;
pub use runtime_spine::retain_completed_runtime_sessions;
pub use runtime_spine::retain_coordinator_run_receipts;
pub use runtime_spine::retain_failed_runtime_worker_attempts;
pub use runtime_spine::retain_fulfilled_runtime_worker_attempts;
pub use runtime_spine::runtime_continuity_recovery_receipt;
pub use runtime_spine::runtime_current_repo_model;
pub use runtime_spine::runtime_eyes_evidence_packet;

View file

@ -4483,6 +4483,42 @@ pub fn runtime_typed_request_fulfillment(
validate_non_empty(request_id, "typed fulfillment request id")?;
let mut cache = runtime_spine_cache(store_path)?;
cache.pull_all_backing_stores()?;
let archived_matches = cache
.get_all::<EpiphanyArchivedRuntimeWorkerAttempt>()?
.into_iter()
.filter(|attempt| attempt.request_id == request_id && attempt.result_id.is_some())
.collect::<Vec<_>>();
if archived_matches.len() > 1 {
return Err(anyhow!(
"typed fulfillment request has multiple archived terminal claimants"
));
}
if let Some(attempt) = archived_matches.first() {
let expected_kind = match request {
RuntimeTypedRequestRef::ProposalModeling(_) => "proposal-modeling",
RuntimeTypedRequestRef::ImaginationConsideration(_) => "imagination-consideration",
RuntimeTypedRequestRef::AdmittedModelDirection(_) => "admitted-model-direction",
};
if attempt.schema_version != ARCHIVED_RUNTIME_WORKER_ATTEMPT_SCHEMA_VERSION
|| attempt.archive_id != attempt.job_id
|| attempt.request_kind != expected_kind
|| attempt.terminal_process_status != "terminal-result"
|| !attempt.retired_chain_digest.starts_with("sha256:")
{
return Err(anyhow!("archived typed fulfillment tombstone is invalid"));
}
if cache.get::<EpiphanyRuntimeWorkerLaunchRequest>(&attempt.job_id)?.is_some()
|| cache.get::<EpiphanyRuntimeWorkerProcessClaim>(&worker_process_claim_id(&attempt.job_id))?.is_some()
|| cache.get::<EpiphanyRuntimeRoleWorkerResult>(&attempt.job_id)?.is_some()
{
return Err(anyhow!("archived typed fulfillment retained live attempt authority"));
}
return Ok(Some(RuntimeTypedFulfillmentEvidence {
job_id: attempt.job_id.clone(),
result_id: attempt.result_id.clone().expect("validated archived result"),
request_id: request_id.to_string(),
}));
}
let matches = cache
.get_all::<EpiphanyRuntimeRoleWorkerResult>()?
.into_iter()
@ -10509,6 +10545,43 @@ pub fn archive_failed_runtime_worker_attempt(
live_resident_request_ids: &BTreeSet<String>,
archived_at: &str,
) -> Result<EpiphanyArchivedRuntimeWorkerAttempt> {
archive_runtime_worker_attempt(
store_path,
job_id,
live_resident_request_ids,
archived_at,
false,
|| Ok(()),
)
}
pub fn archive_fulfilled_runtime_worker_attempt(
store_path: impl AsRef<Path>,
job_id: &str,
live_resident_request_ids: &BTreeSet<String>,
archived_at: &str,
) -> Result<EpiphanyArchivedRuntimeWorkerAttempt> {
archive_runtime_worker_attempt(
store_path,
job_id,
live_resident_request_ids,
archived_at,
true,
|| Ok(()),
)
}
fn archive_runtime_worker_attempt<F>(
store_path: impl AsRef<Path>,
job_id: &str,
live_resident_request_ids: &BTreeSet<String>,
archived_at: &str,
fulfilled: bool,
before_commit: F,
) -> Result<EpiphanyArchivedRuntimeWorkerAttempt>
where
F: FnOnce() -> Result<()>,
{
validate_non_empty(job_id, "archived worker attempt job id")?;
chrono::DateTime::parse_from_rfc3339(archived_at)
.map_err(|error| anyhow!("worker attempt archive timestamp is invalid: {error}"))?;
@ -10520,6 +10593,7 @@ pub fn archive_failed_runtime_worker_attempt(
if existing.schema_version != ARCHIVED_RUNTIME_WORKER_ATTEMPT_SCHEMA_VERSION
|| existing.archive_id != job_id
|| existing.job_id != job_id
|| existing.result_id.is_some() != fulfilled
|| !existing.retired_chain_digest.starts_with("sha256:")
{
return Err(anyhow!("archived worker attempt tombstone is invalid"));
@ -10546,22 +10620,58 @@ pub fn archive_failed_runtime_worker_attempt(
if live_resident_request_ids.contains(request_id) {
return Err(anyhow!("worker attempt archive refuses resident-live typed request"));
}
if cache.get::<EpiphanyRuntimeRoleWorkerResult>(job_id)?.is_some() {
return Err(anyhow!("failed worker attempt archive refuses terminal fulfillment authority"));
let role_result = cache.get::<EpiphanyRuntimeRoleWorkerResult>(job_id)?;
if fulfilled != role_result.is_some() {
return Err(anyhow!("worker attempt archive terminal result shape disagrees with requested archive kind"));
}
let claim_id = worker_process_claim_id(job_id);
let claim = cache.get::<EpiphanyRuntimeWorkerProcessClaim>(&claim_id)?
.ok_or_else(|| anyhow!("worker attempt archive requires its process claim"))?;
if !matches!(claim.status.as_str(), "terminal-death" | "terminal-unactivated" | "terminal-failure")
let valid_claim = if fulfilled {
claim.status == "terminal-result"
} else {
matches!(claim.status.as_str(), "terminal-death" | "terminal-unactivated" | "terminal-failure")
};
if !valid_claim
|| claim.terminal_at.is_none() || claim.terminal_authority_id.is_none()
{
return Err(anyhow!("failed worker attempt archive requires exact terminal process authority"));
}
let job = cache.get::<EpiphanyRuntimeJob>(job_id)?
.ok_or_else(|| anyhow!("worker attempt archive requires its runtime job"))?;
if !matches!(job.status, EpiphanyRuntimeJobStatus::Failed | EpiphanyRuntimeJobStatus::Cancelled) {
return Err(anyhow!("failed worker attempt archive requires a failed or cancelled runtime job"));
let valid_job = if fulfilled {
job.status == EpiphanyRuntimeJobStatus::Completed
} else {
matches!(job.status, EpiphanyRuntimeJobStatus::Failed | EpiphanyRuntimeJobStatus::Cancelled)
};
if !valid_job {
return Err(anyhow!("worker attempt archive requires matching terminal runtime job"));
}
let archived_result_id = if fulfilled {
let request_ref = match request_kind {
"proposal-modeling" => RuntimeTypedRequestRef::ProposalModeling(request_id),
"imagination-consideration" => RuntimeTypedRequestRef::ImaginationConsideration(request_id),
"admitted-model-direction" => RuntimeTypedRequestRef::AdmittedModelDirection(request_id),
_ => unreachable!("typed request kind was selected above"),
};
let evidence = runtime_typed_request_fulfillment(store_path, request_ref)?
.ok_or_else(|| anyhow!("fulfilled worker attempt archive lost authenticated fulfillment"))?;
if evidence.job_id != job_id
|| claim.terminal_authority_id.as_deref() != Some(evidence.result_id.as_str())
{
return Err(anyhow!("fulfilled worker attempt archive substituted terminal authority"));
}
if request_kind == "proposal-modeling"
&& !cache.get_all::<RepoModelAdmissionReceipt>()?.iter().any(|receipt| {
receipt.result_id.as_deref() == Some(evidence.result_id.as_str())
})
{
return Err(anyhow!("proposal Modeling attempt remains live until Mind admission owns its result"));
}
Some(evidence.result_id)
} else {
None
};
let snapshot = cache.snapshot_envelopes();
let proposal_bindings = cache.get_all::<RepoFrontierProposalModelingLaunchBinding>()?.into_iter()
.filter(|item| item.job_id == job_id).map(|item| item.binding_record_id).collect::<BTreeSet<_>>();
@ -10574,6 +10684,7 @@ pub fn archive_failed_runtime_worker_attempt(
let mut deletions = snapshot.iter().filter(|entry| {
(entry.r#type == EpiphanyRuntimeWorkerLaunchRequest::TYPE && entry.key == job_id)
|| (entry.r#type == EpiphanyRuntimeWorkerProcessClaim::TYPE && entry.key == claim_id)
|| (entry.r#type == EpiphanyRuntimeRoleWorkerResult::TYPE && fulfilled && entry.key == job_id)
|| (entry.r#type == EpiphanyRuntimeJob::TYPE && entry.key == job_id)
|| (entry.r#type == EpiphanyRuntimeJobResult::TYPE && job_results.contains(&entry.key))
|| (entry.r#type == EpiphanyRuntimeEvent::TYPE && events.contains(&entry.key))
@ -10600,11 +10711,12 @@ pub fn archive_failed_runtime_worker_attempt(
let tombstone = EpiphanyArchivedRuntimeWorkerAttempt {
schema_version: ARCHIVED_RUNTIME_WORKER_ATTEMPT_SCHEMA_VERSION.into(), archive_id: job_id.into(),
job_id: job_id.into(), request_kind: request_kind.into(), request_id: request_id.into(),
terminal_process_status: claim.status, result_id: None, archived_at: archived_at.into(),
terminal_process_status: claim.status, result_id: archived_result_id, archived_at: archived_at.into(),
retired_type_counts: counts, retired_envelope_count: deletions.len() as u64,
retired_chain_digest: format!("sha256:{:x}", digest.finalize()),
};
let replacement = cache.prepare_entry(job_id, &tombstone)?.0;
before_commit()?;
if !runtime_spine_backing_store(store_path)?.replace_and_delete_if_snapshot_unchanged(
&snapshot, vec![replacement], &deletions,
)? {
@ -10623,10 +10735,16 @@ pub fn retain_failed_runtime_worker_attempts(
require_identity(&cache)?;
let launches = cache.get_all::<EpiphanyRuntimeWorkerLaunchRequest>()?.into_iter()
.map(|launch| (launch.job_id.clone(), launch)).collect::<BTreeMap<_, _>>();
let jobs = cache.get_all::<EpiphanyRuntimeJob>()?.into_iter()
.map(|job| (job.job_id.clone(), job)).collect::<BTreeMap<_, _>>();
let mut candidates = cache.get_all::<EpiphanyRuntimeWorkerProcessClaim>()?.into_iter()
.filter(|claim| matches!(claim.status.as_str(), "terminal-death" | "terminal-unactivated" | "terminal-failure"))
.filter_map(|claim| {
let launch = launches.get(&claim.job_id)?;
let job = jobs.get(&claim.job_id)?;
if !matches!(job.status, EpiphanyRuntimeJobStatus::Failed | EpiphanyRuntimeJobStatus::Cancelled) {
return None;
}
let request_id = [launch.proposal_modeling_request_id.as_deref(), launch.imagination_consideration_request_id.as_deref(), launch.admitted_model_direction_consideration_request_id.as_deref()]
.into_iter().flatten().next()?;
(!live_resident_request_ids.contains(request_id)).then_some(claim)
@ -10637,6 +10755,44 @@ pub fn retain_failed_runtime_worker_attempts(
}).collect()
}
pub fn retain_fulfilled_runtime_worker_attempts(
store_path: impl AsRef<Path>, retain_recent: usize,
live_resident_request_ids: &BTreeSet<String>, archived_at: &str,
) -> Result<Vec<EpiphanyArchivedRuntimeWorkerAttempt>> {
let store_path = store_path.as_ref();
let mut cache = runtime_spine_cache(store_path)?;
cache.pull_all_backing_stores()?;
require_identity(&cache)?;
let launches = cache.get_all::<EpiphanyRuntimeWorkerLaunchRequest>()?.into_iter()
.map(|launch| (launch.job_id.clone(), launch)).collect::<BTreeMap<_, _>>();
let jobs = cache.get_all::<EpiphanyRuntimeJob>()?.into_iter()
.map(|job| (job.job_id.clone(), job)).collect::<BTreeMap<_, _>>();
let role_results = cache.get_all::<EpiphanyRuntimeRoleWorkerResult>()?.into_iter()
.map(|result| (result.job_id.clone(), result)).collect::<BTreeMap<_, _>>();
let admitted_result_ids = cache.get_all::<RepoModelAdmissionReceipt>()?.into_iter()
.filter_map(|receipt| receipt.result_id).collect::<BTreeSet<_>>();
let mut candidates = cache.get_all::<EpiphanyRuntimeWorkerProcessClaim>()?.into_iter()
.filter(|claim| claim.status == "terminal-result")
.filter_map(|claim| {
let launch = launches.get(&claim.job_id)?;
let job = jobs.get(&claim.job_id)?;
let result = role_results.get(&claim.job_id)?;
if job.status != EpiphanyRuntimeJobStatus::Completed
|| (launch.proposal_modeling_request_id.is_some()
&& !admitted_result_ids.contains(&result.result_id))
{
return None;
}
let request_id = [launch.proposal_modeling_request_id.as_deref(), launch.imagination_consideration_request_id.as_deref(), launch.admitted_model_direction_consideration_request_id.as_deref()]
.into_iter().flatten().next()?;
(!live_resident_request_ids.contains(request_id)).then_some(claim)
}).collect::<Vec<_>>();
candidates.sort_by(|a, b| b.terminal_at.cmp(&a.terminal_at).then(b.job_id.cmp(&a.job_id)));
candidates.into_iter().skip(retain_recent.max(1)).map(|claim| {
archive_fulfilled_runtime_worker_attempt(store_path, &claim.job_id, live_resident_request_ids, archived_at)
}).collect()
}
fn coordinator_completion_event(receipt: &EpiphanyCoordinatorRunReceipt) -> EpiphanyRuntimeEvent {
EpiphanyRuntimeEvent {
schema_version: RUNTIME_SPINE_SCHEMA_VERSION.to_string(),
@ -19899,6 +20055,22 @@ pub(crate) mod tests {
assert!(archive_failed_runtime_worker_attempt(&store, &job_id,
&BTreeSet::from([request_id.clone()]), "2026-08-10T20:00:03Z").is_err());
assert_eq!(std::fs::read(&store)?, before);
assert!(archive_runtime_worker_attempt(
&store, &job_id, &BTreeSet::new(), "2026-08-10T20:00:03Z", false,
|| {
append_runtime_event(&store, RuntimeSpineEventOptions {
event_id: "concurrent-worker-archive-event".into(),
occurred_at: "2026-08-10T20:00:02.500Z".into(),
event_type: "test.concurrent".into(),
source: "worker-archive-test".into(),
session_id: None,
job_id: None,
summary: "Concurrent unrelated authority.".into(),
})?;
Ok(())
},
).is_err());
assert!(runtime_worker_launch_request(&store, &job_id)?.is_some());
let tombstone = archive_failed_runtime_worker_attempt(
&store, &job_id, &BTreeSet::new(), "2026-08-10T20:00:03Z")?;
assert_eq!(tombstone.request_id, request_id);
@ -19912,4 +20084,42 @@ pub(crate) mod tests {
&store, &job_id, &BTreeSet::new(), "2026-08-10T20:00:03Z")?, tombstone);
Ok(())
}
#[test]
fn fulfilled_proposal_attempt_archive_preserves_authenticated_fulfillment() -> Result<()> {
let root = tempfile::tempdir()?;
let (store, result, review) = proposal_admission_fixture(root.path(), "fulfilled-archive")?;
let job_id = result.job_id.clone();
let request_id = result.proposal_modeling_request_id.clone().expect("request echo");
let process = crate::capture_process_instance(std::process::id())?;
let token = "fulfilled-archive-token";
claim_runtime_worker_process(&store, &job_id, &process,
&format!("{:x}", Sha256::digest(token.as_bytes())), "2026-08-10T21:00:00Z")?;
activate_runtime_worker_process(&store, &job_id, &process, token, "2026-08-10T21:00:01Z")?;
put_runtime_role_worker_result(&store, &result)?;
let admission = commit_repo_model_admission(&store, &result.result_id, &review)?;
complete_runtime_job(&store, RuntimeSpineJobResultOptions {
result_id: format!("generic-success-{job_id}"), job_id: job_id.clone(),
completed_at: "2026-08-10T21:00:02Z".into(), verdict: "pass".into(),
summary: "Typed worker attempt completed.".into(), next_safe_move: "Retire worker scaffolding.".into(),
evidence_refs: Vec::new(), artifact_refs: Vec::new(),
})?;
let expected = runtime_typed_request_fulfillment(
&store, RuntimeTypedRequestRef::ProposalModeling(&request_id))?.expect("live fulfillment");
let before = std::fs::read(&store)?;
assert!(archive_fulfilled_runtime_worker_attempt(&store, &job_id,
&BTreeSet::from([request_id.clone()]), "2026-08-10T21:00:03Z").is_err());
assert_eq!(std::fs::read(&store)?, before);
let tombstone = archive_fulfilled_runtime_worker_attempt(
&store, &job_id, &BTreeSet::new(), "2026-08-10T21:00:03Z")?;
assert_eq!(tombstone.result_id.as_deref(), Some(result.result_id.as_str()));
assert_eq!(runtime_typed_request_fulfillment(
&store, RuntimeTypedRequestRef::ProposalModeling(&request_id))?, Some(expected));
let mut cache = runtime_spine_cache(&store)?;
cache.pull_all_backing_stores()?;
assert_eq!(cache.get::<RepoModelAdmissionReceipt>(&admission.receipt_id)?, Some(admission));
assert!(runtime_worker_launch_request(&store, &job_id)?.is_none());
assert!(runtime_worker_process_claim(&store, &job_id)?.is_none());
Ok(())
}
}

View file

@ -3335,11 +3335,20 @@ terminal authority. It deletes only the matching launch, claim, lane binding,
job, generic result, and job events under the full physical snapshot fence.
The request and all unrelated envelopes remain live.
This cut deliberately refuses `terminal-result`: successful result/binding
authority still answers `runtime_typed_request_fulfillment`, so deleting it
without a fulfillment-capable tombstone would create false Pending state. That
reader migration, stale-CAS proof, and all-lane production retention proof are
the next cut.
### Fulfillment-capable tombstone cut
`archive_fulfilled_runtime_worker_attempt` first asks the runtime-owned typed
fulfillment verifier to authenticate the complete live attempt. It requires a
Completed generic job and a terminal-result claim bound to that exact result.
Proposal Modeling additionally requires exact Mind admission before the worker
scaffolding stops being the only owner of its patch. The atomic archive records
request kind, request ID, job ID, result ID, terminal status, exact retired type
counts, and chained digest. `runtime_typed_request_fulfillment` recognizes that
narrow tombstone only when no live launch, claim, or worker result coexists.
Thus resident settlement sees the same fulfillment before and after retention.
Producer-owned semantic companions and admission receipts are not retirement
cargo. Successful Imagination and admitted-model-direction live proofs remain
required before this cut is packaged.
- Owner: runtime spine owns archival of one immutable outer worker attempt.
Resident Self supplies cross-store liveness but cannot delete runtime rows.
@ -3371,9 +3380,7 @@ the next cut.
archived success; duplicate archive replay; and negative proof that restoring
or deleting one old envelope cannot resurrect work.
Source finding: current completed-session archival explicitly accepts only
terminal `openai-model-adapter` jobs and refuses outer-worker authority.
`runtime_typed_request_attempt_exists` treats a launch without a claim as live,
while `runtime_typed_request_fulfillment` requires the terminal result. Thus
claim-only or result-only deletion would respectively revive retry exclusion or
erase fulfillment. No production outer-worker retention primitive exists yet.
The completed-session archive remains separate and accepts only terminal
`openai-model-adapter` jobs. Outer worker attempts are owned by the dedicated
per-attempt archive above; retry and fulfillment readers consume its tombstone
rather than inferring state from independently missing claim/result rows.

View file

@ -2671,3 +2671,15 @@ tombstone. A focused proposal-Modeling test proves refusal, retirement,
idempotence, and that deletion cannot recreate retry suppression. Successful
attempt retirement remains open because its tombstone must preserve the same
authenticated fulfillment answer currently owned by the result/binding chain.
## Successful proposal worker archive preserves fulfillment — 2026-08-10
The worker-attempt tombstone can now carry a validated terminal result ID and
answer `runtime_typed_request_fulfillment` after live worker launch, claim,
result, binding, job, generic result, and events are retired. Proposal Modeling
retirement additionally requires a `RepoModelAdmissionReceipt` for that exact
worker result, so runtime retention cannot delete a patch still awaiting Mind.
The admitted model receipt remains byte-live. Focused proof covers resident
liveness refusal, exact live fulfillment before retirement, identical archived
fulfillment afterward, and a concurrent unrelated write that defeats the full
snapshot CAS without losing either side. Imagination and admitted-direction
successful companion preservation plus production enumeration remain open.

Binary file not shown.

View file

@ -70,7 +70,7 @@ current_status:
yggdrasil_epiphany_service_contract: repaired_in_gamecult_ops_812b427_not_installed
resident_physiology: c006_exact_c693aaea_settled_braked_no_active_lease_no_attempt_three_old_processes_stopped
unresolved_authority: Coordinator receipt, Heartbeat pulse-artifact, deployed supervisor/projector log retention, genuine-idle and active resource plateaus, exact-grant terminality, restart-persistent cooldown refusal, schedule/action issuance cardinality, runtime-owned typed fulfillment, narrow model-generation retention, published model-turn JSON ingress, semantic logical/physical retention, Persona conversation retention, stable Starfire firewall ownership, completed model-adapter session archival, normal coordinator lifecycle opening/error closure/legacy repair/archival, packaged admitted-model-direction and Imagination fulfilled-before-receipt settlement, and packaged co-resident resident lifecycle retention are accepted live. Proposal Modeling fulfilled-before-receipt plus runtime retention of terminal worker attempts remain open. Historical migrated semantic attempts without recorded physical namespace remain durable and non-retirable. Repository Body observation still performs two authenticated full-tree Git index/manifest passes. Execute-mode workers require a persistent process body. Mutable Starfire bind storage still needs the packaged randomized interruption/read-loop proof before recovered c005 authority may be trusted. One completed Discord consequence remains blocked by the absent Yggdrasil credential.
next_action: Complete typed runtime worker-attempt retention. The source cut now archives failed/cancelled proposal-Modeling, Imagination, and admitted-model-direction attempts only after resident Self's surviving grants prove no cross-store liveness; one full-snapshot CAS replaces launch, terminal claim, lane binding, job/result/event family with a per-attempt tombstone, and replay cannot resurrect retry suppression. Next make successful tombstones answer authenticated fulfillment without retaining live result/binding authority, add stale-CAS and production enumeration tests across all three lanes, then package and prove copied-state retention. Keep actual c006 braked. Yggdrasil never builds.
next_action: Complete and package typed runtime worker-attempt retention. Source now archives failed attempts and admitted successful proposal-Modeling attempts after resident liveness clears; successful tombstones answer the same typed fulfillment query while the admitted model receipt remains producer-owned, and stale full-snapshot races refuse. Next prove successful Imagination and admitted-model-direction archives preserve their producer-owned companions, exercise production enumeration/retention across all three lanes, then package and run copied-state non-resurrection proof plus direct proposal Modeling construction. Keep actual c006 braked. Yggdrasil never builds.
active_subgoals:
- Prove Persona, Self, Eyes, Modeling, Imagination, Hands, Soul, Mind, Continuity, and nervous-system behavior individually.