diff --git a/epiphany-core/src/bin/epiphany-mvp-coordinator.rs b/epiphany-core/src/bin/epiphany-mvp-coordinator.rs index 4048f51a..75c1fe81 100644 --- a/epiphany-core/src/bin/epiphany-mvp-coordinator.rs +++ b/epiphany-core/src/bin/epiphany-mvp-coordinator.rs @@ -260,10 +260,10 @@ impl Args { fn run_coordinator(args: &Args) -> Result { let root = env::current_dir().context("failed to resolve current dir")?; - match (&args.resident_state_store, &args.resident_preparation_id) { + let resident_claim = match (&args.resident_state_store, &args.resident_preparation_id) { (Some(store), Some(preparation_id)) => { let identity = capture_process_instance(std::process::id())?; - claim_resident_self_preparation_as_child( + Some(claim_resident_self_preparation_as_child( store, preparation_id, &LaunchedCoordinator { @@ -272,15 +272,15 @@ fn run_coordinator(args: &Args) -> Result { process_executable_path: identity.executable_path, }, chrono::Utc::now().timestamp_millis().max(0) as u64, - )?; + )?) } - (None, None) => {} + (None, None) => None, _ => { return Err(anyhow!( "resident coordinator bootstrap requires both state store and preparation id" )); } - } + }; let local_verse_store = status_cli::absolute_path(&args.local_verse_store)?; assert_local_verse_brake_released( &local_verse_store, @@ -355,13 +355,33 @@ fn run_coordinator(args: &Args) -> Result { })); let run_result = (|| -> Result { if let Some(objective) = args.objective.as_deref() { - let intake = intake_operator_objective(&runtime_store, &thread_id, objective)?; - startup_events.push(json!({ - "type": "operatorObjectiveIntake", - "threadId": thread_id, - "revision": intake.state.revision, - "changed": intake.changed, - })); + if let (Some(store), Some(preparation_id), Some(claim)) = ( + args.resident_state_store.as_deref(), + args.resident_preparation_id.as_deref(), + resident_claim.as_ref(), + ) { + epiphany_core::validate_resident_self_prepared_objective( + store, + preparation_id, + claim, + objective, + )?; + startup_events.push(json!({ + "type": "residentObjectiveBinding", + "threadId": thread_id, + "grantId": claim.grant_id, + "preparationId": preparation_id, + "canonicalObjectiveChanged": false, + })); + } else { + let intake = intake_operator_objective(&runtime_store, &thread_id, objective)?; + startup_events.push(json!({ + "type": "operatorObjectiveIntake", + "threadId": thread_id, + "revision": intake.state.revision, + "changed": intake.changed, + })); + } } if let Some(request_id) = args.imagination_consideration_request_id.as_deref() { if args.objective.is_some() { diff --git a/epiphany-core/src/resident_self.rs b/epiphany-core/src/resident_self.rs index 350c4bc7..05ecd659 100644 --- a/epiphany-core/src/resident_self.rs +++ b/epiphany-core/src/resident_self.rs @@ -2678,6 +2678,38 @@ pub fn resident_self_child_claim( .get::(&format!("resident-self-child-claim-{preparation_id}")) } +/// Authenticates the per-turn objective carried by a resident coordinator +/// launch. The canonical coordinator thread objective remains Mind-owned; this +/// validates only the directive already persisted in the exact prepared grant. +pub fn validate_resident_self_prepared_objective( + path: &Path, + preparation_id: &str, + claim: &ResidentSelfChildClaim, + objective: &str, +) -> Result<()> { + let cache = state_cache(path)?; + let state = cache + .get::(RESIDENT_SELF_STATE_KEY)? + .ok_or_else(|| anyhow!("resident Self state is absent at objective bootstrap"))?; + let prepared = state + .prepared_launch + .as_ref() + .filter(|prepared| prepared.preparation_id == preparation_id) + .ok_or_else(|| anyhow!("resident Self preparation is absent at objective bootstrap"))?; + let objective_digest = digest_parts([objective.as_bytes()]); + if prepared.grant.pressure_kind != "operator-objective" + || prepared.grant.grant_id != claim.grant_id + || prepared.launch_digest != claim.launch_digest + || prepared.grant.objective != objective + || prepared.objective_digest != objective_digest + { + return Err(anyhow!( + "resident coordinator objective disagrees with its exact prepared grant" + )); + } + Ok(()) +} + #[cfg(test)] fn complete_resident_self_turn( path: &Path, @@ -4460,6 +4492,32 @@ mod tests { resident_prepared_launch_thread_id(&prepared)?, "resident-self-thread-cognitive-runtime" ); + let process = LaunchedCoordinator { + process_id: u32::MAX - 20, + process_creation_token: 81, + process_executable_path: policy.coordinator_bin.clone(), + }; + let claim = claim_resident_self_preparation_as_child( + &store, + &prepared.preparation_id, + &process, + 4, + )?; + validate_resident_self_prepared_objective( + &store, + &prepared.preparation_id, + &claim, + "Run one bounded planning turn.", + )?; + assert!( + validate_resident_self_prepared_objective( + &store, + &prepared.preparation_id, + &claim, + "Replace the canonical objective.", + ) + .is_err() + ); Ok(()) } diff --git a/notes/epiphany-current-algorithmic-map.md b/notes/epiphany-current-algorithmic-map.md index 9382bd8f..8b4532a8 100644 --- a/notes/epiphany-current-algorithmic-map.md +++ b/notes/epiphany-current-algorithmic-map.md @@ -4234,3 +4234,28 @@ outside this cut because its coordinator and Hands producers own independent access grants before acceptance. Seven coordinator-acceptance tests prove the shared transaction, invalid-witness refusal, prerequisite co-publication, exact Soul binding, and split-admission replay. + +## Resident directive versus canonical objective ownership + +- Owner: canonical coordinator state owns the long-lived thread objective; + resident Self's exact prepared launch owns one resident turn directive. +- Inputs: standalone startup may supply a typed user-objective intake. Resident + startup supplies an exact preparation, grant, child claim, launch digest, + objective digest, and argv objective. +- Outputs: standalone intake atomically seeds state plus `UserObjectiveIntake`. + Resident bootstrap emits authenticated per-turn command context and leaves the + canonical objective byte-identical. +- Derived state: coordinator argv `--objective` is a carrier. It is not itself + permission to replace Mind state. +- Forbidden writers: a resident directive cannot call the seed-only objective + intake, replace canonical state, or rely on an absent legacy intake envelope. + A foreign objective cannot pass the prepared-launch digest checks. +- Shared paths: plain operator pressures use resident authentication; typed + proposal/consideration continuations remain objective-free; standalone + coordinator startup retains initial intake. +- Cut line: branch objective handling on authenticated resident bootstrap + evidence instead of unconditionally calling `intake_user_objective`. +- Verification: c008 attempt 1 failed closed and terminalized without external + consequence. Focused tests prove exact resident objective acceptance, foreign + objective refusal, and unchanged standalone seed-only replacement refusal. + Live attempt 2 replay remains the package gate. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 3208d5f6..c73965bd 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -3856,3 +3856,34 @@ fixture writers were also public. They are now test-only and unexported. Hands paths genuinely produce it independently. All seven coordinator acceptance tests, the historical-family fixture, and production library check pass. Package this final family cut, then move to a larger live matrix gate. + +Exact `8ebe56f1` packages the completed family as warning-free 24-binary release +`sha256-2707ff42e48dd8640b8a962536972799dca9a1f49346d3b8d05695e7fa826a8e` +with witness +`sha256-6003630b550041f90f76ec6261372e6925fd4144ee3daee1d0e2f6864f217289`. +The release published into the live Verse. c007h stopped Heartbeat then resident +Self with exit zero; c008 restarted both on the same named state/workspace +volumes, bounded 10 MiB x3 local logs, exact authenticated readiness, revision +312, no lease, and `awaitFrontierProposal`. The workspace then advanced cleanly +from `3a5d2b5e` to exact `8ebe56f1`, preserving only its untracked `.epiphany/` +runtime configuration. + +A genuine typed operator pressure +`operator-current-body-audit-8ebe56f1` exposed a live ownership fault. +Heartbeat granted attempt 1 and Self launched, but coordinator startup +terminalized the opened run because the existing canonical coordinator state +has no `UserObjectiveIntake`. Heartbeat acknowledged the failed grant and +committed attempt 2 before the canonical brake was re-engaged. State is +revision 316 with no active lease; attempt 2 remains unclaimed. The problem is +not missing legacy data: `intake_user_objective` is deliberately seed-only and +cannot own later resident directives. + +The source cut separates those authorities. Standalone coordinator startup +still atomically seeds the canonical Mind objective. A resident launch instead +authenticates its argv objective against the exact persisted prepared grant, +child claim, launch digest, and objective digest, then treats it as per-turn +command context without changing the canonical objective. Wrong objective or +non-operator pressure refuses. The focused resident test, standalone seed-only +test, and coordinator-runtime binary check pass. Package/publish this cut, +restart c008, release only for committed attempt 2, and require exact settlement +before re-engaging the brake. diff --git a/notes/perfect-machine-audit-roadmap.md b/notes/perfect-machine-audit-roadmap.md index 6056368a..f7764ee4 100644 --- a/notes/perfect-machine-audit-roadmap.md +++ b/notes/perfect-machine-audit-roadmap.md @@ -12,19 +12,16 @@ the actual braked resident body are the live gates. ## Current body - Source branch: `codex/epiphany-shakedown-live`. -- Current source: exact `d7957b42`. -- Accepted runtime implementation: exact `3a5d2b5e`. -- Linux release: - `sha256-84af3da8d2a2e170aa0611e48367eac4ecf5f66b2a2da763dc3045c5ad360177`. -- Witness: - `sha256-589ff2ca11392b02fee9cb5d3a0209d958fc47cc3695f82bb6e5bed08d4c4463`. -- Actual c007h: Heartbeat and resident Self alive in distinct containers, - cognitive brake engaged, resident revision 312, authenticated readiness, - no active lease, and action `awaitFrontierProposal`. -- Audited candidate release: - `sha256-bd0062904fa8e7097946c6fd735191de43ff04a89d1c3c29c0c86f876815fb31`; +- Current pushed source: exact `8ebe56f1`. +- Accepted live runtime implementation: exact `8ebe56f1`. +- Audited/live release: + `sha256-2707ff42e48dd8640b8a962536972799dca9a1f49346d3b8d05695e7fa826a8e`; witness - `sha256-a051980f70b13d9dafa014fedc7fc636eb075a9fc85dc53e3a94081bcc3fe3e0`. + `sha256-6003630b550041f90f76ec6261372e6925fd4144ee3daee1d0e2f6864f217289`. +- Actual c008: Heartbeat and resident Self alive in distinct containers on the + exact current release, cognitive brake engaged, resident revision 316, one + failed operator attempt terminalized, and retry attempt 2 committed but + unclaimed. - Build body: Starfire. Yggdrasil is the small public crossing and never builds this graph. @@ -120,11 +117,11 @@ these legitimate aggregates into ad hoc query piles. ## Selected next bounded cut -Commit and package the completed acceptance-family ownership cut, authenticate -its exact release, then select a larger live organ-matrix gate from current -source. Do not continue fixture-writer archaeology merely because another raw -helper looks ugly. Actual c007h remains braked and untouched; do not manufacture -frontier work. +Package the resident-directive ownership cut and restart exact c008. Release +the brake only for committed attempt 2; require the coordinator to authenticate +the directive from its prepared grant, preserve the canonical Mind objective, +and settle once. Re-engage the brake at the next phase boundary. Do not build +on Yggdrasil. ## Completion standard diff --git a/state/map.yaml b/state/map.yaml index 922c7f37..a654496d 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -36,19 +36,19 @@ 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 9370e47a packages Soul transaction ownership as release sha256-fe3e6c2465017f45649bef61fed1e54b5502f7963c83526fd1f5a791a7a35ac8; exact d4f4f145 packages Mind witness transaction ownership as warning-free 24-binary release sha256-b2490d04a1151d10b8a81b79cd7e56d5544d502829b9b51e1af6cea3a5477d11 with witness sha256-3ac4f12aebe70ae854b9156969ee374838c1e48461357a57632035a18bafd058. The full acceptance-family audit is now source-complete: Soul verdicts, Eyes packets, Continuity recovery receipts, Mind reviews, and Mind commit receipts publish only with the exact coordinator state transaction; their former shape-only writers are test-only. SubstrateGate remains independently writable by its real producers. Seven acceptance tests, focused fixture tests, and production library check pass. Actual c007h remains exact 3a5d2b5e, braked at revision 312 with no active lease and action awaitFrontierProposal. Yggdrasil never builds. + latest_phase: Exact 8ebe56f1 packages the complete acceptance-family ownership cut as warning-free 24-binary release sha256-2707ff42e48dd8640b8a962536972799dca9a1f49346d3b8d05695e7fa826a8e with witness sha256-6003630b550041f90f76ec6261372e6925fd4144ee3daee1d0e2f6864f217289. Live c007h stopped both owners exit zero; c008 runs that exact authenticated Body against the same state/workspace volumes with bounded logs. Braked restart preserved revision 312, no lease, and awaitFrontierProposal. After exact workspace advance, one typed operator pressure launched and failed closed at revision 316 because resident per-turn objective was incorrectly sent through seed-only canonical objective intake; attempt 2 is committed but unclaimed under the re-engaged canonical brake. The source cut now authenticates a resident directive against its exact prepared grant without mutating the Mind-owned canonical objective. Focused resident/standalone tests and coordinator binary check pass. Yggdrasil never builds. operational_state: - local_worktree: exact_d7957b42_actuator_audit_with_current_mind_refresh + local_worktree: resident_directive_ownership_cut_after_live_c008_failure operator_wireguard: restored starfire_persona_permit_firewall: persistent_exact_gamecult_ops_6ee08a4 yggdrasil: canonical_small_public_crossing_body starfire: temporary_epiphany_cognition_body starfire_runtime_identity: epiphany-starfire - starfire_swarm_brake: engaged_in_live_c007h_cognitive_namespace - starfire_release: exact_3a5d2b5e_sha256_84af3da8_live_c007h + starfire_swarm_brake: engaged_in_live_c008_cognitive_namespace + starfire_release: exact_8ebe56f1_sha256_2707ff42_live_c008 starfire_repository_body: bound_and_observed starfire_verse_topology: bound_to_current_repository_body - starfire_native_status: authenticated_braked_c007h_revision_312_no_active_lease + starfire_native_status: authenticated_braked_c008_revision_316_attempt2_unclaimed bifrost: exact_cb3239aa_f67f5122_native_runtime_active_on_yggdrasil bifrost_persona_feedback: ready_on_yggdrasil bifrost_feedback_binding: gamecult_aquarium_to_epiphany_starfire @@ -68,9 +68,9 @@ current_status: starfire_linux_role_cognition: eyes_and_modeling_tools_results_and_acceptance_proven_zero_consequence starfire_linux_modeling_peak: 109887488_bytes_resident_body_plus_modeling_circuit yggdrasil_epiphany_service_contract: repaired_in_gamecult_ops_812b427_not_installed - resident_physiology: c007h_exact_3a5d2b5e_live_braked_revision_312_bounded_local_logs + resident_physiology: c008_exact_8ebe56f1_live_braked_revision_316_bounded_local_logs 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, deterministic incremental release construction, and canonical-brake refusal of direct daemon lifecycle actuation 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 exact 3a5d2b5e c007h braked at revision 312. Commit, push, and package the completed acceptance-family ownership cut, authenticate its exact release, then select a larger live organ-matrix gate from current source rather than continuing fixture-writer archaeology. Do not manufacture frontier work or build on Yggdrasil. + next_action: Keep exact 8ebe56f1 c008 braked with operator attempt 2 committed and unclaimed. Commit, push, and package the resident-directive ownership cut; publish/restart exact c008, release the brake, and require attempt 2 to authenticate the persisted directive, preserve the canonical coordinator objective, and settle once. Re-engage the brake at the next phase boundary. Do not build on Yggdrasil. active_subgoals: - Prove Persona, Self, Eyes, Modeling, Imagination, Hands, Soul, Mind, Continuity, and nervous-system behavior individually.