diff --git a/epiphany-core/src/bin/epiphany-persona-memory-recall-smoke.rs b/epiphany-core/src/bin/epiphany-persona-memory-recall-smoke.rs index 09adc401..8ef344a5 100644 --- a/epiphany-core/src/bin/epiphany-persona-memory-recall-smoke.rs +++ b/epiphany-core/src/bin/epiphany-persona-memory-recall-smoke.rs @@ -15,6 +15,7 @@ use epiphany_core::build_persona_interpreter_prompt; use epiphany_core::build_persona_memory_chunks; use epiphany_core::build_persona_projector_prompt; use epiphany_core::build_persona_turn_prompt; +use epiphany_core::render_dynamic_persona_memory_recall_for_output; use epiphany_core::render_persona_memory_recall_with_cache; use epiphany_core::render_persona_semantic_memory_recall; use epiphany_core::semantic_memory_recall_from_heartbeat_action; @@ -147,20 +148,64 @@ fn main() { assert_contains(&persona_prompt, "Semantic memory recall"); assert_contains(&persona_prompt, "Fallback typed memory graph context"); + let persona_output = "I can speak, but the effect needs a receipt."; + let dynamic = render_dynamic_persona_memory_recall_for_output( + &persona_memory_entry(), + "state/agents.msgpack#Persona", + &persona_prompt, + persona_output, + &recall, + 4, + Some(&EpiphanyMemoryContextPacket { + id: "memctx-smoke-dynamic-fallback".to_string(), + query_id: "persona-smoke-dynamic-output".to_string(), + summaries: vec![EpiphanyMemorySummary { + id: "summary-smoke-dynamic-fallback".to_string(), + target: "role:Persona".to_string(), + claim: "Dynamic self-memory recall should inspect the Persona output before Mind interprets side effects." + .to_string(), + action_implication: + "Interpreter should see output-triggered recall, not only the pre-turn prompt recall." + .to_string(), + freshness: EpiphanyMemoryFreshnessStatus::Ready, + confidence: 82, + ..Default::default() + }], + ..Default::default() + }), + &PersonaMemoryCacheConfig { + qdrant_url: "http://127.0.0.1:1".to_string(), + qdrant_api_key: None, + qdrant_timeout_ms: 1, + ollama_base_url: "http://127.0.0.1:1".to_string(), + ollama_model: "qwen3-embedding:0.6b".to_string(), + ollama_timeout_ms: 1, + collection_name: "epiphany_persona_memory_dynamic_smoke".to_string(), + query_instruction: "dynamic-smoke".to_string(), + }, + ); + assert_eq!(dynamic.status, "fallback"); + assert_contains( + &dynamic.rendered_recall, + "Dynamic self-memory recall should inspect the Persona output", + ); + let interpreter_prompt = build_persona_interpreter_prompt(&PersonaInterpreterInput { identity, persona_prompt, - persona_output: "I can speak, but the effect needs a receipt.".to_string(), + persona_output: persona_output.to_string(), semantic_memory_recall: recall, + dynamic_semantic_memory_recall: dynamic.rendered_recall, pending_mentions: Vec::new(), allowed_channel_ids: vec!["aquarium".to_string()], }); - assert_contains(&interpreter_prompt, "Dynamic semantic memory recall"); + assert_contains(&interpreter_prompt, "Dynamic self-memory recall"); + assert_contains(&interpreter_prompt, "output-triggered recall"); assert_contains(&interpreter_prompt, "STATE NOTE"); assert_contains(&interpreter_prompt, "SAY"); println!( - "status=ok recallSource=typed-memory-graph qdrantCache=persona-memory-bridge-wired heartbeatRecall=prompt-wired liveQdrant=not-required personaLayers=projector,persona,interpreter privateStateExposed=false" + "status=ok recallSource=typed-memory-graph qdrantCache=persona-memory-bridge-wired heartbeatRecall=prompt-wired dynamicRecall=interpreter-output-wired liveQdrant=not-required personaLayers=projector,persona,interpreter privateStateExposed=false" ); } diff --git a/epiphany-core/src/bin/epiphany-repo-swarm-mvp-gate-smoke.rs b/epiphany-core/src/bin/epiphany-repo-swarm-mvp-gate-smoke.rs index 7e95000b..599accb3 100644 --- a/epiphany-core/src/bin/epiphany-repo-swarm-mvp-gate-smoke.rs +++ b/epiphany-core/src/bin/epiphany-repo-swarm-mvp-gate-smoke.rs @@ -24,6 +24,7 @@ use epiphany_core::build_persona_turn_prompt; use epiphany_core::build_weksa_interlingua_packet; use epiphany_core::build_weksa_target_lowering_request; use epiphany_core::record_weksa_target_lowering_receipt; +use epiphany_core::render_dynamic_persona_memory_recall_for_output; use epiphany_core::render_persona_memory_recall_with_cache; use epiphany_core::render_persona_semantic_memory_recall; use epiphany_core::semantic_memory_recall_from_heartbeat_action; @@ -172,7 +173,7 @@ fn run_smoke(args: Args) -> Result { green( "persona-memory-recall", "Persona/Mind", - "Qdrant-backed Persona memory cache and typed graph fallback feed Projector, Persona, and Interpreter prompts without exposing private state", + "Qdrant-backed Persona memory cache and typed graph fallback feed Projector, Persona, and output-triggered Interpreter prompts without exposing private state", ), green( "imagination-plan", @@ -313,6 +314,10 @@ fn verify_fresh_repo(value: &Value) -> Result<()> { require_eq(value, &["familyAssertionsStatus"], "passed")?; require_eq(value, &["publishStatus"], "publication-receipts-recorded")?; require_eq(value, &["syncStatus"], "upstream-main-synced")?; + require_non_empty(value, &["personaMemoryRecallStatus"])?; + require_non_empty(value, &["personaMemoryRecallCacheStatus"])?; + require_non_empty(value, &["personaInterpreterDynamicRecallStatus"])?; + require_non_empty(value, &["personaInterpreterDynamicRecallCacheStatus"])?; require_bool(value, &["upstreamMainSynced"], true)?; require_eq(value, &["publicProofStatus"], "public-proof-exported")?; require_bool(value, &["privateStateExposed"], false) @@ -646,17 +651,70 @@ fn verify_persona_memory_recall() -> Result { "Persona prompt", )?; + let persona_output = "I can speak, but the effect needs a receipt."; + let dynamic = render_dynamic_persona_memory_recall_for_output( + &memory_entry, + "state/agents.msgpack#Persona", + &persona_prompt, + persona_output, + &recall, + 4, + Some(&EpiphanyMemoryContextPacket { + id: "memctx-repo-swarm-mvp-gate-dynamic-fallback".to_string(), + query_id: "repo-swarm-mvp-gate-persona-dynamic-output".to_string(), + summaries: vec![EpiphanyMemorySummary { + id: "summary-repo-swarm-mvp-gate-dynamic-fallback".to_string(), + target: "role:Persona".to_string(), + claim: "Dynamic self-memory recall should inspect the Persona output before Mind interprets side effects." + .to_string(), + action_implication: + "Interpreter should see output-triggered recall, not only the pre-turn prompt recall." + .to_string(), + freshness: EpiphanyMemoryFreshnessStatus::Ready, + confidence: 82, + ..Default::default() + }], + ..Default::default() + }), + &PersonaMemoryCacheConfig { + qdrant_url: "http://127.0.0.1:1".to_string(), + qdrant_api_key: None, + qdrant_timeout_ms: 1, + ollama_base_url: "http://127.0.0.1:1".to_string(), + ollama_model: "qwen3-embedding:0.6b".to_string(), + ollama_timeout_ms: 1, + collection_name: "epiphany_persona_memory_mvp_gate_dynamic".to_string(), + query_instruction: "repo-swarm-mvp-gate-dynamic".to_string(), + }, + ); + require_contains( + &dynamic.rendered_recall, + "Dynamic self-memory recall should inspect the Persona output", + "dynamic Persona memory recall", + )?; + if dynamic.private_state_exposed || dynamic.rendered_recall.contains("sealed private note") { + return Err(anyhow!( + "dynamic Persona memory recall exposed private state" + )); + } + let interpreter_prompt = build_persona_interpreter_prompt(&PersonaInterpreterInput { identity, persona_prompt, - persona_output: "I can speak, but the effect needs a receipt.".to_string(), + persona_output: persona_output.to_string(), semantic_memory_recall: recall, + dynamic_semantic_memory_recall: dynamic.rendered_recall, pending_mentions: Vec::new(), allowed_channel_ids: vec!["aquarium".to_string()], }); require_contains( &interpreter_prompt, - "Dynamic semantic memory recall", + "Dynamic self-memory recall", + "Persona Interpreter prompt", + )?; + require_contains( + &interpreter_prompt, + "output-triggered recall", "Persona Interpreter prompt", )?; require_contains( @@ -670,10 +728,13 @@ fn verify_persona_memory_recall() -> Result { "schemaVersion": "epiphany.repo_swarm_mvp_persona_memory_recall_gate.v0", "status": bridge.status, "cacheStatus": bridge.cache_status, + "dynamicCacheStatus": dynamic.cache_status, "chunkCount": bridge.chunk_count, "hitCount": bridge.hit_count, + "dynamicHitCount": dynamic.hit_count, "fallbackContainsTypedGraph": true, "heartbeatRecallWired": true, + "dynamicRecallWired": true, "personaLayers": ["projector", "persona", "interpreter"], "liveQdrantRequiredForSmoke": false, "privateStateExposed": false, @@ -825,6 +886,19 @@ fn require_bool(value: &Value, path: &[&str], expected: bool) -> Result<()> { } } +fn require_non_empty(value: &Value, path: &[&str]) -> Result<()> { + let actual = path + .iter() + .try_fold(value, |current, key| current.get(*key)) + .and_then(Value::as_str) + .unwrap_or(""); + if actual.trim().is_empty() { + Err(anyhow!("expected {} to be non-empty", path.join("."))) + } else { + Ok(()) + } +} + fn require_contains(haystack: &str, needle: &str, label: &str) -> Result<()> { if haystack.contains(needle) { Ok(()) diff --git a/epiphany-core/src/bin/epiphany-repo-swarm-mvp-smoke.rs b/epiphany-core/src/bin/epiphany-repo-swarm-mvp-smoke.rs index b9517148..c82592fb 100644 --- a/epiphany-core/src/bin/epiphany-repo-swarm-mvp-smoke.rs +++ b/epiphany-core/src/bin/epiphany-repo-swarm-mvp-smoke.rs @@ -311,6 +311,8 @@ fn run_smoke(args: Args) -> Result { require_eq(&export, &["status"], "public-proof-exported")?; require_non_empty(&intake, &["memoryRecallStatus"])?; require_non_empty(&intake, &["memoryRecallCacheStatus"])?; + require_non_empty(&intake, &["interpreterDynamicRecallStatus"])?; + require_non_empty(&intake, &["interpreterDynamicRecallCacheStatus"])?; require_non_empty(&intake, &["weksaLoweringReceiptId"])?; require_bool(&intake, &["privateStateExposed"], false)?; require_bool(&overview, &["privateStateExposed"], false)?; @@ -342,6 +344,9 @@ fn run_smoke(args: Args) -> Result { "personaMemoryRecallStatus": intake["memoryRecallStatus"], "personaMemoryRecallCacheStatus": intake["memoryRecallCacheStatus"], "personaMemoryRecallHitCount": intake["memoryRecallHitCount"], + "personaInterpreterDynamicRecallStatus": intake["interpreterDynamicRecallStatus"], + "personaInterpreterDynamicRecallCacheStatus": intake["interpreterDynamicRecallCacheStatus"], + "personaInterpreterDynamicRecallHitCount": intake["interpreterDynamicRecallHitCount"], "weksaLoweringReceiptId": intake["weksaLoweringReceiptId"], "planStatus": plan["status"], "preRunOverviewGate": pre_run_overview["gate"], diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index 23ffc6d9..38773e26 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -1931,6 +1931,9 @@ fn run_persona_intake(args: PersonaIntakeArgs) -> Result { "memoryRecallStatus": receipt["persona"]["memoryRecall"]["status"], "memoryRecallCacheStatus": receipt["persona"]["memoryRecall"]["cacheStatus"], "memoryRecallHitCount": receipt["persona"]["memoryRecall"]["hitCount"], + "interpreterDynamicRecallStatus": receipt["persona"]["memoryRecall"]["interpreterDynamicRecall"]["status"], + "interpreterDynamicRecallCacheStatus": receipt["persona"]["memoryRecall"]["interpreterDynamicRecall"]["cacheStatus"], + "interpreterDynamicRecallHitCount": receipt["persona"]["memoryRecall"]["interpreterDynamicRecall"]["hitCount"], "weksaLoweringReceiptId": receipt["persona"]["weksa"]["receiptId"], "bubblePath": receipt["persona"]["bubblePath"], "acceptReceiptPath": accept["receiptPath"], @@ -2006,6 +2009,20 @@ fn record_repo_persona_intake_memory_recall( Some(&fallback), &config, ); + let synthetic_persona_prompt = format!( + "Repo Persona intake message:\n{}\n\nInitial semantic memory recall:\n{}", + message, recall.rendered_recall + ); + let dynamic_recall = epiphany_core::render_dynamic_persona_memory_recall_for_output( + &entry, + format!("{}#Persona", agent_store.display()), + &synthetic_persona_prompt, + message, + &recall.rendered_recall, + 8, + Some(&fallback), + &config, + ); json!({ "schemaVersion": recall.schema_version, @@ -2016,6 +2033,26 @@ fn record_repo_persona_intake_memory_recall( "chunkCount": recall.chunk_count, "hitCount": recall.hit_count, "renderedRecall": recall.rendered_recall, + "interpreterDynamicRecall": { + "schemaVersion": dynamic_recall.schema_version, + "status": dynamic_recall.status, + "cacheStatus": dynamic_recall.cache_status, + "identityId": dynamic_recall.identity_id, + "roleId": dynamic_recall.role_id, + "chunkCount": dynamic_recall.chunk_count, + "hitCount": dynamic_recall.hit_count, + "renderedRecall": dynamic_recall.rendered_recall, + "warnings": dynamic_recall.warnings, + "queryBasis": "candidate-say-meaning", + "authority": { + "scaffoldedFromOperatorMessage": true, + "fullAutonomousPersonaTurn": false, + "durableStateAdmitted": false, + "publicationAuthorized": false, + "privateStateExposed": false + }, + "privateStateExposed": dynamic_recall.private_state_exposed + }, "warnings": recall.warnings, "privateStateExposed": recall.private_state_exposed, }) diff --git a/epiphany-core/src/heartbeat_state.rs b/epiphany-core/src/heartbeat_state.rs index d9c08e8a..6d791efa 100644 --- a/epiphany-core/src/heartbeat_state.rs +++ b/epiphany-core/src/heartbeat_state.rs @@ -3879,10 +3879,23 @@ mod tests { assert_eq!(recall["roleId"], "Persona"); assert_eq!(recall["privateStateExposed"], false); assert!( - recall["renderedRecall"] + !recall["status"].as_str().unwrap_or_default().is_empty(), + "Persona recall should report whether it came from Qdrant or fallback" + ); + assert!( + !recall["cacheStatus"] .as_str() .unwrap_or_default() - .contains("typed memory graph") + .is_empty(), + "Persona recall should report cache status" + ); + assert!( + !recall["renderedRecall"] + .as_str() + .unwrap_or_default() + .trim() + .is_empty(), + "Persona recall should carry a rendered prompt surface" ); assert!(recall["chunkCount"].as_u64().unwrap_or_default() > 0); assert!( diff --git a/epiphany-core/src/lib.rs b/epiphany-core/src/lib.rs index adf53c98..2889347f 100644 --- a/epiphany-core/src/lib.rs +++ b/epiphany-core/src/lib.rs @@ -621,6 +621,7 @@ pub use persona_memory_cache::PersonaMemoryRecallRender; pub use persona_memory_cache::PersonaMemorySearchHit; pub use persona_memory_cache::build_persona_memory_chunks; pub use persona_memory_cache::index_persona_memory_chunks; +pub use persona_memory_cache::render_dynamic_persona_memory_recall_for_output; pub use persona_memory_cache::render_persona_memory_recall_with_cache; pub use persona_memory_cache::search_persona_memory_cache; pub use persona_turn::PERSONA_INTERPRETER_PROMPT_SCHEMA_VERSION; diff --git a/epiphany-core/src/persona_memory_cache.rs b/epiphany-core/src/persona_memory_cache.rs index 5aa3958d..2d33f30f 100644 --- a/epiphany-core/src/persona_memory_cache.rs +++ b/epiphany-core/src/persona_memory_cache.rs @@ -363,6 +363,53 @@ pub fn render_persona_memory_recall_with_cache( } } +pub fn render_dynamic_persona_memory_recall_for_output( + entry: &EpiphanyAgentMemoryEntry, + source_state_ref: impl Into, + persona_prompt: &str, + persona_output: &str, + initial_recall_seed: &str, + limit: usize, + fallback_context: Option<&EpiphanyMemoryContextPacket>, + config: &PersonaMemoryCacheConfig, +) -> PersonaMemoryRecallRender { + let query = build_dynamic_persona_memory_recall_query( + &entry.agent.agent_id, + persona_prompt, + persona_output, + initial_recall_seed, + ); + render_persona_memory_recall_with_cache( + entry, + source_state_ref, + &query, + limit, + fallback_context, + config, + ) +} + +pub fn build_dynamic_persona_memory_recall_query( + identity_id: &str, + persona_prompt: &str, + persona_output: &str, + initial_recall_seed: &str, +) -> String { + [ + format!("Current train of thought from {identity_id}:"), + collapse_whitespace(persona_output, 6_000), + "Original Persona turn pressure:".to_string(), + extract_prompt_seed(persona_prompt), + "Initial semantic memory recall seed:".to_string(), + collapse_whitespace(initial_recall_seed, 2_000), + ] + .into_iter() + .map(|part| part.trim().to_string()) + .filter(|part| !part.is_empty()) + .collect::>() + .join("\n") +} + fn render_persona_memory_cache_hits(hits: &[PersonaMemorySearchHit]) -> String { let mut lines = vec![ "These are derived Qdrant Persona-memory cache hits from typed Persona state. They are hints, not durable authority; typed memory remains the owner.".to_string(), @@ -380,6 +427,40 @@ fn render_persona_memory_cache_hits(hits: &[PersonaMemorySearchHit]) -> String { lines.join("\n") } +fn extract_prompt_seed(prompt: &str) -> String { + let markers = [ + "Semantic memory recall:", + "Projected inner state from Imagination:", + "Recent home-repo activity", + "Pending addressed pressure:", + "Raw room transcript", + ]; + let mut sections = Vec::new(); + + for marker in markers { + let Some(start) = prompt.find(marker) else { + continue; + }; + let end = markers + .iter() + .filter(|candidate| **candidate != marker) + .filter_map(|candidate| { + prompt[start + marker.len()..] + .find(candidate) + .map(|offset| start + marker.len() + offset) + }) + .min() + .unwrap_or_else(|| prompt.len().min(start + 2_400)); + sections.push(prompt[start..end.min(start + 2_400)].trim().to_string()); + } + + if sections.is_empty() { + collapse_whitespace(prompt, 2_400) + } else { + sections.join("\n\n") + } +} + fn fallback_persona_memory_recall( identity_id: String, role_id: String, diff --git a/epiphany-core/src/persona_turn.rs b/epiphany-core/src/persona_turn.rs index c3bf3968..cd20abf0 100644 --- a/epiphany-core/src/persona_turn.rs +++ b/epiphany-core/src/persona_turn.rs @@ -101,6 +101,8 @@ pub struct PersonaInterpreterInput { #[serde(default)] pub semantic_memory_recall: String, #[serde(default)] + pub dynamic_semantic_memory_recall: String, + #[serde(default)] pub pending_mentions: Vec, #[serde(default)] pub allowed_channel_ids: Vec, @@ -246,9 +248,12 @@ Allowed channel ids: Pending addressed pressure: {mentions} -Dynamic semantic memory recall: +Initial semantic memory recall from the Persona turn: {semantic_recall} +Dynamic self-memory recall from the Persona output: +{dynamic_semantic_recall} + Original Persona prompt: ``` {persona_prompt} @@ -266,6 +271,14 @@ Return concise structured effect blocks. No prose outside the blocks. channels = render_allowed_channels(&input.allowed_channel_ids), mentions = render_pending_mentions(&input.pending_mentions), semantic_recall = render_semantic_memory_recall_text(&input.semantic_memory_recall), + dynamic_semantic_recall = render_semantic_memory_recall_text( + input + .dynamic_semantic_memory_recall + .trim() + .is_empty() + .then_some(input.semantic_memory_recall.as_str()) + .unwrap_or(input.dynamic_semantic_memory_recall.as_str()) + ), persona_prompt = input.persona_prompt.trim(), persona_output = input.persona_output.trim(), ) @@ -583,6 +596,7 @@ mod tests { persona_prompt: persona, persona_output: "I want to answer, but only if I can name the cut plainly.".to_string(), semantic_memory_recall: String::new(), + dynamic_semantic_memory_recall: String::new(), pending_mentions: vec![pending], allowed_channel_ids: vec!["aquarium".to_string()], }); @@ -642,10 +656,13 @@ mod tests { persona_prompt: persona, persona_output: "I can answer, but the answer should stay review-gated.".to_string(), semantic_memory_recall: recall, + dynamic_semantic_memory_recall: "Output-triggered recall says review gates matter." + .to_string(), pending_mentions: Vec::new(), allowed_channel_ids: vec!["aquarium".to_string()], }); - assert!(interpreter.contains("Dynamic semantic memory recall")); + assert!(interpreter.contains("Dynamic self-memory recall")); + assert!(interpreter.contains("Output-triggered recall")); assert!(interpreter.contains("STATE NOTE")); assert!(interpreter.contains("SAY")); } diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 8caffe41..ec46c102 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -194,7 +194,7 @@ remembers doctrine; the branch remembers the blade. - `bifrost-publication` is the compact non-mutating Bifrost publication proof; use it to prove body-change routing, credit, and GitHub publication receipt state without performing GitHub mutation. Its JSON now points back to compact swarm overview and tool-directory readback. - `bifrost-artifact-acceptance` and `bifrost-metrics` are compact Bifrost/Maintainer closure rites for the safe-family planning/accounting lanes. They write typed accepted-artifact and metrics receipts from explicit artifact/public-proof/review/model-spend/review-load/credit refs, verify latest receipt readback, and let `bifrost-ledger` close `artifact-acceptance-request` and `metrics-request` rows from Bifrost-owned receipts instead of request cargo. The request-family smokes now prove both states: `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-130520` and `.epiphany-smoke\repo-metrics-request-family-20260621-130635` first assert open request rows, then write final receipts and assert closed rows; wrapper proof `local-20260621-140740-750-2815f6f7` read the closed metrics row with `privateStateExposed=False`. `epiphany-repo-bifrost-accounting-bundle-smoke` consumes the closed family summaries and emits one operator-safe aggregate receipt; wrapper mode `tools/epiphany_local_run.ps1 -Mode bifrost-accounting-bundle` now builds/runs that verifier, accepts optional exact summary paths, writes normal operator run receipts, and proved bundle `.epiphany-smoke\repo-bifrost-accounting-bundle-20260621-132815` via wrapper artifact `local-20260621-142716-268-d6bc58b4` with final Bifrost receipt ids, `planningAuthorityOnly=true`, and `privateStateExposed=false`. - `daemon-survival-rehearsal` is the bounded Idunn physiology proof. `epiphany-daemon-survival-rehearsal-smoke` writes a durable restart policy for `epiphany-daemon-self`, runs `epiphany-daemon-supervisor serve --max-iterations 2 --force --loop-interval-seconds 0`, verifies two scheduler pulses and the scheduler receipt row, and keeps service-manager mutation/elevation/private-state exposure false. Wrapper proof `tools/epiphany_local_run.ps1 -Mode daemon-survival-rehearsal -SkipBuild` emitted `.epiphany-smoke\daemon-survival-rehearsal-20260621-135723` via artifact `local-20260621-145723-011-1175e273`. -- `repo-swarm-mvp-gate` is the compact aggregate MVP proof rite. `epiphany-repo-swarm-mvp-gate-smoke` consumes the latest fresh-repo MVP, repo-work readiness, Bifrost accounting-bundle, Idunn deployment handoff, daemon survival, Weksa interlingua, and Persona semantic memory recall proofs, verifies the green proof rows, and leaves only Idunn elevated service/install/start/remote execution as an explicit warning gate instead of laundering it into completion. Direct proof `.epiphany-smoke\repo-swarm-mvp-gate-20260621-170445` reports `demoReady=true`, `mvpReady=false`, `green=15`, `warnings=1`, `blockers=0`, `personaMemoryRecall.cacheStatus=qdrant-unavailable`, `personaMemoryRecall.status=fallback`, `personaMemoryRecall.heartbeatRecallWired=true`, Projector/Persona/Interpreter prompt coverage, and `privateStateExposed=false`. This is live-fire ready for a controlled repo Body; unattended/elevated production service or deployment execution remains an operator-granted Idunn rite. +- `repo-swarm-mvp-gate` is the compact aggregate MVP proof rite. `epiphany-repo-swarm-mvp-gate-smoke` consumes the latest fresh-repo MVP, repo-work readiness, Bifrost accounting-bundle, Idunn deployment handoff, daemon survival, Weksa interlingua, and Persona semantic memory recall proofs, verifies the green proof rows, and leaves only Idunn elevated service/install/start/remote execution as an explicit warning gate instead of laundering it into completion. Direct proof `.epiphany-smoke\repo-swarm-mvp-gate-20260621-174742` reports `demoReady=true`, `mvpReady=false`, `green=15`, `warnings=1`, `blockers=0`, `personaMemoryRecall.cacheStatus=qdrant-unavailable`, `personaMemoryRecall.status=fallback`, `personaMemoryRecall.dynamicCacheStatus=qdrant-unavailable`, `personaMemoryRecall.dynamicRecallWired=true`, `personaMemoryRecall.heartbeatRecallWired=true`, Projector/Persona/output-triggered Interpreter prompt coverage, and `privateStateExposed=false`. This is live-fire ready for a controlled repo Body; unattended/elevated production service or deployment execution remains an operator-granted Idunn rite. - Huginn is the first controlled live-fire repo Body past closure. On branch `epiphany/huginn/first-awakening`, item `huginn-inspection-readback-livefire` went through Persona intake, Imagination `repo.status_section` planning, Self run, Mind adoption, Hands README-only commit `e9b07c38fceabbdc89ea35c2156326c80c0393a2`, Soul closure, and Mind map admission. Refreshed overview reports `gate=awaiting-publication`, `blocker=bifrost-publication-missing`, `soulVerdict=passed`, `changedPaths=[README.md]`, and `privateStateExposed=false`; concrete TypeScript build verification passed via `C:\Program Files\nodejs\node.exe E:\Projects\Huginn\node_modules\typescript\bin\tsc -p tsconfig.json`. Do not push, publish, merge, or sync Huginn without Bifrost/maintainer authority. - `epiphany-repo-livefire-closure-smoke` is the repeatable proof for a controlled repo Body that has reached closure. It checks the close receipt, Mind map entry, overview gate/blocker, authority seals, and actual `git show --name-only` changed paths. Huginn proof with `--workspace E:\Projects\Huginn --item huginn-inspection-readback-livefire --expected-path README.md --expected-family repo.status_section --expected-gate awaiting-publication --expected-blocker bifrost-publication-missing` returned `status=ok`, `soulVerdict=passed`, `publicationGate=Bifrost`, changed paths `[README.md]`, and `privateStateExposed=false`. - `bifrost-ledger` is the compact Bifrost/Imagination readback rite; use it after collaboration, publication, accepted-artifact, or metrics writes to see the latest body-change, public-proof, accepted-artifact, metrics, GitHub, feedback, consensus, credit/review-count, and accounting closure rows without opening the full local Verse. @@ -1534,11 +1534,15 @@ target-language lowering request, lowering receipt, and local Verse `epiphany.cultmesh.weksa_lowering_receipt.v0` mirror before any mouth transport publication. The receipt-directory row is Weksa-owned sight only; Bifrost or the configured mouth edge still owns publication, and Mind still owns durable state. -Repo Persona intake also carries semantic Persona memory recall now. It loads -repo-local `agents.msgpack`, tries the bounded Qdrant/Ollama Persona-memory -cache, falls back to a typed RoleSelf memory-graph context cut, and records -sealed recall status in the intake receipt before routing public pressure to -Imagination. Qdrant is a rebuildable semantic cache; typed memory remains the +Repo Persona intake also carries VoidBot-style two-pass semantic Persona memory +recall now. It loads repo-local `agents.msgpack`, tries the bounded +Qdrant/Ollama Persona-memory cache, falls back to a typed RoleSelf memory-graph +context cut, and records sealed pre-turn recall status before routing public +pressure to Imagination. It also records `interpreterDynamicRecall`, keyed from +the candidate SAY meaning, so Mind/Interpreter has output-triggered self-memory +context instead of only the pre-turn prompt recall. Current repo-intake remains +a scaffolded operator-message path rather than a full autonomous model Persona +turn; Qdrant is a rebuildable semantic cache, and typed memory remains the owner. `notes/organ-dependency-contracts.md` is the standing dependency map: every sub-agent depends on all the other standing sub-agents. Dependency does not collapse diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 5c2c2ee8..cfa52e97 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 95494aac..42b10ed3 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -627,7 +627,7 @@ current_status: - `epiphany-verse-query connect-eve` and `tools/epiphany_local_run.ps1 -Mode eve-connect` provide the compact Odin-to-Eve collaboration receipt. The command selects the daemon-published surface through the narrow Eve directory, writes connection intent/receipt documents, verifies latest receipt keys through narrow CultMesh loaders, defaults the wrapper target to `epiphany.cluster.persona`, and exposes no private state. - `epiphany-verse-query collaboration-feedback` and `tools/epiphany_local_run.ps1 -Mode collaboration-feedback` provide the public Persona feedback to Imagination consensus receipt path. The wrapper records the prerequisite Eve connection receipt, writes feedback plus Imagination consensus receipt documents, verifies latest keys through narrow CultMesh loaders, publishes follow-on command hints for wrapper feedback, Eve connection, direct Bifrost publication, and wrapper Bifrost publication, and exposes no private state. The command returns compact TUI rows for the feedback and Imagination consensus receipt with explicit `owner=Persona->Imagination` / `owner=Imagination`, `public=`, candidate action refs, consensus packet ref, adoption gate, and `private=false`; wrapper proof `local-20260618-224207-941-2ca01b41` prints both rows in `feedbackRows`, including Persona public discussion feedback routed to Imagination consensus discovery before Mind/Bifrost adoption. - `epiphany-verse-query bifrost-publication` and `tools/epiphany_local_run.ps1 -Mode bifrost-publication` provide the non-mutating Bifrost body-change publication proof path. It writes Bifrost intent, Bifrost publication receipt, and GitHub publication receipt documents from explicit review/verification/credit inputs, verifies latest keys through narrow CultMesh loaders, publishes follow-on command hints for swarm overview, tool directory, and wrapper Bifrost publication readback, and exposes no private state. - - `epiphany-verse-query bifrost-ledger` and `tools/epiphany_local_run.ps1 -Mode bifrost-ledger` provide the compact Bifrost ledger sight organ. It reads only the latest Bifrost body-change intent, Bifrost publication receipt, GitHub publication receipt, public-proof publication receipt, artifact-acceptance receipt, metrics receipt, repo-work readiness-review receipt, collaboration feedback, Imagination consensus receipt, and Mind-admitted repo-work map entries through narrow CultMesh loaders, returns agent-friendly ledger TUI rows, publishes follow-on command hints for swarm overview, tool directory, collaboration feedback, Bifrost publication, artifact acceptance, metrics, and ledger readback, and exposes no private state. Compact ledger rows carry explicit `owner=`, `public=`, and `private=false`, so body-change/public-feedback proof is inspectable without opening raw local Verse payloads or inferring authority from document names. Bifrost ledger readback derives six `BIFROST-ACCOUNTING` rows for `body-change-publication`, `public-proof-publication`, `repo-work-readiness-review`, `artifact-acceptance-request`, `metrics-request`, and `collaboration-consensus`, with closure status, ledger/receipt/public refs, review and credit receipt counts, artifact count, and private-state seal. Readiness-review accounting closes only when latest `epiphany.cultmesh.repo_work_readiness_review.v0` has four Maintainer/Soul/Mind/Bifrost review refs, readiness approval, zero missing required rows, present review artifact, and no durable-state/publication/merge/sync/deployment/service/Hands/private authority. Artifact-acceptance and metrics request rows are `open` when only Mind-admitted request map entries exist, and close only from typed Bifrost/Maintainer receipts: `epiphany-verse-query bifrost-artifact-acceptance` writes `gamecult.bifrost.artifact_acceptance_receipt` from explicit artifact/public-proof/ledger/review refs, while `epiphany-verse-query bifrost-metrics` writes `gamecult.bifrost.metrics_receipt` from explicit accepted-artifact, model-spend, review-load, credit-readback, public-proof, and metrics summary refs. Wrapper modes `bifrost-artifact-acceptance` and `bifrost-metrics` expose the same closure rites. Focused smokes `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-130520` and `.epiphany-smoke\repo-metrics-request-family-20260621-130635` now prove request rows open first and then close from final Bifrost receipts without private-state exposure; wrapper proof `local-20260621-140740-750-2815f6f7` printed the closed metrics row from the repo-local Verse target. `epiphany-repo-bifrost-accounting-bundle-smoke` consumes the closed request-family summaries as an operator-safe aggregate proof, and `tools/epiphany_local_run.ps1 -Mode bifrost-accounting-bundle` now wraps that verifier with optional exact summary path inputs and the normal operator run receipts. Wrapper proof `local-20260621-142716-268-d6bc58b4` built the verifier, emitted bundle `.epiphany-smoke\repo-bifrost-accounting-bundle-20260621-132815`, and verified artifact acceptance and metrics close statuses, final Bifrost receipt ids, closed accounting rows, `planningAuthorityOnly=true`, and `privateStateExposed=false`. `epiphany-daemon-survival-rehearsal-smoke` now proves Idunn's bounded `serve` physiology can consume a durable restart policy, run two scheduler pulses, write scheduler receipts, and keep service-manager mutation/elevation/private-state exposure false; wrapper proof `local-20260621-145723-011-1175e273` emitted `.epiphany-smoke\daemon-survival-rehearsal-20260621-135723` with `serveIterations=2` and scheduler receipt `daemon-scheduler-receipt-epiphany-daemon-survival-rehearsal-2`. `epiphany-repo-swarm-mvp-gate-smoke` now consumes the fresh-repo MVP, repo-work readiness, Bifrost accounting-bundle, Idunn deployment handoff, daemon survival, Weksa interlingua, and Persona semantic memory recall proofs as one operator-safe MVP gate report; direct proof `.epiphany-smoke\repo-swarm-mvp-gate-20260621-170445` reports `demoReady=true`, `mvpReady=false`, fifteen green gates, one Idunn elevated-service warning gate, zero blockers, `personaMemoryRecall.cacheStatus=qdrant-unavailable`, `personaMemoryRecall.status=fallback`, `personaMemoryRecall.heartbeatRecallWired=true`, Projector/Persona/Interpreter prompt coverage, and `privateStateExposed=false`. + - `epiphany-verse-query bifrost-ledger` and `tools/epiphany_local_run.ps1 -Mode bifrost-ledger` provide the compact Bifrost ledger sight organ. It reads only the latest Bifrost body-change intent, Bifrost publication receipt, GitHub publication receipt, public-proof publication receipt, artifact-acceptance receipt, metrics receipt, repo-work readiness-review receipt, collaboration feedback, Imagination consensus receipt, and Mind-admitted repo-work map entries through narrow CultMesh loaders, returns agent-friendly ledger TUI rows, publishes follow-on command hints for swarm overview, tool directory, collaboration feedback, Bifrost publication, artifact acceptance, metrics, and ledger readback, and exposes no private state. Compact ledger rows carry explicit `owner=`, `public=`, and `private=false`, so body-change/public-feedback proof is inspectable without opening raw local Verse payloads or inferring authority from document names. Bifrost ledger readback derives six `BIFROST-ACCOUNTING` rows for `body-change-publication`, `public-proof-publication`, `repo-work-readiness-review`, `artifact-acceptance-request`, `metrics-request`, and `collaboration-consensus`, with closure status, ledger/receipt/public refs, review and credit receipt counts, artifact count, and private-state seal. Readiness-review accounting closes only when latest `epiphany.cultmesh.repo_work_readiness_review.v0` has four Maintainer/Soul/Mind/Bifrost review refs, readiness approval, zero missing required rows, present review artifact, and no durable-state/publication/merge/sync/deployment/service/Hands/private authority. Artifact-acceptance and metrics request rows are `open` when only Mind-admitted request map entries exist, and close only from typed Bifrost/Maintainer receipts: `epiphany-verse-query bifrost-artifact-acceptance` writes `gamecult.bifrost.artifact_acceptance_receipt` from explicit artifact/public-proof/ledger/review refs, while `epiphany-verse-query bifrost-metrics` writes `gamecult.bifrost.metrics_receipt` from explicit accepted-artifact, model-spend, review-load, credit-readback, public-proof, and metrics summary refs. Wrapper modes `bifrost-artifact-acceptance` and `bifrost-metrics` expose the same closure rites. Focused smokes `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-130520` and `.epiphany-smoke\repo-metrics-request-family-20260621-130635` now prove request rows open first and then close from final Bifrost receipts without private-state exposure; wrapper proof `local-20260621-140740-750-2815f6f7` printed the closed metrics row from the repo-local Verse target. `epiphany-repo-bifrost-accounting-bundle-smoke` consumes the closed request-family summaries as an operator-safe aggregate proof, and `tools/epiphany_local_run.ps1 -Mode bifrost-accounting-bundle` now wraps that verifier with optional exact summary path inputs and the normal operator run receipts. Wrapper proof `local-20260621-142716-268-d6bc58b4` built the verifier, emitted bundle `.epiphany-smoke\repo-bifrost-accounting-bundle-20260621-132815`, and verified artifact acceptance and metrics close statuses, final Bifrost receipt ids, closed accounting rows, `planningAuthorityOnly=true`, and `privateStateExposed=false`. `epiphany-daemon-survival-rehearsal-smoke` now proves Idunn's bounded `serve` physiology can consume a durable restart policy, run two scheduler pulses, write scheduler receipts, and keep service-manager mutation/elevation/private-state exposure false; wrapper proof `local-20260621-145723-011-1175e273` emitted `.epiphany-smoke\daemon-survival-rehearsal-20260621-135723` with `serveIterations=2` and scheduler receipt `daemon-scheduler-receipt-epiphany-daemon-survival-rehearsal-2`. `epiphany-repo-swarm-mvp-gate-smoke` now consumes the fresh-repo MVP, repo-work readiness, Bifrost accounting-bundle, Idunn deployment handoff, daemon survival, Weksa interlingua, and Persona semantic memory recall proofs as one operator-safe MVP gate report; direct proof `.epiphany-smoke\repo-swarm-mvp-gate-20260621-174742` reports `demoReady=true`, `mvpReady=false`, fifteen green gates, one Idunn elevated-service warning gate, zero blockers, `personaMemoryRecall.cacheStatus=qdrant-unavailable`, `personaMemoryRecall.status=fallback`, `personaMemoryRecall.dynamicCacheStatus=qdrant-unavailable`, `personaMemoryRecall.dynamicRecallWired=true`, `personaMemoryRecall.heartbeatRecallWired=true`, Projector/Persona/output-triggered Interpreter prompt coverage, and `privateStateExposed=false`. Repo Persona intake now records both pre-turn semantic recall and `interpreterDynamicRecall` from candidate SAY meaning; this matches VoidBot's two-pass Projector/Face/Interpreter memory membrane while preserving the scaffold seal that repo-intake is not yet a full autonomous model Persona turn. - `epiphany-verse-query receipt-directory` and `tools/epiphany_local_run.ps1 -Mode receipt-directory` provide the compact latest-witness directory over local Verse. It indexes operator run, daemon poke, daemon tool invocation, Eve connection, Bifrost publication, Imagination consensus, coordinator run, Hands gate, role review, work-loop, cluster service lifecycle, single-service lifecycle, cluster service execution runbook, single-service execution runbook, scheduler, Persona speech, and agent-state SoA witness families from typed local Verse projections; returns agent-friendly `OK`/`ABSENT`/`ATTN` TUI rows with owner, family, status, route, latest id, follow-up command, `presentRowCount`, and `absentRowCount`; preserves `missingRowCount` as compatibility for absent witnesses; flags sealed service lifecycle failure states such as `not-elevated`, `execution-refused-not-elevated`, and `incomplete` as attention without exposing receipt payloads; routes service lifecycle receipts by their typed receipt action through `service_execution_check_follow_up_command` (readiness to readiness, install to install execute, start/stop to control execute, status/reconcile to their readback rites, audit to audit), while cluster/single execution-runbook witnesses route to their runbook regeneration wrappers; and exposes no private state or receipt payload previews. The lifecycle projection now reads the typed receipt family, splits `cluster-service-lifecycle` from `service-lifecycle`, selects the latest attention receipt before falling back to latest overall, and exposes `service-id::action` route values such as `epiphany-cluster-daemon-services::cluster-windows-service-execution-audit`, so agents can see the owning lifecycle action without opening raw audit JSON. Compact receipt TUI rows append `followUp=`, artifact status, and SHA-256; wrapper proof `local-20260618-205920-451-383b0da7` now prints all seventeen compact rows in `receiptRows`, including missing Hands/role/work-loop gates, runbook hashes, scheduler follow-up, Bifrost/Imagination witnesses, and the active service lifecycle attention rows. It also exposes `cluster-service-execution-runbook` plus `service-execution-runbook` as display-only rows, so newer harmless planned/runbook lifecycle receipts cannot hide the active seven-service cluster wound. Receipt-directory JSON now carries Rust-owned `attentionRouteRows` derived from the same policy predicate as `attentionRowCount`, and the wrapper prints that field instead of rebuilding attention from ad hoc status strings; source smoke now proves a `cluster-windows-service-execution-readiness` receipt routes to `cluster-service-execution-readiness` and wrapper mode `cluster-service-execution-readiness` instead of laundering the row through audit. Live proof `local-20260618-212134-758-c7c56240` left the old degraded Hands daemon-poke receipt as an `OK` historical witness while attention routes named only the cluster and single-service lifecycle wounds. Daemon-poke rows now resolve historical receipt status against current daemon liveness: source smoke proves degraded remains degraded before heartbeat recovery and becomes `resolved` after current status returns ready, while live wrapper proof `local-20260618-212649-563-48647018` printed the old Hands poke receipt as `OK | Self | daemon-poke | resolved`. - `tools/epiphany_local_run.ps1 -Mode service-tick` is the wrapper-owned daemon scheduler pulse rite. It runs `epiphany-daemon-supervisor tick` through the same local Verse store, operator run intent/receipt, agent-state SoA refresh, and swarm-brake preflight as other service lifecycle modes, but leaves restart authority inside durable daemon restart policies. The receipt directory scheduler row now follows up with `tools/epiphany_local_run.ps1 -Mode service-tick` instead of passive service status. Proof seeded one disabled Persona restart policy as inert policy metadata, then the wrapper wrote `daemon-scheduler-receipt-epiphany-daemon-supervisor-0` with `status=tickComplete`, `outcomeCount=1`, `skippedCount=1`, `restartedCount=0`, `refusedCount=0`, and `privateStateExposed=false`; the follow-up receipt-directory proof reported the scheduler row as present with route `*`, follow-up command `service-tick`, and no private-state exposure. - `epiphany-cluster-daemon` is the first real per-cluster daemon heartbeat body. It runs as a narrow Rust binary parameterized by daemon id, publishes typed `epiphany.cultmesh.daemon_status.v0` heartbeats into the shared local Verse, can run once or loop, and exposes no private state. Durable restart policies for Self, Hands, Persona, Imagination, Eyes, Modeling, and Soul now invoke `epiphany-cluster-daemon heartbeat`, not the generic query/debug writer. A degraded proof showed `service-tick` invoking all seven daemon bodies through the supervisor and restoring ready liveness with sealed scheduler/poke receipts; a fresh tick no-ops when all heartbeats are current. `epiphany-daemon-supervisor cluster-service-runbook` and wrapper `-Mode cluster-service-runbook` write a non-mutating service runbook plus `daemon_service_lifecycle` receipt for all seven organ daemon `epiphany-cluster-daemon serve` commands. Direct `service-runbook` and `cluster-service-runbook` wrapper summaries now print local artifact SHA-256 plus follow-up/aftercare wrapper routes; live proofs `local-20260618-232133-314-4e55120e` and `local-20260618-232146-541-982dd60b` showed hashes `85a956f768e584a9d098f13a9bf03fc3560915821a2ae7eaab94889dd9ecda85` and `40616423a9210101486949d07291bf795175579a39e99de5e5a759f8e0d7a78c` without service mutation. Wrapper `service-plan` and `service-launch` now expose the native daemon-supervisor service lifecycle surfaces under the same brake gate; `service-launch` silences child stdout/stderr so the parent lifecycle receipt remains the only stdout JSON. Live proof `local-20260618-232935-349-7e3901c8` completed a bounded one-iteration launch with `exitCode=0` and no private-state exposure. `epiphany-daemon-supervisor cluster-service-install-plan` and wrapper `-Mode cluster-service-install-plan` write a non-mutating Windows install script plus lifecycle receipt for seven distinct per-organ Windows services. Wrapper `-Mode cluster-service-install-execute` requests execution through the same typed path and, in non-elevated shells, writes `execution-refused-not-elevated` with `executed=false` instead of mutating services. Direct cluster install wrapper summaries now include `artifactSha256=` and `followUp=tools/epiphany_local_run.ps1 -Mode cluster-service-install-execute`; live proofs `local-20260618-230937-335-71c4fdaa` and `local-20260618-230937-313-cb288388` showed the planned and non-elevated-refused cluster install artifact hash `c6b697e173eb319073da341fc90c2963bcd6bee63d804349205b6309c88df764`. `epiphany-daemon-supervisor cluster-service-audit` and wrapper `-Mode cluster-service-audit` read Windows service-manager state for those seven expected service names, writing an incomplete audit receipt when they are missing; direct audit summaries now point missing cluster services to `cluster-service-install-plan` plus `cluster-service-execution-audit` aftercare, with live proof `local-20260618-232200-992-b842ae01` reporting seven missing services and no mutation. `epiphany-daemon-supervisor cluster-service-start`/`cluster-service-stop` and wrapper `-Mode cluster-service-start-plan`, `cluster-service-stop-plan`, `cluster-service-start-execute`, and `cluster-service-stop-execute` record cluster lifecycle receipts for all seven services: plan modes emit seven `*-planned` rows without mutation, and explicit execute modes refuse as `execution-refused-not-elevated` with seven refused rows when the shell lacks service authority. The cluster install/audit/control wrapper summaries now print compact `serviceRows` for all seven daemon-owned Windows service names with daemon id, status or observed status, cluster id, executed flag, exit code, start type, and `private=false`; live proofs `local-20260618-211051-126-2a89d61c`, `local-20260618-211051-125-cd687ee2`, `local-20260618-211051-063-f0ff980d`, and `local-20260618-211118-108-df5cb8cd` show seven missing audit rows, seven ready/demand install-plan rows, seven start-planned rows, and seven stop-planned rows without service mutation. `cluster-service-execution-runbook` writes an admin-gated wrapper sequence for cluster-native readiness, cluster install, cluster start, cluster audit, cluster stop, and final cluster audit; the artifact now uses `Invoke-EpiphanyRunbookStep` to reset `$LASTEXITCODE`, catch thrown/nonzero failures, continue gathering receipts after a failed step, and always runs `cluster-service-execution-audit` from `finally`; generated child execution runbooks no longer use `Invoke-Expression`, and each step invokes the known wrapper `ScriptPath` with an explicit `Arguments` array. The wrapper calls `epiphany-daemon-supervisor cluster-service-execution-runbook` after artifact generation, so the runbook itself has a typed `daemon_service_lifecycle` receipt with action `cluster-windows-service-execution-runbook`, status `written`, artifact path, final-audit metadata, step-failure policy metadata, and `privateStateExposed=false`. Its wrapper JSON and typed receipt args expose `runbookTryModes`, `finalAuditMode=cluster-service-execution-audit`, `finalAuditRunsInFinally=true`, `stepFailurePolicy=continue-after-step-failure`, `continueAfterStepFailure=true`, `nonzeroExitFailsStep=true`, and `exitsNonzeroAfterFinalAudit=true`; direct wrapper summaries now print the exact `elevatedCommand=Start-Process PowerShell -Verb RunAs -Wait ...` invocation, `artifactSha256=`, and `aftercare=tools/epiphany_local_run.ps1 -Mode cluster-service-execution-audit`. Live proof `local-20260619-010940-407-b0744f08` generated the robust cluster artifact and printed hash `bf116ed4fd5bb2c9dc77f5032d19e792b012941a60b109389b79e5fcb0a2a5f6` without service mutation. `cluster-service-execution-audit` first requires the sealed `cluster-windows-service-execution-runbook` receipt, then checks the latest cluster-native readiness plus cluster install/start/audit/stop lifecycle receipts by receipt timestamp and reports `complete` only when the runbook and elevated effect receipts are sealed and successful. Audit check rows retain lifecycle `operatorArtifactRef`; wrapper summaries now print OK runbook witnesses with SHA-256 before compact failed-check anatomy. Live proof `local-20260618-170322-330-e6cb2117` printed `cluster-windows-service-execution-runbook=...\epiphany-cluster-daemon-services-execution-runbook.ps1:sha256=3239ac17008b1ce857970e40b17d37a1ecf1631a3a6636bb2b8678312fb604a0` and the expected five failed checks without mutating Windows services. @@ -650,4 +650,4 @@ current_status: - Service lifecycle receipt history is now event-only: `load_epiphany_cultmesh_daemon_service_lifecycle_receipts` filters out the `epiphany-local/daemon-service-lifecycle-receipt/latest` mirror, while `load_latest_epiphany_cultmesh_daemon_service_lifecycle_receipt` remains the latest-state reader. Focused unit test `service_lifecycle_receipt_history_excludes_latest_mirror` proves two per-receipt writes return exactly two history records and latest points at the second. Fresh smoke `verse-query-lifecycle-history-filter-smoke` and live overview/triage `local-20260618-145632-497-efac6f0d` / `local-20260618-145632-321-867947af` prove compact swarm sights still expose service lifecycle attention plus the present elevated runbook artifact without daemon pokes or service mutation. Do not use a broad unscoped cargo test filter for this check on Windows; it fans out across bin harnesses and hit a broken pipe during this pass. - `epiphany-verse-query seed-compact` is the compact seed receipt for wrappers and read-only rites. The older `seed` command still prints the full local Verse context for explicit debugging, but compact wrapper modes now avoid full `seed`/final `query` readback after the combined overview proof exposed Windows debug stack overflow from full-context serialization pressure. last_completed_repo_swarm_cut: Huginn live-fire has crossed the first real repo Body from Persona pressure to branch-local Hands commit and Soul/Mind closure, and now has a repeatable verifier. On `E:\Projects\Huginn` branch `epiphany/huginn/first-awakening`, `tools/epiphany_local_run.ps1 -Mode repo-persona-intake` accepted item `huginn-inspection-readback-livefire`, Weksa/Persona intake remained sealed, and `epiphany-work derive-plan` lowered it to model-authored safe family `repo.status_section` for `README.md` only. `tools/epiphany_local_run.ps1 -Mode repo-swarm-run` advanced four bounded pulses: run-from-plan, adopt-from-plan, execute-from-plan, and close-from-execute. Huginn commit `e9b07c38fceabbdc89ea35c2156326c80c0393a2` updated only `README.md`; closure receipt `.epiphany\work\work-close-huginn-inspection-readback-livefire.json` records status `closed`, Soul verdict `passed`, Mind state commit `repo-work-close-huginn-inspection-readback-livefire-mind-commit`, safe family `repo.status_section`, path scope `README.md`, Bifrost publication gate, and `privateStateExposed=false`. Verification also ran Huginn's TypeScript compiler through concrete Node path: `C:\Program Files\nodejs\node.exe E:\Projects\Huginn\node_modules\typescript\bin\tsc -p tsconfig.json` passed. New native verifier `epiphany-repo-livefire-closure-smoke --workspace E:\Projects\Huginn --item huginn-inspection-readback-livefire --expected-path README.md --expected-family repo.status_section --expected-gate awaiting-publication --expected-blocker bifrost-publication-missing` checks closure receipt, Mind map entry, overview gate/blocker, authority seals, and `git show` changed paths, returning `status=ok`, `soulVerdict=passed`, `publicationGate=Bifrost`, and `privateStateExposed=false`. - next_action: Continue repo-swarm MVP work from `notes/epiphany-repo-swarm-mvp-contract.md`. Huginn is now live-fire proven through branch-local closure and is awaiting Bifrost publication/upstream-main sync; do not push, publish, merge, or sync that branch without explicit Bifrost/maintainer authority. Useful next cuts are Bifrost publication proof for Huginn's closed item, controlled upstream sync only after publication authority, explicit elevated/operator Idunn execution proof only when the human grants that authority, or another repo-owned safe action family only if it materially improves the MVP story. Persona-to-Imagination consensus readback, Mind-owned interpreter brief cargo, safe-family planning depth and closure, Gjallar closure/readiness/readiness-review rows, receipt-directory readiness-review indexing, Bifrost ledger accounting rows including readiness-review closure plus artifact/metrics final receipt closure, readiness wrapper mouth, repo deployment handoff/readback wrappers, readiness deployment-aftercare closure, readiness Idunn/tool-directory receipt validation, readiness Bifrost/GitHub publication-chain validation, readiness upstream-main sync validation, readiness review/adoption receipt validation, aggregate fresh-repo/readiness/Bifrost/deployment-handoff/daemon-survival/Weksa/Persona-memory MVP gate reporting, bounded Idunn daemon survival rehearsal, and Huginn live-fire branch-local closure are sealed; preserve Idunn service lifecycle ownership, Bifrost publication/upstream-main ownership, Mind durable-state admission, and existing CultMesh/Odin/Eve tool directories. Windows service install/start/deployment execution still requires explicit elevated operator authority. + next_action: Continue repo-swarm MVP work from `notes/epiphany-repo-swarm-mvp-contract.md`. Huginn is now live-fire proven through branch-local closure and is awaiting Bifrost publication/upstream-main sync; do not push, publish, merge, or sync that branch without explicit Bifrost/maintainer authority. Useful next cuts are Bifrost publication proof for Huginn's closed item, controlled upstream sync only after publication authority, explicit elevated/operator Idunn execution proof only when the human grants that authority, or another repo-owned safe action family only if it materially improves the MVP story. Persona-to-Imagination consensus readback, Mind-owned interpreter brief cargo, safe-family planning depth and closure, Gjallar closure/readiness/readiness-review rows, receipt-directory readiness-review indexing, Bifrost ledger accounting rows including readiness-review closure plus artifact/metrics final receipt closure, readiness wrapper mouth, repo deployment handoff/readback wrappers, readiness deployment-aftercare closure, readiness Idunn/tool-directory receipt validation, readiness Bifrost/GitHub publication-chain validation, readiness upstream-main sync validation, readiness review/adoption receipt validation, aggregate fresh-repo/readiness/Bifrost/deployment-handoff/daemon-survival/Weksa/Persona two-pass memory MVP gate reporting, bounded Idunn daemon survival rehearsal, and Huginn live-fire branch-local closure are sealed; preserve Idunn service lifecycle ownership, Bifrost publication/upstream-main ownership, Mind durable-state admission, and existing CultMesh/Odin/Eve tool directories. Windows service install/start/deployment execution still requires explicit elevated operator authority.