From fb873927d79342590f8d00a66d55a40a26d58cee Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 11 Aug 2026 13:44:36 +0200 Subject: [PATCH] Protect the runtime root session --- .../src/bin/epiphany-runtime-spine.rs | 29 +++- epiphany-core/src/bin/epiphany-swarm.rs | 20 +++ epiphany-core/src/coordinator_launch.rs | 2 +- epiphany-core/src/lib.rs | 2 + epiphany-core/src/runtime_spine.rs | 143 ++++++++++++++++++ notes/epiphany-current-algorithmic-map.md | 32 ++++ notes/fresh-workspace-handoff.md | 35 +++++ state/map.yaml | 4 +- 8 files changed, 263 insertions(+), 4 deletions(-) diff --git a/epiphany-core/src/bin/epiphany-runtime-spine.rs b/epiphany-core/src/bin/epiphany-runtime-spine.rs index 9539947a..f14adea5 100644 --- a/epiphany-core/src/bin/epiphany-runtime-spine.rs +++ b/epiphany-core/src/bin/epiphany-runtime-spine.rs @@ -18,6 +18,7 @@ use epiphany_core::complete_runtime_job; use epiphany_core::create_runtime_job; use epiphany_core::create_runtime_session; use epiphany_core::initialize_runtime_spine; +use epiphany_core::repair_runtime_root_session_after_invalid_completion; use epiphany_core::runtime_has_actionable_eyes_frontier; use epiphany_core::runtime_has_actionable_hands_frontier; use epiphany_core::runtime_spine_cache; @@ -213,6 +214,15 @@ fn main() -> Result<()> { println!("runtime session completed"); println!("session: {}", session.session_id); } + Command::RepairRootSession { reason } => { + let session = repair_runtime_root_session_after_invalid_completion( + &args.store, + &now(), + &reason, + )?; + println!("runtime root session repaired"); + println!("session: {}", session.session_id); + } Command::RecordEvent { event_id, event_type, @@ -332,6 +342,9 @@ enum Command { session_id: String, summary: String, }, + RepairRootSession { + reason: String, + }, RecordEvent { event_id: String, event_type: String, @@ -550,6 +563,20 @@ fn parse_command(mut args: Vec) -> Result { } Ok(Command::CloseSession { session_id, summary }) } + "repair-root-session" => { + let mut reason = String::new(); + parse_options(args, |name, value| match name { + "--reason" => { + reason = value; + Ok(()) + } + _ => Err(anyhow!("unknown repair-root-session argument: {name}")), + })?; + if reason.trim().is_empty() { + return Err(anyhow!("repair-root-session requires --reason")); + } + Ok(Command::RepairRootSession { reason }) + } "complete-job" => { let mut result_id = format!("result-{}", Uuid::new_v4()); let mut job_id = String::new(); @@ -678,7 +705,7 @@ fn now() -> String { } fn usage() -> &'static str { - "usage: epiphany-runtime-spine [--store path] " + "usage: epiphany-runtime-spine [--store path] " } fn model_input_item_chars(item: &EpiphanyModelInputItem) -> usize { diff --git a/epiphany-core/src/bin/epiphany-swarm.rs b/epiphany-core/src/bin/epiphany-swarm.rs index 3a7a39e9..decd4522 100644 --- a/epiphany-core/src/bin/epiphany-swarm.rs +++ b/epiphany-core/src/bin/epiphany-swarm.rs @@ -76,6 +76,7 @@ fn main() -> Result<()> { println!("{}", serde_json::to_string_pretty(&projection)?); return Ok(()); } + require_resident_git("git")?; let _singleton = acquire_resident_process_singleton("resident-self", &args.state_store)?; if let Some(pressure) = args.pressure.as_ref() { enqueue_resident_self_pressure(&args.state_store, pressure)?; @@ -130,6 +131,20 @@ fn main() -> Result<()> { Ok(()) } +fn require_resident_git(executable: &str) -> Result<()> { + let output = Command::new(executable) + .arg("--version") + .output() + .with_context(|| format!("resident coordinator body lacks required {executable:?}"))?; + if !output.status.success() { + return Err(anyhow!( + "resident coordinator body has unusable {executable:?}: exit {}", + output.status + )); + } + Ok(()) +} + fn maintain_resident_runtime(args: &Args, state: &ResidentSelfState) -> Result<()> { retain_runtime_receipts(args, state)?; retain_resident_self_lifecycles( @@ -757,6 +772,11 @@ fn resident_self_brake_engaged( mod brake_tests { use super::*; + #[test] + fn resident_body_preflight_refuses_missing_git_before_serve() { + assert!(require_resident_git("epiphany-deliberately-missing-git").is_err()); + } + #[test] fn brake_lookup_uses_the_exact_requested_runtime_namespace() -> Result<()> { let temp = tempfile::tempdir()?; diff --git a/epiphany-core/src/coordinator_launch.rs b/epiphany-core/src/coordinator_launch.rs index f811fd60..fa7ac140 100644 --- a/epiphany-core/src/coordinator_launch.rs +++ b/epiphany-core/src/coordinator_launch.rs @@ -305,7 +305,7 @@ fn commit_coordinator_job_launch_in_cache( RuntimeSpineHeartbeatJobOptions { runtime_id: runtime_identity.runtime_id, display_name: "Epiphany Local".to_string(), - session_id: "epiphany-main".to_string(), + session_id: crate::runtime_spine::EPIPHANY_RUNTIME_ROOT_SESSION_ID.to_string(), objective: plan .planning_state .objective diff --git a/epiphany-core/src/lib.rs b/epiphany-core/src/lib.rs index 0659a3a2..4b4c7c23 100644 --- a/epiphany-core/src/lib.rs +++ b/epiphany-core/src/lib.rs @@ -1013,6 +1013,7 @@ pub use runtime_spine::EpiphanyArchivedRuntimeWorkerAttempt; pub use runtime_spine::EpiphanyToolInvocationStatus; pub use runtime_spine::PreparedRuntimeSpineHeartbeatJob; pub use runtime_spine::RUNTIME_EVENT_TYPE; +pub use runtime_spine::EPIPHANY_RUNTIME_ROOT_SESSION_ID; pub use runtime_spine::RUNTIME_IDENTITY_KEY; pub use runtime_spine::RUNTIME_IDENTITY_TYPE; pub use runtime_spine::RUNTIME_JOB_RESULT_TYPE; @@ -1112,6 +1113,7 @@ pub use runtime_spine::put_soul_verdict_receipt; pub use runtime_spine::put_substrate_gate_repo_access_grant_receipt; pub use runtime_spine::relinquish_repo_frontier_hands_route; pub use runtime_spine::repair_legacy_terminal_coordinator_sessions; +pub use runtime_spine::repair_runtime_root_session_after_invalid_completion; pub use runtime_spine::replace_or_append_epiphany_job_binding; pub use runtime_spine::require_runtime_tool_execution_binding; pub use runtime_spine::retain_completed_runtime_sessions; diff --git a/epiphany-core/src/runtime_spine.rs b/epiphany-core/src/runtime_spine.rs index 6fc0d1c7..20948e8a 100644 --- a/epiphany-core/src/runtime_spine.rs +++ b/epiphany-core/src/runtime_spine.rs @@ -194,6 +194,7 @@ pub const RUNTIME_SWARM_BINDING_TYPE: &str = "epiphany.runtime.swarm_binding"; pub const RUNTIME_SWARM_BINDING_KEY: &str = "runtime-swarm-binding"; pub const RUNTIME_SWARM_BINDING_SCHEMA_VERSION: &str = "epiphany.runtime.swarm_binding.v0"; pub const RUNTIME_SPINE_SCHEMA_VERSION: &str = "epiphany.runtime_spine.v0"; +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"; pub const RUNTIME_TOOL_EXECUTION_BINDING_SCHEMA_VERSION: &str = @@ -1433,6 +1434,12 @@ pub fn close_runtime_session( validate_non_empty(&options.session_id, "session id")?; validate_non_empty(&options.completed_at, "session completion time")?; validate_non_empty(&options.summary, "session completion summary")?; + if options.session_id == EPIPHANY_RUNTIME_ROOT_SESSION_ID { + return Err(anyhow!( + "runtime root session {:?} is long-lived and cannot be generically completed", + options.session_id + )); + } let mut cache = runtime_spine_cache(store_path.as_ref())?; cache.pull_all_backing_stores()?; require_identity(&cache)?; @@ -1495,6 +1502,81 @@ pub fn close_runtime_session( Ok(session) } +pub fn repair_runtime_root_session_after_invalid_completion( + store_path: impl AsRef, + repaired_at: &str, + reason: &str, +) -> Result { + validate_non_empty(repaired_at, "root session repair time")?; + validate_non_empty(reason, "root session repair reason")?; + chrono::DateTime::parse_from_rfc3339(repaired_at) + .context("root session repair time must be RFC 3339")?; + let store_path = store_path.as_ref(); + let mut cache = runtime_spine_cache(store_path)?; + cache.pull_all_backing_stores()?; + require_identity(&cache)?; + let snapshot = cache.snapshot_envelopes(); + let mut session = cache + .get::(EPIPHANY_RUNTIME_ROOT_SESSION_ID)? + .ok_or_else(|| anyhow!("runtime root session does not exist"))?; + let event_id = format!("event-session-completed-{EPIPHANY_RUNTIME_ROOT_SESSION_ID}"); + let event = cache.get::(&event_id)?; + if session.status == EpiphanyRuntimeSessionStatus::Active { + if event.is_some() { + return Err(anyhow!("active runtime root session has a hostile completion event")); + } + return Ok(session); + } + if session.status != EpiphanyRuntimeSessionStatus::Completed { + return Err(anyhow!("runtime root session is not repairable from its current status")); + } + if cache + .get::(EPIPHANY_RUNTIME_ROOT_SESSION_ID)? + .is_some() + { + return Err(anyhow!("archived runtime root session cannot be repaired")); + } + let event = event + .ok_or_else(|| anyhow!("completed runtime root session lacks its completion event"))?; + if event.schema_version != RUNTIME_SPINE_SCHEMA_VERSION + || event.event_type != "session.completed" + || event.source != "continuity" + || event.session_id.as_deref() != Some(EPIPHANY_RUNTIME_ROOT_SESSION_ID) + || event.job_id.is_some() + || event.occurred_at != session.updated_at + || event.summary != session.coordinator_note + { + return Err(anyhow!( + "runtime root completion event does not exactly bind the completed session" + )); + } + if cache.get_all::()?.into_iter().any(|job| { + job.session_id == EPIPHANY_RUNTIME_ROOT_SESSION_ID + && matches!(job.status, EpiphanyRuntimeJobStatus::Queued | EpiphanyRuntimeJobStatus::Running | EpiphanyRuntimeJobStatus::WaitingForReview) + }) { + return Err(anyhow!( + "runtime root session has open jobs and cannot be repaired" + )); + } + let event_envelope = snapshot + .iter() + .find(|entry| entry.r#type == EpiphanyRuntimeEvent::TYPE && entry.key == event_id) + .cloned() + .ok_or_else(|| anyhow!("runtime root completion event envelope is missing"))?; + session.status = EpiphanyRuntimeSessionStatus::Active; + session.updated_at = repaired_at.to_string(); + session.coordinator_note = reason.to_string(); + let replacement = cache.prepare_entry(EPIPHANY_RUNTIME_ROOT_SESSION_ID, &session)?.0; + if !runtime_spine_backing_store(store_path)?.replace_and_delete_if_snapshot_unchanged( + &snapshot, + vec![replacement], + &[event_envelope], + )? { + return Err(anyhow!("runtime root session repair lost its full snapshot fence")); + } + Ok(session) +} + pub fn create_runtime_job( store_path: impl AsRef, options: RuntimeSpineJobOptions, @@ -18417,6 +18499,67 @@ pub(crate) mod tests { Ok(()) } + #[test] + fn runtime_root_session_refuses_generic_closure_and_repairs_exact_invalid_completion() + -> Result<()> { + let temp = tempdir()?; + let store = temp.path().join("runtime.msgpack"); + initialize_runtime_spine(&store, RuntimeSpineInitOptions { + runtime_id: "epiphany-test".into(), display_name: "Epiphany Test".into(), + created_at: "2026-08-11T09:00:00Z".into(), + })?; + create_runtime_session(&store, RuntimeSpineSessionOptions { + session_id: EPIPHANY_RUNTIME_ROOT_SESSION_ID.into(), + objective: "Own the long-lived cognitive runtime.".into(), + created_at: "2026-08-11T09:00:01Z".into(), coordinator_note: "root active".into(), + })?; + let before = fs::read(&store)?; + assert!(close_runtime_session(&store, RuntimeSpineSessionClosureOptions { + session_id: EPIPHANY_RUNTIME_ROOT_SESSION_ID.into(), + completed_at: "2026-08-11T09:00:02Z".into(), summary: "invalid".into(), + }).is_err()); + assert_eq!(fs::read(&store)?, before); + + let completed_at = "2026-08-11T09:00:04Z"; + let summary = "operator incorrectly completed the root"; + let mut cache = runtime_spine_cache(&store)?; + cache.pull_all_backing_stores()?; + let mut session = cache.get::(EPIPHANY_RUNTIME_ROOT_SESSION_ID)?.unwrap(); + session.status = EpiphanyRuntimeSessionStatus::Completed; + session.updated_at = completed_at.into(); + session.coordinator_note = summary.into(); + cache.put(EPIPHANY_RUNTIME_ROOT_SESSION_ID, &session)?; + let completed_without_event = fs::read(&store)?; + assert!(repair_runtime_root_session_after_invalid_completion( + &store, + "2026-08-11T09:00:05Z", + "must refuse incomplete authority", + ).is_err()); + assert_eq!(fs::read(&store)?, completed_without_event); + let event_id = format!("event-session-completed-{EPIPHANY_RUNTIME_ROOT_SESSION_ID}"); + cache.put(&event_id, &EpiphanyRuntimeEvent { + schema_version: RUNTIME_SPINE_SCHEMA_VERSION.into(), event_id: event_id.clone(), + occurred_at: completed_at.into(), event_type: "session.completed".into(), + source: "continuity".into(), session_id: Some(EPIPHANY_RUNTIME_ROOT_SESSION_ID.into()), + job_id: None, summary: summary.into(), metadata: BTreeMap::new(), + })?; + let repaired = repair_runtime_root_session_after_invalid_completion( + &store, "2026-08-11T09:00:06Z", "restore root authority")?; + assert_eq!(repaired.status, EpiphanyRuntimeSessionStatus::Active); + let mut cache = runtime_spine_cache(&store)?; + cache.pull_all_backing_stores()?; + assert!(cache.get::(&event_id)?.is_none()); + create_runtime_job(&store, RuntimeSpineJobOptions { + job_id: "job-after-root-repair".into(), session_id: EPIPHANY_RUNTIME_ROOT_SESSION_ID.into(), + role: "modeling".into(), created_at: "2026-08-11T09:00:07Z".into(), + summary: "Prove restored root accepts work.".into(), artifact_refs: Vec::new(), + })?; + assert_eq!(repair_runtime_root_session_after_invalid_completion( + &store, "2026-08-11T09:00:08Z", "idempotent")?.status, + EpiphanyRuntimeSessionStatus::Active); + Ok(()) + } + #[test] fn runtime_model_execution_binding_owns_atomic_request_membership() -> Result<()> { let temp = tempdir()?; diff --git a/notes/epiphany-current-algorithmic-map.md b/notes/epiphany-current-algorithmic-map.md index 5f45f510..771fbbc2 100644 --- a/notes/epiphany-current-algorithmic-map.md +++ b/notes/epiphany-current-algorithmic-map.md @@ -1671,6 +1671,38 @@ pre-adoption frontier-item hash is deliberately not equated with the route's post-adoption frontier-item hash; Mind's admitted patch is the transition that changes that item. +## Long-lived runtime root-session ownership + +- Owner: Runtime Continuity owns the canonical `epiphany-main` root session; + coordinator launches consume that identity but cannot decide its lifetime. +- Inputs: the exact typed root session, its deterministic Continuity completion + event, archive absence, terminal job set, repair timestamp/reason, and the + full runtime snapshot. +- Outputs: ordinary session closure refuses the root without changing bytes. A + narrow repair replaces only an invalidly Completed root as Active and deletes + only its exact completion event in one snapshot-fenced CultCache mutation. +- Derived state: `active_sessions` is status projection, not leaked-work + authority. Open job status owns whether work is live. +- Forbidden writers: generic close-session, retention, operator tidiness, and + session-count heuristics cannot terminalize or recreate the root. A repair + cannot infer authority from timestamps, a missing event, an archive, or an + open job. +- Shared paths: coordinator heartbeat preparation and all later cognitive jobs + use `EPIPHANY_RUNTIME_ROOT_SESSION_ID`; the packaged runtime CLI delegates to + the same strict repair primitive. +- Cut line: the production string literal and generic closure authority are + removed. The preserved c007 invalid completion is repaired only after this + exact source is packaged and authenticated. +- Verification: generic closure leaves root bytes unchanged; incomplete or + hostile completion families refuse; exact repair removes the event, restores + Active, accepts a subsequent job, replays idempotently, and loses a concurrent + full-snapshot fence rather than merging authority. + +Resident coordinator Body readiness separately proves the required external +`git` executable before singleton acquisition or pressure consumption. Missing +Body capability is a startup refusal, not a reason to hammer one immutable +typed request through process-failure retries. + ## Exact release build cache ownership The root release-bundle manifest owns release profile policy. Measured on the diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 1b1f754b..8ed60408 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -3581,3 +3581,38 @@ bootstrap rite invoked `cargo run` without the mandated shared target and paid names that build-free path and the correct shared-target fallback. Preserve the single deterministic release publisher; do not split it to fix operator contamination. Yggdrasil never builds. + +## c007 root Continuity fault and Body preflight — 2026-08-11 + +Exact `d296c424` packaged as release +`sha256-fc5bf3a8e8377c1effec824497184278909ee463cbff66278da35c00bb797001` +with witness +`sha256-cae5a0e9d4483d9c8a158e42202de11181094517a547b42930f410e579703c04`, +24 binaries, and zero warnings. The first clean pass after the contaminated +fingerprint rebuild took 5m10s Cargo; the identical warm replay took 0.80s +Cargo and 9.20s wall. Warm packaging is no longer the iteration bottleneck. + +c007 launched with Docker's bounded `local` log driver. A fresh typed proposal +then exposed two pre-cognition faults. The slim resident image lacked `git`, but +readiness did not prove that required Body capability, so the same immutable +proposal failed before worker launch 59 times. A git-capable c007c reached +Runtime Continuity and then failed because the operator had mistaken six +long-lived Active sessions for leaked work and generically completed them. +Closing `epiphany-main` was invalid: every coordinator job uses it as the +long-lived root session, so later work was refused as terminal. The incorrect +receipt is explicitly marked operator corruption under +`.epiphany-run/c007-d296c424/receipt.md`. c007c remains alive and cognitively +braked; no failed attempt is accepted cognition. + +The active cut assigns ownership to Runtime Continuity. The canonical +`EPIPHANY_RUNTIME_ROOT_SESSION_ID` supplies coordinator launch, generic session +closure refuses it before mutation, and a narrow `repair-root-session` API/CLI +requires the exact Completed root plus its deterministic Continuity completion +event, no archive, and no open jobs. It atomically restores Active and deletes +only that event behind the full snapshot fence. Resident serve/once now proves +`git --version` before taking its singleton or consuming pressure. Focused root +repair, ordinary closure, resident Body-preflight, and 34 coordinator-launch +tests pass. This source is still uncommitted/unpackaged. Next commit/push, +package exact source plus identical warm replay, then use only the authenticated +repair CLI on the preserved c007 state before releasing the proposal once. +Yggdrasil never builds. diff --git a/state/map.yaml b/state/map.yaml index 1dd9be50..25b6ade9 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -36,7 +36,7 @@ invariants: current_status: summary: Epiphany is a supervised engineering alpha on Starfire, not deployment-ready. Exact b8138a6b active-child SIGTERM and restart, exact 9f369528 deterministic warm packaging, exact c930f505 cross-container ownership, exact ed15f83a resident lifecycle retention, exact 16c4b19f coordinator receipt and Heartbeat artifact retention, exact cce2b8ac narrow model-generation retention, exact eea15e82 model-turn JSON ingress, exact b1e8c89a semantic unattempted-generation retention, exact 6bc3ec3f semantic physical-epoch retirement, and exact 44230a05 Persona conversation retention are proven. Gamecult-ops 059821f owns Yggdrasil stream retention and exact 6ee08a4 owns stable Starfire Persona-permit firewall ingress. Exact 16c4b19f genuine idle and exact a987d2f7 active cognition completed 900-pulse bounded plateaus. Runtime-owned typed fulfillment is accepted live under exact 6dd9b132. Yggdrasil is the small public crossing body, never the release forge. - latest_phase: Exact c006 c9a2a979 completed a 10h23m braked endurance run and was retired cleanly. Heartbeat stopped after 36,700 iterations with 36,624 brake refusals, only 72 retained pulse directories/4.2 MiB, no grant, and exit zero; resident ended revision 34 braked with no active turn and exit zero. Runtime, cognitive local Verse/brake, and release Verse hashes remained byte-identical. Its Docker json-file logs grew to about 37.3 MiB because the ad hoc Starfire launch had no rotation; that launch contract is rejected for c007. Receipts are .epiphany-run/c006-endurance-retirement-20260811. The build audit found no release-graph fault: b81b59a7 warm packaging remained deterministic, but transient code was illicitly edited inside the exact-source cache and restored with different mtimes. Routine Mind sight also compiled only because the bootstrap rite omitted the existing shared target; the shared epiphany-state binary completes status in 37.9ms. AGENTS now names the build-free/shared-target path. Yggdrasil never builds. + latest_phase: Exact d296c424 packaged cleanly after the contaminated fingerprint rebuild and then replayed identically in 9.20s wall/0.80s Cargo with 24 binaries, zero warnings, release sha256-fc5bf3a8e8377c1effec824497184278909ee463cbff66278da35c00bb797001, and witness sha256-cae5a0e9d4483d9c8a158e42202de11181094517a547b42930f410e579703c04. c007 uses bounded Docker local logs. Its fresh typed proposal exposed two Body/Continuity faults before valid cognition: the slim resident body lacked git and retried 59 times, then an operator incorrectly used generic close-session on the long-lived epiphany-main root because Active session count was mistaken for leaked work. c007c now runs a git-capable body and remains cognitively braked. The corrupted root, completion event, exact before/after hashes, and failed attempts are preserved. The active source cut makes the root a canonical constant, forbids generic closure, adds a strict snapshot-fenced repair transaction/CLI, and requires git before resident serve/once. Focused root, closure, swarm-preflight, and 34 coordinator-launch tests pass; source is not yet committed or packaged. Yggdrasil never builds. operational_state: local_worktree: exact_acd91e6e_imagination_runtime_owned_causality_live_accepted operator_wireguard: restored @@ -70,7 +70,7 @@ current_status: yggdrasil_epiphany_service_contract: repaired_in_gamecult_ops_812b427_not_installed resident_physiology: c006_exact_c9a2a979_stopped_cleanly_braked_revision_34_after_36700_pulse_endurance unresolved_authority: Coordinator receipt, Heartbeat pulse-artifact, genuine-idle and active resource plateaus, exact-grant terminality, restart-persistent cooldown refusal, schedule/action issuance cardinality, runtime-owned typed fulfillment, all three packaged fulfilled-before-receipt lanes, genuine packaged Imagination option generation, 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, co-resident resident lifecycle retention, authenticated outer-worker attempt retention, deployed supervisor/projector journald ownership, Docker named-volume atomic snapshot visibility, and deterministic incremental release construction are accepted. Starfire's Docker Desktop F: bind is rejected for mutable authority after an exact packaged lockless reader observed an empty published snapshot during writer interruption. Historical migrated semantic attempts without recorded physical namespace remain durable and non-retirable. One completed Discord consequence remains blocked by the absent Yggdrasil credential. Exact aa841873 also makes legacy coordinator repair one full-snapshot transaction so a later hostile family cannot leave an earlier partial repair. - next_action: Keep sealed c006 stopped with its cognitive brake and volumes intact. Before c007, give Starfire container stdout/stderr one bounded owner: an explicit rotating Docker log contract or a proper supervised service; do not relaunch an unbounded json-file body. Preserve the deterministic content-addressed package cache, never edit its exact-source worktree for fixture construction, and use the existing shared-target state binary for routine sight. Then start c007 from the latest authenticated runtime release and inspect the next canonical RepoFrontier typed action. Persona public consequence remains an external credential decision. Yggdrasil never builds. + next_action: Finish hostile-state verification for the root-session ownership cut, commit and push it, then package exact source through the persistent Starfire cache and require an identical warm replay. While c007c remains braked, use only that authenticated package's repair-root-session transaction against the preserved invalid epiphany-main completion; prove the exact event is removed, root is Active, unrelated runtime bytes remain unchanged, and a new job can open. Then release the exact typed proposal once, accept valid Modeling, reengage the brake, and inspect the next organ action. Do not treat Active session count as work leakage, do not retry around missing Body dependencies, and never build on Yggdrasil. active_subgoals: - Prove Persona, Self, Eyes, Modeling, Imagination, Hands, Soul, Mind, Continuity, and nervous-system behavior individually.