diff --git a/epiphany-core/src/bin/epiphany-repo-bifrost-accounting-bundle-smoke.rs b/epiphany-core/src/bin/epiphany-repo-bifrost-accounting-bundle-smoke.rs new file mode 100644 index 00000000..901af849 --- /dev/null +++ b/epiphany-core/src/bin/epiphany-repo-bifrost-accounting-bundle-smoke.rs @@ -0,0 +1,336 @@ +use anyhow::Context; +use anyhow::Result; +use anyhow::anyhow; +use chrono::Utc; +use serde_json::Value; +use serde_json::json; +use std::env; +use std::fs; +use std::path::Path; +use std::path::PathBuf; + +fn main() -> Result<()> { + let args = Args::parse()?; + let result = run_smoke(args)?; + println!("{}", serde_json::to_string_pretty(&result)?); + Ok(()) +} + +#[derive(Clone, Debug)] +struct Args { + root: PathBuf, + smoke_root: PathBuf, + artifact_summary: Option, + metrics_summary: Option, +} + +impl Args { + fn parse() -> Result { + let mut root = env::current_dir().context("failed to resolve current directory")?; + let mut smoke_root = root.join(".epiphany-smoke"); + let mut artifact_summary = None; + let mut metrics_summary = None; + let mut args = env::args().skip(1).peekable(); + while let Some(arg) = args.next() { + match arg.as_str() { + "--root" => root = take_path(&mut args, "--root")?, + "--smoke-root" => smoke_root = take_path(&mut args, "--smoke-root")?, + "--artifact-summary" => { + artifact_summary = Some(take_path(&mut args, "--artifact-summary")?) + } + "--metrics-summary" => { + metrics_summary = Some(take_path(&mut args, "--metrics-summary")?) + } + other => return Err(anyhow!("unexpected argument {other:?}")), + } + } + Ok(Self { + root, + smoke_root, + artifact_summary, + metrics_summary, + }) + } +} + +fn run_smoke(args: Args) -> Result { + let root = args + .root + .canonicalize() + .with_context(|| format!("failed to resolve {}", args.root.display()))?; + let manifest = root.join("epiphany-core").join("Cargo.toml"); + if !manifest.exists() { + return Err(anyhow!( + "could not find epiphany-core manifest at {}", + manifest.display() + )); + } + fs::create_dir_all(&args.smoke_root) + .with_context(|| format!("failed to create {}", args.smoke_root.display()))?; + let stamp = Utc::now().format("%Y%m%d-%H%M%S").to_string(); + let smoke_dir = args + .smoke_root + .join(format!("repo-bifrost-accounting-bundle-{stamp}")); + if smoke_dir.exists() { + fs::remove_dir_all(&smoke_dir) + .with_context(|| format!("failed to clear {}", smoke_dir.display()))?; + } + fs::create_dir_all(&smoke_dir) + .with_context(|| format!("failed to create {}", smoke_dir.display()))?; + + let artifact_summary = args.artifact_summary.unwrap_or_else(|| { + latest_summary(&args.smoke_root, "repo-artifact-acceptance-request-family-") + }); + let metrics_summary = args + .metrics_summary + .unwrap_or_else(|| latest_summary(&args.smoke_root, "repo-metrics-request-family-")); + let artifact = read_json(&artifact_summary)?; + let metrics = read_json(&metrics_summary)?; + + require_eq( + &artifact, + &["schemaVersion"], + "epiphany.repo_artifact_acceptance_request_family_smoke.v0", + )?; + require_eq(&artifact, &["status"], "ok")?; + require_eq( + &artifact, + &["safeActionFamily"], + "repo.artifact_acceptance_request", + )?; + require_eq(&artifact, &["closeStatus"], "closed")?; + require_eq(&artifact, &["soulVerdict"], "passed")?; + require_eq(&artifact, &["familyAssertionsStatus"], "passed")?; + require_bool(&artifact, &["privateStateExposed"], false)?; + require_bool(&artifact, &["artifactAcceptanceAuthorized"], false)?; + require_bool(&artifact, &["handsActionAuthorized"], false)?; + require_bool(&artifact, &["upstreamSyncAuthorized"], false)?; + require_eq( + &artifact, + &["bifrostArtifactAcceptanceReceiptId"], + "bifrost-artifact-acceptance-repo-artifact-acceptance-request-family", + )?; + require_row( + &artifact, + &["bifrostArtifactAcceptanceOpenAccountingRow"], + "artifact-acceptance-request", + "open", + 3, + 1, + None, + )?; + require_row( + &artifact, + &["bifrostArtifactAcceptanceClosedAccountingRow"], + "artifact-acceptance-request", + "closed", + 1, + 1, + None, + )?; + + require_eq( + &metrics, + &["schemaVersion"], + "epiphany.repo_metrics_request_family_smoke.v0", + )?; + require_eq(&metrics, &["status"], "ok")?; + require_eq(&metrics, &["safeActionFamily"], "repo.metrics_request")?; + require_eq(&metrics, &["closeStatus"], "closed")?; + require_eq(&metrics, &["soulVerdict"], "passed")?; + require_eq(&metrics, &["familyAssertionsStatus"], "passed")?; + require_bool(&metrics, &["privateStateExposed"], false)?; + require_bool(&metrics, &["metricsLedgerAuthorized"], false)?; + require_bool(&metrics, &["handsActionAuthorized"], false)?; + require_bool(&metrics, &["upstreamSyncAuthorized"], false)?; + require_eq( + &metrics, + &["bifrostMetricsReceiptId"], + "bifrost-metrics-repo-metrics-request-family", + )?; + require_row( + &metrics, + &["bifrostMetricsOpenAccountingRow"], + "metrics-request", + "open", + 3, + 1, + Some(0), + )?; + require_row( + &metrics, + &["bifrostMetricsClosedAccountingRow"], + "metrics-request", + "closed", + 2, + 1, + Some(1), + )?; + + let summary = json!({ + "schemaVersion": "epiphany.repo_bifrost_accounting_bundle_smoke.v0", + "status": "ok", + "smokeDir": smoke_dir, + "artifactAcceptanceSummary": artifact_summary, + "metricsSummary": metrics_summary, + "artifactAcceptanceSmokeDir": artifact["smokeDir"], + "metricsSmokeDir": metrics["smokeDir"], + "artifactAcceptanceFamily": artifact["safeActionFamily"], + "metricsFamily": metrics["safeActionFamily"], + "artifactAcceptanceCloseStatus": artifact["closeStatus"], + "metricsCloseStatus": metrics["closeStatus"], + "artifactAcceptanceReceiptId": artifact["bifrostArtifactAcceptanceReceiptId"], + "metricsReceiptId": metrics["bifrostMetricsReceiptId"], + "artifactAcceptanceClosedAccountingRow": artifact["bifrostArtifactAcceptanceClosedAccountingRow"], + "metricsClosedAccountingRow": metrics["bifrostMetricsClosedAccountingRow"], + "operatorSafeProofBundle": true, + "planningAuthorityOnly": true, + "privateStateExposed": false, + }); + write_json(&smoke_dir.join("summary.json"), &summary)?; + Ok(summary) +} + +fn write_json(path: &Path, value: &Value) -> Result<()> { + if let Some(parent) = path.parent() { + fs::create_dir_all(parent) + .with_context(|| format!("failed to create {}", parent.display()))?; + } + fs::write(path, serde_json::to_vec_pretty(value)?) + .with_context(|| format!("failed to write {}", path.display())) +} + +fn read_json(path: &Path) -> Result { + let bytes = fs::read(path).with_context(|| format!("failed to read {}", path.display()))?; + serde_json::from_slice(&bytes).with_context(|| format!("failed to parse {}", path.display())) +} + +fn latest_summary(smoke_root: &Path, parent_prefix: &str) -> PathBuf { + let mut candidates = Vec::new(); + collect_summaries(smoke_root, parent_prefix, &mut candidates); + candidates + .into_iter() + .max_by_key(|(modified, _)| *modified) + .map(|(_, path)| path) + .unwrap_or_else(|| smoke_root.join(parent_prefix).join("summary.json")) +} + +fn collect_summaries(root: &Path, parent_prefix: &str, summaries: &mut Vec<(u128, PathBuf)>) { + let Ok(entries) = fs::read_dir(root) else { + return; + }; + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + collect_summaries(&path, parent_prefix, summaries); + } else if path.file_name().and_then(|name| name.to_str()) == Some("summary.json") + && path + .parent() + .and_then(Path::file_name) + .and_then(|name| name.to_str()) + .is_some_and(|name| name.starts_with(parent_prefix)) + { + let modified = entry + .metadata() + .and_then(|metadata| metadata.modified()) + .ok() + .and_then(|time| time.duration_since(std::time::UNIX_EPOCH).ok()) + .map(|duration| duration.as_millis()) + .unwrap_or(0); + summaries.push((modified, path)); + } + } +} + +fn require_eq(value: &Value, path: &[&str], expected: &str) -> Result<()> { + let actual = path + .iter() + .try_fold(value, |current, key| current.get(*key)) + .and_then(Value::as_str) + .unwrap_or(""); + if actual == expected { + Ok(()) + } else { + Err(anyhow!( + "expected {} to be {expected:?}, got {actual:?}", + path.join(".") + )) + } +} + +fn require_bool(value: &Value, path: &[&str], expected: bool) -> Result<()> { + let actual = path + .iter() + .try_fold(value, |current, key| current.get(*key)) + .and_then(Value::as_bool); + if actual == Some(expected) { + Ok(()) + } else { + Err(anyhow!( + "expected {} to be {expected}, got {:?}", + path.join("."), + actual + )) + } +} + +fn require_row( + value: &Value, + path: &[&str], + lane: &str, + status: &str, + review_receipt_count: u64, + public_artifact_count: u64, + credit_receipt_count: Option, +) -> Result<()> { + let row = path + .iter() + .try_fold(value, |current, key| current.get(*key)) + .ok_or_else(|| anyhow!("missing accounting row {}", path.join(".")))?; + let actual_lane = row + .get("lane") + .and_then(Value::as_str) + .unwrap_or(""); + let actual_status = row + .get("status") + .and_then(Value::as_str) + .unwrap_or(""); + let actual_review_receipt_count = row + .get("reviewReceiptCount") + .and_then(Value::as_u64) + .unwrap_or(0); + let actual_public_artifact_count = row + .get("publicArtifactCount") + .and_then(Value::as_u64) + .unwrap_or(0); + let actual_credit_receipt_count = row.get("creditReceiptCount").and_then(Value::as_u64); + let actual_private = row + .get("privateStateExposed") + .and_then(Value::as_bool) + .unwrap_or(true); + let credit_matches = credit_receipt_count + .is_none_or(|expected| actual_credit_receipt_count.unwrap_or(0) == expected); + if actual_lane == lane + && actual_status == status + && actual_review_receipt_count == review_receipt_count + && actual_public_artifact_count == public_artifact_count + && credit_matches + && !actual_private + { + Ok(()) + } else { + Err(anyhow!( + "accounting row {} mismatch: lane={actual_lane:?}, status={actual_status:?}, reviewReceiptCount={actual_review_receipt_count}, publicArtifactCount={actual_public_artifact_count}, creditReceiptCount={actual_credit_receipt_count:?}, privateStateExposed={actual_private}", + path.join(".") + )) + } +} + +fn take_path( + args: &mut std::iter::Peekable>, + flag: &str, +) -> Result { + args.next() + .map(PathBuf::from) + .with_context(|| format!("missing value for {flag}")) +} diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 1b51c2d5..eb0b2c9a 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -192,7 +192,7 @@ remembers doctrine; the branch remembers the blade. - `eve-connect` is the compact connection actuator for the advertised Eve surface; use it when the operator wants a typed collaboration receipt for Persona's public surface without opening the whole local Verse. - `collaboration-feedback` is the compact public-feedback actuator; use it after or instead of manual `eve-connect` when Persona/human discussion should be routed to Imagination consensus discovery as typed local Verse receipts. Its JSON now points the next agent at Eve and Bifrost follow-on rites. - `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`. +- `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; latest bundle `.epiphany-smoke\repo-bifrost-accounting-bundle-20260621-131949` verified closed artifact-acceptance and metrics rows, final Bifrost receipt ids, `planningAuthorityOnly=true`, 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. - `tool-directory` is the non-mutating daemon tool sight rite; it shows which globally available daemon-hosted tools any agent can invoke through typed intents and receipts, while still exposing host readiness. - `tool-invoke` now embeds compact readbacks for common daemon-hosted tools. Status calls return `daemonStatusReadback`, Eve calls return `eveConnectionReadback`, Self `service-health` returns Idunn-owned `serviceHealthReadback`, Self `service-policy-directory` returns Idunn-owned `servicePolicyDirectoryReadback`, Self `swarm-online-runbook` returns Idunn-owned `swarmOnlineRunbookReadback`, and Hands/Soul authority tools return `authorityToolReadback` with gate, input contract, receipt contract, intent/receipt routes, host cluster, and private-state seal. This proves global tool ergonomics without moving action, verification, or daemon lifecycle ownership into the wrapper; live proofs routed Persona to Hands `repo-action` (`local-20260619-021628-143-7bf7f2e0`), Soul `verify` (`local-20260619-021701-458-852cfa6f`), Self `swarm-online-runbook` (`local-20260619-032244-273-acb3c6a4`), and Self `service-policy-directory` (`local-20260619-035238-138-633f3ff0`) with `privateStateExposed=false`. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index d4584bdc..fa9b50f5 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 060f1898..791f1e59 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-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` now consumes the closed request-family summaries as an operator-safe aggregate proof; bundle `.epiphany-smoke\repo-bifrost-accounting-bundle-20260621-131949` verified artifact acceptance and metrics close statuses, final Bifrost receipt ids, closed accounting rows, `planningAuthorityOnly=true`, and `privateStateExposed=false`. - `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.