From ee40b60b33b412c290aaa775afb5cbb51c85de73 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 21 Jun 2026 14:01:55 +0100 Subject: [PATCH] Close Bifrost artifact and metrics accounting --- epiphany-core/src/bin/epiphany-verse-query.rs | 521 ++++++++++++++++-- epiphany-core/src/cultmesh_integration.rs | 324 +++++++++++ epiphany-core/src/lib.rs | 14 + notes/fresh-workspace-handoff.md | 3 +- state/ledgers.msgpack | Bin 373561 -> 374093 bytes state/map.yaml | 6 +- tools/epiphany_local_run.ps1 | 108 +++- 7 files changed, 923 insertions(+), 53 deletions(-) diff --git a/epiphany-core/src/bin/epiphany-verse-query.rs b/epiphany-core/src/bin/epiphany-verse-query.rs index 8c5a3653..fce57ed9 100644 --- a/epiphany-core/src/bin/epiphany-verse-query.rs +++ b/epiphany-core/src/bin/epiphany-verse-query.rs @@ -8,10 +8,12 @@ use epiphany_core::EPIPHANY_CULTMESH_INTERNAL_VERSE_ID; use epiphany_core::EPIPHANY_CULTMESH_WORK_LOOP_TELEMETRY_SCHEMA_VERSION; use epiphany_core::EpiphanyAgentStateSoaEntry; use epiphany_core::EpiphanyCultMeshAgentStateSoaSummaryEntry; +use epiphany_core::EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry; use epiphany_core::EpiphanyCultMeshBifrostBodyChangePublicationIntentEntry; use epiphany_core::EpiphanyCultMeshBifrostBodyChangePublicationReceiptEntry; use epiphany_core::EpiphanyCultMeshBifrostCollaborationFeedbackEntry; use epiphany_core::EpiphanyCultMeshBifrostGithubPublicationReceiptEntry; +use epiphany_core::EpiphanyCultMeshBifrostMetricsReceiptEntry; use epiphany_core::EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry; use epiphany_core::EpiphanyCultMeshClusterTopologyEntry; use epiphany_core::EpiphanyCultMeshDaemonPokeReceiptEntry; @@ -36,10 +38,12 @@ use epiphany_core::EpiphanyServiceExecutionAuditCheck; use epiphany_core::default_epiphany_cultmesh_swarm_brake; use epiphany_core::epiphany_cluster_service_execution_audit_report; use epiphany_core::epiphany_cultmesh_agent_state_soa_summary_from_entry; +use epiphany_core::epiphany_cultmesh_bifrost_artifact_acceptance_receipt_for_map_entry; use epiphany_core::epiphany_cultmesh_bifrost_body_change_publication_intent; use epiphany_core::epiphany_cultmesh_bifrost_body_change_publication_receipt_for_intent; use epiphany_core::epiphany_cultmesh_bifrost_collaboration_feedback; use epiphany_core::epiphany_cultmesh_bifrost_github_publication_receipt_for_publication; +use epiphany_core::epiphany_cultmesh_bifrost_metrics_receipt_for_map_entry; use epiphany_core::epiphany_cultmesh_bifrost_public_proof_publication_receipt_for_proof; use epiphany_core::epiphany_cultmesh_daemon_poke_intent_from_status; use epiphany_core::epiphany_cultmesh_daemon_poke_receipt_for_intent; @@ -63,10 +67,12 @@ use epiphany_core::load_epiphany_cultmesh_repo_work_readiness_reports; use epiphany_core::load_epiphany_cultmesh_repo_work_readiness_reviews; use epiphany_core::load_epiphany_cultmesh_swarm_brake; use epiphany_core::load_latest_epiphany_cultmesh_agent_state_soa_summary; +use epiphany_core::load_latest_epiphany_cultmesh_bifrost_artifact_acceptance_receipt; use epiphany_core::load_latest_epiphany_cultmesh_bifrost_body_change_publication_intent; use epiphany_core::load_latest_epiphany_cultmesh_bifrost_body_change_publication_receipt; use epiphany_core::load_latest_epiphany_cultmesh_bifrost_collaboration_feedback; use epiphany_core::load_latest_epiphany_cultmesh_bifrost_github_publication_receipt; +use epiphany_core::load_latest_epiphany_cultmesh_bifrost_metrics_receipt; use epiphany_core::load_latest_epiphany_cultmesh_bifrost_public_proof_publication_receipt; use epiphany_core::load_latest_epiphany_cultmesh_daemon_service_lifecycle_receipt; use epiphany_core::load_latest_epiphany_cultmesh_daemon_tool_invocation_intent; @@ -85,10 +91,12 @@ use epiphany_core::open_epiphany_cultmesh_node; use epiphany_core::query_epiphany_local_verse_context; use epiphany_core::seed_epiphany_local_verse_context; use epiphany_core::write_epiphany_cultmesh_agent_state_soa_summary; +use epiphany_core::write_epiphany_cultmesh_bifrost_artifact_acceptance_receipt; use epiphany_core::write_epiphany_cultmesh_bifrost_body_change_publication_intent; use epiphany_core::write_epiphany_cultmesh_bifrost_body_change_publication_receipt; use epiphany_core::write_epiphany_cultmesh_bifrost_collaboration_feedback; use epiphany_core::write_epiphany_cultmesh_bifrost_github_publication_receipt; +use epiphany_core::write_epiphany_cultmesh_bifrost_metrics_receipt; use epiphany_core::write_epiphany_cultmesh_bifrost_public_proof_publication_receipt; use epiphany_core::write_epiphany_cultmesh_daemon_poke_intent; use epiphany_core::write_epiphany_cultmesh_daemon_poke_receipt; @@ -126,6 +134,9 @@ const WRAPPER_COLLABORATION_FEEDBACK_COMMAND: &str = "tools/epiphany_local_run.ps1 -Mode collaboration-feedback"; const WRAPPER_BIFROST_PUBLICATION_COMMAND: &str = "tools/epiphany_local_run.ps1 -Mode bifrost-publication"; +const WRAPPER_BIFROST_ARTIFACT_ACCEPTANCE_COMMAND: &str = + "tools/epiphany_local_run.ps1 -Mode bifrost-artifact-acceptance"; +const WRAPPER_BIFROST_METRICS_COMMAND: &str = "tools/epiphany_local_run.ps1 -Mode bifrost-metrics"; const WRAPPER_BIFROST_LEDGER_COMMAND: &str = "tools/epiphany_local_run.ps1 -Mode bifrost-ledger"; const WRAPPER_RECEIPT_DIRECTORY_COMMAND: &str = "tools/epiphany_local_run.ps1 -Mode receipt-directory"; @@ -1211,6 +1222,208 @@ fn run_cli() -> Result<()> { }))? ); } + "bifrost-artifact-acceptance" | "artifact-acceptance" => { + seed_epiphany_local_verse_context( + &args.store, + args.runtime_id.clone(), + Utc::now().to_rfc3339(), + )?; + let (_, map_entries) = load_repo_work_map_entries(&args)?; + let map_entry = latest_repo_work_map_entry_for_family( + &map_entries, + "repo.artifact_acceptance_request", + ) + .context( + "bifrost-artifact-acceptance requires a repo.artifact_acceptance_request map entry", + )?; + let artifact_ref = args + .artifact_ref + .clone() + .context("bifrost-artifact-acceptance requires --artifact-ref")?; + let public_proof_ref = args + .public_proof_id + .clone() + .or_else(|| args.result_ref.clone()) + .context( + "bifrost-artifact-acceptance requires --public-proof-ref or --result-ref", + )?; + let review_receipts = required_list( + &args.review_receipts, + "bifrost-artifact-acceptance requires --review-receipt", + )?; + let ledger_entry_id = args + .ledger_entry_id + .clone() + .unwrap_or_else(|| map_entry.publication_gate.clone()); + let receipt_id = args + .receipt_id + .clone() + .unwrap_or_else(|| format!("bifrost-artifact-acceptance-{}", map_entry.item)); + let receipt_status = args + .receipt_status + .clone() + .unwrap_or_else(|| "accepted-artifact-recorded".to_string()); + let accepted_by = args + .source_agent_id + .clone() + .unwrap_or_else(|| "Maintainer/Bifrost".to_string()); + let receipt = epiphany_cultmesh_bifrost_artifact_acceptance_receipt_for_map_entry( + receipt_id, + &map_entry, + artifact_ref, + public_proof_ref, + review_receipts, + ledger_entry_id, + receipt_status, + accepted_by, + ); + let written = write_epiphany_cultmesh_bifrost_artifact_acceptance_receipt( + &args.store, + args.runtime_id.clone(), + receipt, + )?; + let latest = load_latest_epiphany_cultmesh_bifrost_artifact_acceptance_receipt( + &args.store, + args.runtime_id.clone(), + )?; + if latest.as_ref().map(|receipt| receipt.receipt_id.as_str()) + != Some(written.receipt_id.as_str()) + { + anyhow::bail!( + "local Verse query lost Bifrost artifact acceptance receipt after write" + ); + } + println!( + "{}", + serde_json::to_string_pretty(&json!({ + "schemaVersion": "epiphany.local_verse_bifrost_artifact_acceptance.v0", + "status": "ok", + "store": args.store, + "runtimeId": args.runtime_id, + "receiptId": written.receipt_id, + "item": written.item, + "sourceWorkspace": written.source_workspace, + "sourceBranch": written.source_branch, + "commitSha": written.commit_sha, + "changedPaths": written.changed_paths, + "artifactRef": written.artifact_ref, + "publicProofRef": written.public_proof_ref, + "ledgerEntryId": written.bifrost_ledger_entry_id, + "reviewReceiptIds": written.maintainer_review_receipt_ids, + "acceptedBy": written.accepted_by, + "commands": { + "swarmOverview": WRAPPER_OVERVIEW_COMMAND, + "bifrostArtifactAcceptance": WRAPPER_BIFROST_ARTIFACT_ACCEPTANCE_COMMAND, + "bifrostLedger": WRAPPER_BIFROST_LEDGER_COMMAND + }, + "privateStateExposed": written.private_state_exposed, + }))? + ); + } + "bifrost-metrics" | "metrics-receipt" => { + seed_epiphany_local_verse_context( + &args.store, + args.runtime_id.clone(), + Utc::now().to_rfc3339(), + )?; + let (_, map_entries) = load_repo_work_map_entries(&args)?; + let map_entry = + latest_repo_work_map_entry_for_family(&map_entries, "repo.metrics_request") + .context("bifrost-metrics requires a repo.metrics_request map entry")?; + let latest_artifact_acceptance = + load_latest_epiphany_cultmesh_bifrost_artifact_acceptance_receipt( + &args.store, + args.runtime_id.clone(), + )?; + let artifact_acceptance_receipt_id = args + .artifact_ref + .clone() + .or_else(|| { + latest_artifact_acceptance + .as_ref() + .map(|receipt| receipt.receipt_id.clone()) + }) + .context("bifrost-metrics requires --accepted-artifact-receipt-id or a latest artifact acceptance receipt")?; + let model_spend_receipts = required_list( + &args.verification_receipts, + "bifrost-metrics requires --model-spend-receipt", + )?; + let review_load_receipts = required_list( + &args.review_receipts, + "bifrost-metrics requires --review-load-receipt", + )?; + let credit_readback_receipts = required_list( + &args.credit_receipt_ids, + "bifrost-metrics requires --credit-receipt", + )?; + let public_proof_ref = args + .public_proof_id + .clone() + .or_else(|| args.result_ref.clone()) + .context("bifrost-metrics requires --public-proof-ref or --result-ref")?; + let metrics_summary = args.receipt_summary.clone().unwrap_or_else(|| { + "model spend, review load, accepted artifact, and credit readback recorded" + .to_string() + }); + let receipt_id = args + .receipt_id + .clone() + .unwrap_or_else(|| format!("bifrost-metrics-{}", map_entry.item)); + let receipt_status = args + .receipt_status + .clone() + .unwrap_or_else(|| "metrics-recorded".to_string()); + let receipt = epiphany_cultmesh_bifrost_metrics_receipt_for_map_entry( + receipt_id, + &map_entry, + artifact_acceptance_receipt_id, + model_spend_receipts, + review_load_receipts, + credit_readback_receipts, + public_proof_ref, + metrics_summary, + receipt_status, + ); + let written = write_epiphany_cultmesh_bifrost_metrics_receipt( + &args.store, + args.runtime_id.clone(), + receipt, + )?; + let latest = load_latest_epiphany_cultmesh_bifrost_metrics_receipt( + &args.store, + args.runtime_id.clone(), + )?; + if latest.as_ref().map(|receipt| receipt.receipt_id.as_str()) + != Some(written.receipt_id.as_str()) + { + anyhow::bail!("local Verse query lost Bifrost metrics receipt after write"); + } + println!( + "{}", + serde_json::to_string_pretty(&json!({ + "schemaVersion": "epiphany.local_verse_bifrost_metrics.v0", + "status": "ok", + "store": args.store, + "runtimeId": args.runtime_id, + "receiptId": written.receipt_id, + "item": written.item, + "sourceWorkspace": written.source_workspace, + "sourceBranch": written.source_branch, + "artifactAcceptanceReceiptId": written.artifact_acceptance_receipt_id, + "modelSpendReceiptIds": written.model_spend_receipt_ids, + "reviewLoadReceiptIds": written.review_load_receipt_ids, + "creditReadbackReceiptIds": written.credit_readback_receipt_ids, + "publicProofRef": written.public_proof_ref, + "metricsSummary": written.metrics_summary, + "commands": { + "swarmOverview": WRAPPER_OVERVIEW_COMMAND, + "bifrostMetrics": WRAPPER_BIFROST_METRICS_COMMAND, + "bifrostLedger": WRAPPER_BIFROST_LEDGER_COMMAND + }, + "privateStateExposed": written.private_state_exposed, + }))? + ); + } "bifrost-ledger" | "publication-ledger" => { seed_epiphany_local_verse_context( &args.store, @@ -1228,6 +1441,8 @@ fn run_cli() -> Result<()> { "rowCount": report.rows.len(), "publicationChainCount": report.publication_chain_count, "publicProofPublicationCount": report.public_proof_publication_count, + "artifactAcceptanceReceiptCount": report.artifact_acceptance_receipt_count, + "metricsReceiptCount": report.metrics_receipt_count, "collaborationChainCount": report.collaboration_chain_count, "repoWorkAccountingRequestCount": report.repo_work_accounting_request_count, "accountingRowCount": report.accounting_rows.len(), @@ -1237,6 +1452,8 @@ fn run_cli() -> Result<()> { "latestBifrostPublicationReceipt": report.latest_publication_receipt_id, "latestBifrostGithubReceipt": report.latest_github_receipt_id, "latestBifrostPublicProofPublicationReceipt": report.latest_public_proof_publication_receipt_id, + "latestBifrostArtifactAcceptanceReceipt": report.latest_artifact_acceptance_receipt_id, + "latestBifrostMetricsReceipt": report.latest_metrics_receipt_id, "latestRepoWorkReadinessReview": report.latest_readiness_review_id, "latestBifrostCollaborationFeedback": report.latest_feedback_id, "latestImaginationConsensusReceipt": report.latest_consensus_receipt_id, @@ -1248,6 +1465,8 @@ fn run_cli() -> Result<()> { "swarmOverview": WRAPPER_OVERVIEW_COMMAND, "toolDirectory": "tools/epiphany_local_run.ps1 -Mode tool-directory", "collaborationFeedback": WRAPPER_COLLABORATION_FEEDBACK_COMMAND, + "bifrostArtifactAcceptance": WRAPPER_BIFROST_ARTIFACT_ACCEPTANCE_COMMAND, + "bifrostMetrics": WRAPPER_BIFROST_METRICS_COMMAND, "bifrostPublication": WRAPPER_BIFROST_PUBLICATION_COMMAND, "bifrostLedger": WRAPPER_BIFROST_LEDGER_COMMAND }, @@ -3753,7 +3972,7 @@ fn run_cli() -> Result<()> { ); } other => anyhow::bail!( - "unknown command {other:?}; use seed, query, tools, tool-directory, invoke-tool, restart-policy-directory, swarm-brake, swarm-status, cluster-topology, eve-surfaces, daemon-status, agent-state, agent-state-report, poke-daemon, poke-down-daemons, bifrost-publication, bifrost-public-proof, bifrost-ledger, collaboration-feedback, connect-eve, or smoke" + "unknown command {other:?}; use seed, query, tools, tool-directory, invoke-tool, restart-policy-directory, swarm-brake, swarm-status, cluster-topology, eve-surfaces, daemon-status, agent-state, agent-state-report, poke-daemon, poke-down-daemons, bifrost-publication, bifrost-public-proof, bifrost-artifact-acceptance, bifrost-metrics, bifrost-ledger, collaboration-feedback, connect-eve, or smoke" ), } Ok(()) @@ -4943,6 +5162,8 @@ struct BifrostLedgerReport { accounting_tui_rows: Vec, publication_chain_count: usize, public_proof_publication_count: usize, + artifact_acceptance_receipt_count: usize, + metrics_receipt_count: usize, collaboration_chain_count: usize, closed_accounting_row_count: usize, attention_accounting_row_count: usize, @@ -4950,6 +5171,8 @@ struct BifrostLedgerReport { latest_publication_receipt_id: Option, latest_github_receipt_id: Option, latest_public_proof_publication_receipt_id: Option, + latest_artifact_acceptance_receipt_id: Option, + latest_metrics_receipt_id: Option, latest_readiness_review_id: Option, latest_feedback_id: Option, latest_consensus_receipt_id: Option, @@ -6950,6 +7173,21 @@ fn load_repo_work_map_entries( Ok((latest_repo_work_map_entry, repo_work_map_entries)) } +fn latest_repo_work_map_entry_for_family( + entries: &[EpiphanyCultMeshRepoWorkMapEntry], + family: &str, +) -> Option { + entries + .iter() + .filter(|entry| entry.safe_action_family == family) + .max_by(|left, right| { + left.admitted_at + .cmp(&right.admitted_at) + .then_with(|| left.map_entry_id.cmp(&right.map_entry_id)) + }) + .cloned() +} + fn load_repo_work_public_proofs( args: &Args, ) -> Result<( @@ -8548,6 +8786,15 @@ fn load_bifrost_ledger_report(args: &Args) -> Result { &args.store, args.runtime_id.clone(), )?; + let latest_artifact_acceptance = + load_latest_epiphany_cultmesh_bifrost_artifact_acceptance_receipt( + &args.store, + args.runtime_id.clone(), + )?; + let latest_metrics = load_latest_epiphany_cultmesh_bifrost_metrics_receipt( + &args.store, + args.runtime_id.clone(), + )?; let latest_readiness_review = load_latest_epiphany_cultmesh_repo_work_readiness_review( &args.store, args.runtime_id.clone(), @@ -8567,6 +8814,8 @@ fn load_bifrost_ledger_report(args: &Args) -> Result { latest_publication.as_ref(), latest_github.as_ref(), latest_public_proof_publication.as_ref(), + latest_artifact_acceptance.as_ref(), + latest_metrics.as_ref(), latest_readiness_review.as_ref(), latest_feedback.as_ref(), latest_consensus.as_ref(), @@ -8581,6 +8830,8 @@ fn bifrost_ledger_report( latest_public_proof_publication: Option< &EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry, >, + latest_artifact_acceptance: Option<&EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry>, + latest_metrics: Option<&EpiphanyCultMeshBifrostMetricsReceiptEntry>, latest_readiness_review: Option<&EpiphanyCultMeshRepoWorkReadinessReviewEntry>, latest_feedback: Option<&EpiphanyCultMeshBifrostCollaborationFeedbackEntry>, latest_consensus: Option<&EpiphanyCultMeshImaginationConsensusReceiptEntry>, @@ -8662,6 +8913,40 @@ fn bifrost_ledger_report( }, ); } + if let Some(receipt) = latest_artifact_acceptance { + push_bifrost_ledger_row( + &mut rows, + &mut tui_rows, + BifrostLedgerRow { + document_kind: "artifact-acceptance-receipt".to_string(), + owner: "Maintainer/Bifrost".to_string(), + id: receipt.receipt_id.clone(), + status: receipt.status.clone(), + route: receipt.bifrost_ledger_entry_id.clone(), + summary: receipt.artifact_ref.clone(), + public_ref: receipt.public_proof_ref.clone(), + private_state_included: false, + private_state_exposed: receipt.private_state_exposed, + }, + ); + } + if let Some(receipt) = latest_metrics { + push_bifrost_ledger_row( + &mut rows, + &mut tui_rows, + BifrostLedgerRow { + document_kind: "metrics-receipt".to_string(), + owner: "Bifrost/Maintainer".to_string(), + id: receipt.receipt_id.clone(), + status: receipt.status.clone(), + route: receipt.artifact_acceptance_receipt_id.clone(), + summary: receipt.metrics_summary.clone(), + public_ref: receipt.public_proof_ref.clone(), + private_state_included: false, + private_state_exposed: receipt.private_state_exposed, + }, + ); + } if let Some(feedback) = latest_feedback { push_bifrost_ledger_row( &mut rows, @@ -8701,6 +8986,8 @@ fn bifrost_ledger_report( + usize::from(latest_publication.is_some()) + usize::from(latest_github.is_some()); let public_proof_publication_count = usize::from(latest_public_proof_publication.is_some()); + let artifact_acceptance_receipt_count = usize::from(latest_artifact_acceptance.is_some()); + let metrics_receipt_count = usize::from(latest_metrics.is_some()); let collaboration_chain_count = usize::from(latest_feedback.is_some()) + usize::from(latest_consensus.is_some()); let (accounting_rows, accounting_tui_rows) = bifrost_accounting_rows( @@ -8708,6 +8995,8 @@ fn bifrost_ledger_report( latest_publication, latest_github, latest_public_proof_publication, + latest_artifact_acceptance, + latest_metrics, latest_readiness_review, latest_feedback, latest_consensus, @@ -8740,6 +9029,8 @@ fn bifrost_ledger_report( accounting_tui_rows, publication_chain_count, public_proof_publication_count, + artifact_acceptance_receipt_count, + metrics_receipt_count, collaboration_chain_count, closed_accounting_row_count, attention_accounting_row_count, @@ -8748,6 +9039,9 @@ fn bifrost_ledger_report( latest_github_receipt_id: latest_github.map(|receipt| receipt.receipt_id.clone()), latest_public_proof_publication_receipt_id: latest_public_proof_publication .map(|receipt| receipt.receipt_id.clone()), + latest_artifact_acceptance_receipt_id: latest_artifact_acceptance + .map(|receipt| receipt.receipt_id.clone()), + latest_metrics_receipt_id: latest_metrics.map(|receipt| receipt.receipt_id.clone()), latest_readiness_review_id: latest_readiness_review.map(|review| review.review_id.clone()), latest_feedback_id: latest_feedback.map(|feedback| feedback.feedback_id.clone()), latest_consensus_receipt_id: latest_consensus.map(|receipt| receipt.receipt_id.clone()), @@ -8791,6 +9085,8 @@ fn bifrost_accounting_rows( latest_public_proof_publication: Option< &EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry, >, + latest_artifact_acceptance: Option<&EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry>, + latest_metrics: Option<&EpiphanyCultMeshBifrostMetricsReceiptEntry>, latest_readiness_review: Option<&EpiphanyCultMeshRepoWorkReadinessReviewEntry>, latest_feedback: Option<&EpiphanyCultMeshBifrostCollaborationFeedbackEntry>, latest_consensus: Option<&EpiphanyCultMeshImaginationConsensusReceiptEntry>, @@ -8978,21 +9274,17 @@ fn bifrost_accounting_rows( }, ); - push_repo_work_request_accounting_row( + push_artifact_acceptance_accounting_row( &mut rows, &mut tui_rows, repo_work_map_entries, - "artifact-acceptance-request", - "repo.artifact_acceptance_request", - "Maintainer/Bifrost", + latest_artifact_acceptance, ); - push_repo_work_request_accounting_row( + push_metrics_accounting_row( &mut rows, &mut tui_rows, repo_work_map_entries, - "metrics-request", - "repo.metrics_request", - "Bifrost/Maintainer", + latest_metrics, ); let collaboration_private = latest_feedback @@ -9044,27 +9336,135 @@ fn bifrost_accounting_rows( (rows, tui_rows) } -fn push_repo_work_request_accounting_row( +fn push_artifact_acceptance_accounting_row( rows: &mut Vec, tui_rows: &mut Vec, repo_work_map_entries: &[EpiphanyCultMeshRepoWorkMapEntry], - lane: &str, - safe_action_family: &str, - owner: &str, + latest_receipt: Option<&EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry>, ) { let matching = repo_work_map_entries .iter() - .filter(|entry| entry.safe_action_family == safe_action_family) + .filter(|entry| entry.safe_action_family == "repo.artifact_acceptance_request") .collect::>(); - let latest = matching.iter().copied().max_by(|left, right| { + let latest_request = matching.iter().copied().max_by(|left, right| { left.admitted_at .cmp(&right.admitted_at) .then_with(|| left.map_entry_id.cmp(&right.map_entry_id)) }); - let request_present = latest.is_some(); - let private = matching.iter().any(|entry| entry.private_state_exposed); - let latest_item = latest.map(|entry| entry.item.as_str()).unwrap_or("none"); - let review_receipt_count = latest + let request_private = matching.iter().any(|entry| entry.private_state_exposed); + let receipt_private = latest_receipt + .map(|receipt| receipt.private_state_exposed) + .unwrap_or(false); + let review_receipt_count = latest_receipt + .map(|receipt| receipt.maintainer_review_receipt_ids.len()) + .or_else(|| { + latest_request.map(|entry| { + [ + &entry.soul_verdict_receipt_id, + &entry.mind_gateway_review_id, + &entry.mind_state_commit_receipt_id, + ] + .iter() + .filter(|receipt| !receipt.trim().is_empty() && receipt.as_str() != "none") + .count() + }) + }) + .unwrap_or(0); + let public_artifact_count = latest_receipt + .map(|receipt| receipt.changed_paths.len()) + .or_else(|| latest_request.map(|entry| entry.changed_paths.len())) + .unwrap_or(0); + let private = request_private || receipt_private; + let receipt_closed = latest_receipt + .map(|receipt| { + !receipt.artifact_ref.trim().is_empty() + && !receipt.public_proof_ref.trim().is_empty() + && !receipt.bifrost_ledger_entry_id.trim().is_empty() + && !receipt.commit_sha.trim().is_empty() + && review_receipt_count > 0 + && public_artifact_count > 0 + && !receipt.private_state_exposed + }) + .unwrap_or(false); + push_bifrost_accounting_row( + rows, + tui_rows, + BifrostAccountingRow { + lane: "artifact-acceptance-request".to_string(), + owner: "Maintainer/Bifrost".to_string(), + status: bifrost_accounting_status( + receipt_closed, + latest_request.is_some() || latest_receipt.is_some(), + private, + ), + closure: format!( + "request={} acceptance={} review={} artifacts={}", + present_word(latest_request.is_some()), + present_word(latest_receipt.is_some()), + review_receipt_count, + public_artifact_count + ), + ledger_entry_id: latest_receipt + .map(|receipt| receipt.bifrost_ledger_entry_id.clone()) + .or_else(|| latest_request.map(|entry| entry.publication_gate.clone())) + .unwrap_or_else(|| "none".to_string()), + latest_receipt_id: latest_receipt + .map(|receipt| receipt.receipt_id.clone()) + .or_else(|| latest_request.map(|entry| entry.mind_state_commit_receipt_id.clone())) + .unwrap_or_else(|| "none".to_string()), + public_ref: latest_receipt + .map(|receipt| receipt.public_proof_ref.clone()) + .or_else(|| { + latest_request.map(|entry| { + if entry.commit_sha.trim().is_empty() || entry.commit_sha == "none" { + entry.branch.clone() + } else { + entry.commit_sha.clone() + } + }) + }) + .unwrap_or_else(|| "none".to_string()), + review_receipt_count, + credit_receipt_count: 0, + public_artifact_count, + private_state_exposed: private, + }, + ); +} + +fn push_metrics_accounting_row( + rows: &mut Vec, + tui_rows: &mut Vec, + repo_work_map_entries: &[EpiphanyCultMeshRepoWorkMapEntry], + latest_receipt: Option<&EpiphanyCultMeshBifrostMetricsReceiptEntry>, +) { + let matching = repo_work_map_entries + .iter() + .filter(|entry| entry.safe_action_family == "repo.metrics_request") + .collect::>(); + let latest_request = matching.iter().copied().max_by(|left, right| { + left.admitted_at + .cmp(&right.admitted_at) + .then_with(|| left.map_entry_id.cmp(&right.map_entry_id)) + }); + let request_private = matching.iter().any(|entry| entry.private_state_exposed); + let receipt_private = latest_receipt + .map(|receipt| receipt.private_state_exposed) + .unwrap_or(false); + let model_spend_count = latest_receipt + .map(|receipt| receipt.model_spend_receipt_ids.len()) + .unwrap_or(0); + let review_load_count = latest_receipt + .map(|receipt| receipt.review_load_receipt_ids.len()) + .unwrap_or(0); + let credit_count = latest_receipt + .map(|receipt| receipt.credit_readback_receipt_ids.len()) + .unwrap_or(0); + let public_artifact_count = latest_receipt + .map(|_| 1) + .or_else(|| latest_request.map(|entry| entry.changed_paths.len())) + .unwrap_or(0); + let request_review_count = latest_request .map(|entry| { [ &entry.soul_verdict_receipt_id, @@ -9076,37 +9476,64 @@ fn push_repo_work_request_accounting_row( .count() }) .unwrap_or(0); + let review_receipt_count = if latest_receipt.is_some() { + model_spend_count + review_load_count + } else { + request_review_count + }; + let private = request_private || receipt_private; + let receipt_closed = latest_receipt + .map(|receipt| { + !receipt.artifact_acceptance_receipt_id.trim().is_empty() + && model_spend_count > 0 + && review_load_count > 0 + && credit_count > 0 + && !receipt.public_proof_ref.trim().is_empty() + && !receipt.metrics_summary.trim().is_empty() + && !receipt.private_state_exposed + }) + .unwrap_or(false); push_bifrost_accounting_row( rows, tui_rows, BifrostAccountingRow { - lane: lane.to_string(), - owner: owner.to_string(), - status: bifrost_accounting_status(false, request_present, private), - closure: format!( - "request={} items={} latest={}", - present_word(request_present), - matching.len(), - latest_item + lane: "metrics-request".to_string(), + owner: "Bifrost/Maintainer".to_string(), + status: bifrost_accounting_status( + receipt_closed, + latest_request.is_some() || latest_receipt.is_some(), + private, ), - ledger_entry_id: latest + closure: format!( + "request={} metrics={} modelSpend={} reviewLoad={} credit={}", + present_word(latest_request.is_some()), + present_word(latest_receipt.is_some()), + model_spend_count, + review_load_count, + credit_count + ), + ledger_entry_id: latest_request .map(|entry| entry.publication_gate.clone()) .unwrap_or_else(|| "none".to_string()), - latest_receipt_id: latest - .map(|entry| entry.mind_state_commit_receipt_id.clone()) + latest_receipt_id: latest_receipt + .map(|receipt| receipt.receipt_id.clone()) + .or_else(|| latest_request.map(|entry| entry.mind_state_commit_receipt_id.clone())) .unwrap_or_else(|| "none".to_string()), - public_ref: latest - .map(|entry| { - if entry.commit_sha.trim().is_empty() || entry.commit_sha == "none" { - entry.branch.clone() - } else { - entry.commit_sha.clone() - } + public_ref: latest_receipt + .map(|receipt| receipt.public_proof_ref.clone()) + .or_else(|| { + latest_request.map(|entry| { + if entry.commit_sha.trim().is_empty() || entry.commit_sha == "none" { + entry.branch.clone() + } else { + entry.commit_sha.clone() + } + }) }) .unwrap_or_else(|| "none".to_string()), review_receipt_count, - credit_receipt_count: 0, - public_artifact_count: latest.map(|entry| entry.changed_paths.len()).unwrap_or(0), + credit_receipt_count: credit_count, + public_artifact_count, private_state_exposed: private, }, ); @@ -10442,7 +10869,7 @@ impl Args { resulting_status = Some(values.next().context("missing --resulting-status value")?); } - "--artifact-ref" => { + "--artifact-ref" | "--accepted-artifact-receipt-id" => { artifact_ref = Some(values.next().context("missing --artifact-ref value")?); } "--invocation-ref" | "--payload-ref" => { @@ -10451,7 +10878,7 @@ impl Args { "--result-ref" => { result_ref = Some(values.next().context("missing --result-ref value")?); } - "--receipt-summary" => { + "--receipt-summary" | "--metrics-summary" => { receipt_summary = Some(values.next().context("missing --receipt-summary value")?); } @@ -10478,7 +10905,10 @@ impl Args { values.next().context("missing --changed-path value")?, ); } - "--verification-receipt" | "--verification-receipts" => { + "--verification-receipt" + | "--verification-receipts" + | "--model-spend-receipt" + | "--model-spend-receipts" => { extend_list( &mut verification_receipts, values @@ -10486,7 +10916,10 @@ impl Args { .context("missing --verification-receipt value")?, ); } - "--review-receipt" | "--review-receipts" => { + "--review-receipt" + | "--review-receipts" + | "--review-load-receipt" + | "--review-load-receipts" => { extend_list( &mut review_receipts, values.next().context("missing --review-receipt value")?, @@ -10525,7 +10958,7 @@ impl Args { publication_url = Some(values.next().context("missing --publication-url value")?); } - "--public-proof-id" => { + "--public-proof-id" | "--public-proof-ref" => { public_proof_id = Some(values.next().context("missing --public-proof-id value")?); } diff --git a/epiphany-core/src/cultmesh_integration.rs b/epiphany-core/src/cultmesh_integration.rs index 071f115e..1ec3a9a5 100644 --- a/epiphany-core/src/cultmesh_integration.rs +++ b/epiphany-core/src/cultmesh_integration.rs @@ -236,6 +236,17 @@ pub const EPIPHANY_CULTMESH_BIFROST_PUBLIC_PROOF_PUBLICATION_RECEIPT_SCHEMA_VERS "gamecult.bifrost.public_proof_publication_receipt.v0"; pub const EPIPHANY_CULTMESH_BIFROST_PUBLIC_PROOF_PUBLICATION_RECEIPT_LATEST_KEY: &str = "gamecult-local/bifrost/public-proof-publication-receipt/latest"; +pub const EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_TYPE: &str = + "gamecult.bifrost.artifact_acceptance_receipt"; +pub const EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_SCHEMA_VERSION: &str = + "gamecult.bifrost.artifact_acceptance_receipt.v0"; +pub const EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_LATEST_KEY: &str = + "gamecult-local/bifrost/artifact-acceptance-receipt/latest"; +pub const EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_TYPE: &str = "gamecult.bifrost.metrics_receipt"; +pub const EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_SCHEMA_VERSION: &str = + "gamecult.bifrost.metrics_receipt.v0"; +pub const EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_LATEST_KEY: &str = + "gamecult-local/bifrost/metrics-receipt/latest"; pub const EPIPHANY_CULTMESH_BIFROST_COLLABORATION_FEEDBACK_TYPE: &str = "gamecult.bifrost.collaboration_feedback"; pub const EPIPHANY_CULTMESH_BIFROST_COLLABORATION_FEEDBACK_SCHEMA_VERSION: &str = @@ -2228,6 +2239,80 @@ pub struct EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry { pub notes: Vec, } +#[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)] +#[cultcache( + type = "gamecult.bifrost.artifact_acceptance_receipt", + schema = "EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry" +)] +pub struct EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry { + #[cultcache(key = 0)] + pub schema_version: String, + #[cultcache(key = 1)] + pub receipt_id: String, + #[cultcache(key = 2)] + pub item: String, + #[cultcache(key = 3)] + pub source_workspace: String, + #[cultcache(key = 4)] + pub source_branch: String, + #[cultcache(key = 5)] + pub commit_sha: String, + #[cultcache(key = 6)] + pub changed_paths: Vec, + #[cultcache(key = 7)] + pub artifact_ref: String, + #[cultcache(key = 8)] + pub public_proof_ref: String, + #[cultcache(key = 9)] + pub maintainer_review_receipt_ids: Vec, + #[cultcache(key = 10)] + pub bifrost_ledger_entry_id: String, + #[cultcache(key = 11)] + pub status: String, + #[cultcache(key = 12)] + pub accepted_by: String, + #[cultcache(key = 13)] + pub private_state_exposed: bool, + #[cultcache(key = 14)] + pub notes: Vec, +} + +#[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)] +#[cultcache( + type = "gamecult.bifrost.metrics_receipt", + schema = "EpiphanyCultMeshBifrostMetricsReceiptEntry" +)] +pub struct EpiphanyCultMeshBifrostMetricsReceiptEntry { + #[cultcache(key = 0)] + pub schema_version: String, + #[cultcache(key = 1)] + pub receipt_id: String, + #[cultcache(key = 2)] + pub item: String, + #[cultcache(key = 3)] + pub source_workspace: String, + #[cultcache(key = 4)] + pub source_branch: String, + #[cultcache(key = 5)] + pub artifact_acceptance_receipt_id: String, + #[cultcache(key = 6)] + pub model_spend_receipt_ids: Vec, + #[cultcache(key = 7)] + pub review_load_receipt_ids: Vec, + #[cultcache(key = 8)] + pub credit_readback_receipt_ids: Vec, + #[cultcache(key = 9)] + pub public_proof_ref: String, + #[cultcache(key = 10)] + pub metrics_summary: String, + #[cultcache(key = 11)] + pub status: String, + #[cultcache(key = 12)] + pub private_state_exposed: bool, + #[cultcache(key = 13)] + pub notes: Vec, +} + #[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)] #[cultcache( type = "gamecult.bifrost.collaboration_feedback", @@ -2435,6 +2520,8 @@ cultmesh_documents!(EpiphanyCultMeshDocuments { EpiphanyCultMeshBifrostBodyChangePublicationReceiptEntry => EPIPHANY_CULTMESH_BIFROST_BODY_CHANGE_PUBLICATION_RECEIPT_SCHEMA_VERSION, EpiphanyCultMeshBifrostGithubPublicationReceiptEntry => EPIPHANY_CULTMESH_BIFROST_GITHUB_PUBLICATION_RECEIPT_SCHEMA_VERSION, EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry => EPIPHANY_CULTMESH_BIFROST_PUBLIC_PROOF_PUBLICATION_RECEIPT_SCHEMA_VERSION, + EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry => EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_SCHEMA_VERSION, + EpiphanyCultMeshBifrostMetricsReceiptEntry => EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_SCHEMA_VERSION, EpiphanyCultMeshBifrostCollaborationFeedbackEntry => EPIPHANY_CULTMESH_BIFROST_COLLABORATION_FEEDBACK_SCHEMA_VERSION, EpiphanyCultMeshImaginationConsensusReceiptEntry => EPIPHANY_CULTMESH_IMAGINATION_CONSENSUS_RECEIPT_SCHEMA_VERSION, }); @@ -4267,6 +4354,126 @@ pub fn load_latest_epiphany_cultmesh_bifrost_public_proof_publication_receipt( node.get(EPIPHANY_CULTMESH_BIFROST_PUBLIC_PROOF_PUBLICATION_RECEIPT_LATEST_KEY) } +#[allow(clippy::too_many_arguments)] +pub fn epiphany_cultmesh_bifrost_artifact_acceptance_receipt_for_map_entry( + receipt_id: impl Into, + map_entry: &EpiphanyCultMeshRepoWorkMapEntry, + artifact_ref: impl Into, + public_proof_ref: impl Into, + maintainer_review_receipt_ids: Vec, + bifrost_ledger_entry_id: impl Into, + status: impl Into, + accepted_by: impl Into, +) -> EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry { + EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry { + schema_version: EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_SCHEMA_VERSION + .to_string(), + receipt_id: receipt_id.into(), + item: map_entry.item.clone(), + source_workspace: map_entry.workspace.clone(), + source_branch: map_entry.branch.clone(), + commit_sha: map_entry.commit_sha.clone(), + changed_paths: map_entry.changed_paths.clone(), + artifact_ref: artifact_ref.into(), + public_proof_ref: public_proof_ref.into(), + maintainer_review_receipt_ids, + bifrost_ledger_entry_id: bifrost_ledger_entry_id.into(), + status: status.into(), + accepted_by: accepted_by.into(), + private_state_exposed: false, + notes: vec![ + "Bifrost artifact acceptance receipt closes accepted-artifact accounting for Mind-admitted branch work.".to_string(), + "This receipt carries artifact, review, ledger, commit, and path refs only; private worker/operator/agent state remains sealed.".to_string(), + "Repo-work request cargo may ask for this receipt, but Bifrost/Maintainer owns acceptance.".to_string(), + ], + } +} + +pub fn write_epiphany_cultmesh_bifrost_artifact_acceptance_receipt( + store_path: impl AsRef, + runtime_id: impl Into, + receipt: EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry, +) -> Result { + validate_bifrost_artifact_acceptance_receipt(&receipt)?; + let mut node = open_epiphany_cultmesh_node(store_path, runtime_id)?; + let receipt_key = + epiphany_cultmesh_bifrost_artifact_acceptance_receipt_key(&receipt.receipt_id); + let written = node.put(receipt_key.as_str(), &receipt)?; + node.put( + EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_LATEST_KEY, + &written, + )?; + node.flush()?; + Ok(written) +} + +pub fn load_latest_epiphany_cultmesh_bifrost_artifact_acceptance_receipt( + store_path: impl AsRef, + runtime_id: impl Into, +) -> Result> { + let node = open_epiphany_cultmesh_node(store_path, runtime_id)?; + node.get(EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_LATEST_KEY) +} + +#[allow(clippy::too_many_arguments)] +pub fn epiphany_cultmesh_bifrost_metrics_receipt_for_map_entry( + receipt_id: impl Into, + map_entry: &EpiphanyCultMeshRepoWorkMapEntry, + artifact_acceptance_receipt_id: impl Into, + model_spend_receipt_ids: Vec, + review_load_receipt_ids: Vec, + credit_readback_receipt_ids: Vec, + public_proof_ref: impl Into, + metrics_summary: impl Into, + status: impl Into, +) -> EpiphanyCultMeshBifrostMetricsReceiptEntry { + EpiphanyCultMeshBifrostMetricsReceiptEntry { + schema_version: EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_SCHEMA_VERSION.to_string(), + receipt_id: receipt_id.into(), + item: map_entry.item.clone(), + source_workspace: map_entry.workspace.clone(), + source_branch: map_entry.branch.clone(), + artifact_acceptance_receipt_id: artifact_acceptance_receipt_id.into(), + model_spend_receipt_ids, + review_load_receipt_ids, + credit_readback_receipt_ids, + public_proof_ref: public_proof_ref.into(), + metrics_summary: metrics_summary.into(), + status: status.into(), + private_state_exposed: false, + notes: vec![ + "Bifrost metrics receipt closes model-spend, review-load, accepted-artifact, and credit-readback accounting for branch work.".to_string(), + "Metrics are operator-safe refs and summaries, not private worker transcripts or raw model streams.".to_string(), + "Repo-work request cargo may ask for this receipt, but Bifrost/Maintainer owns accounting.".to_string(), + ], + } +} + +pub fn write_epiphany_cultmesh_bifrost_metrics_receipt( + store_path: impl AsRef, + runtime_id: impl Into, + receipt: EpiphanyCultMeshBifrostMetricsReceiptEntry, +) -> Result { + validate_bifrost_metrics_receipt(&receipt)?; + let mut node = open_epiphany_cultmesh_node(store_path, runtime_id)?; + let receipt_key = epiphany_cultmesh_bifrost_metrics_receipt_key(&receipt.receipt_id); + let written = node.put(receipt_key.as_str(), &receipt)?; + node.put( + EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_LATEST_KEY, + &written, + )?; + node.flush()?; + Ok(written) +} + +pub fn load_latest_epiphany_cultmesh_bifrost_metrics_receipt( + store_path: impl AsRef, + runtime_id: impl Into, +) -> Result> { + let node = open_epiphany_cultmesh_node(store_path, runtime_id)?; + node.get(EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_LATEST_KEY) +} + pub fn epiphany_cultmesh_bifrost_collaboration_feedback( feedback_id: impl Into, source_persona_id: impl Into, @@ -4542,6 +4749,115 @@ fn validate_bifrost_public_proof_publication_receipt( Ok(()) } +fn validate_bifrost_artifact_acceptance_receipt( + receipt: &EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry, +) -> Result<()> { + if receipt.schema_version + != EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_SCHEMA_VERSION + { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require schema version {}", + EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_SCHEMA_VERSION + )); + } + if receipt.private_state_exposed { + return Err(anyhow!( + "Bifrost artifact acceptance receipts must not expose private state" + )); + } + if receipt.item.trim().is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require an item" + )); + } + if receipt.artifact_ref.trim().is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require an artifact ref" + )); + } + if receipt.public_proof_ref.trim().is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require a public proof ref" + )); + } + if receipt.commit_sha.trim().is_empty() || receipt.commit_sha == "none" { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require a commit SHA" + )); + } + if receipt.changed_paths.is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require changed paths" + )); + } + if receipt.maintainer_review_receipt_ids.is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require maintainer review receipts" + )); + } + if receipt.bifrost_ledger_entry_id.trim().is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require a ledger entry" + )); + } + if receipt.accepted_by.trim().is_empty() { + return Err(anyhow!( + "Bifrost artifact acceptance receipts require an accepted-by authority" + )); + } + Ok(()) +} + +fn validate_bifrost_metrics_receipt( + receipt: &EpiphanyCultMeshBifrostMetricsReceiptEntry, +) -> Result<()> { + if receipt.schema_version != EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_SCHEMA_VERSION { + return Err(anyhow!( + "Bifrost metrics receipts require schema version {}", + EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_SCHEMA_VERSION + )); + } + if receipt.private_state_exposed { + return Err(anyhow!( + "Bifrost metrics receipts must not expose private state" + )); + } + if receipt.item.trim().is_empty() { + return Err(anyhow!("Bifrost metrics receipts require an item")); + } + if receipt.artifact_acceptance_receipt_id.trim().is_empty() { + return Err(anyhow!( + "Bifrost metrics receipts require an artifact acceptance receipt" + )); + } + if receipt.model_spend_receipt_ids.is_empty() { + return Err(anyhow!( + "Bifrost metrics receipts require model spend receipts" + )); + } + if receipt.review_load_receipt_ids.is_empty() { + return Err(anyhow!( + "Bifrost metrics receipts require review load receipts" + )); + } + if receipt.credit_readback_receipt_ids.is_empty() { + return Err(anyhow!( + "Bifrost metrics receipts require credit readback receipts" + )); + } + if receipt.public_proof_ref.trim().is_empty() { + return Err(anyhow!( + "Bifrost metrics receipts require a public proof ref" + )); + } + if receipt.metrics_summary.trim().is_empty() { + return Err(anyhow!( + "Bifrost metrics receipts require a metrics summary" + )); + } + Ok(()) +} + fn validate_bifrost_collaboration_feedback( feedback: &EpiphanyCultMeshBifrostCollaborationFeedbackEntry, ) -> Result<()> { @@ -5784,6 +6100,14 @@ fn epiphany_cultmesh_bifrost_public_proof_publication_receipt_key(receipt_id: &s format!("gamecult-local/bifrost/public-proof-publication-receipt/{receipt_id}") } +fn epiphany_cultmesh_bifrost_artifact_acceptance_receipt_key(receipt_id: &str) -> String { + format!("gamecult-local/bifrost/artifact-acceptance-receipt/{receipt_id}") +} + +fn epiphany_cultmesh_bifrost_metrics_receipt_key(receipt_id: &str) -> String { + format!("gamecult-local/bifrost/metrics-receipt/{receipt_id}") +} + fn epiphany_cultmesh_bifrost_collaboration_feedback_key(feedback_id: &str) -> String { format!("gamecult-local/bifrost/collaboration-feedback/{feedback_id}") } diff --git a/epiphany-core/src/lib.rs b/epiphany-core/src/lib.rs index 6e8ae6f5..de7aa514 100644 --- a/epiphany-core/src/lib.rs +++ b/epiphany-core/src/lib.rs @@ -117,6 +117,9 @@ pub use cultcache_rs::SingleFileMessagePackBackingStore; pub use cultmesh_integration::EPIPHANY_CULTMESH_AGENT_STATE_SOA_SUMMARY_LATEST_KEY; pub use cultmesh_integration::EPIPHANY_CULTMESH_AGENT_STATE_SOA_SUMMARY_SCHEMA_VERSION; pub use cultmesh_integration::EPIPHANY_CULTMESH_AGENT_STATE_SOA_SUMMARY_TYPE; +pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_LATEST_KEY; +pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_SCHEMA_VERSION; +pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_ARTIFACT_ACCEPTANCE_RECEIPT_TYPE; pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_BODY_CHANGE_PUBLICATION_INTENT_LATEST_KEY; pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_BODY_CHANGE_PUBLICATION_INTENT_SCHEMA_VERSION; pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_BODY_CHANGE_PUBLICATION_INTENT_TYPE; @@ -131,6 +134,9 @@ pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_CONTRACT_TYPE; pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_GITHUB_PUBLICATION_RECEIPT_LATEST_KEY; pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_GITHUB_PUBLICATION_RECEIPT_SCHEMA_VERSION; pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_GITHUB_PUBLICATION_RECEIPT_TYPE; +pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_LATEST_KEY; +pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_SCHEMA_VERSION; +pub use cultmesh_integration::EPIPHANY_CULTMESH_BIFROST_METRICS_RECEIPT_TYPE; pub use cultmesh_integration::EPIPHANY_CULTMESH_CONTINUITY_CONTRACT_SCHEMA_VERSION; pub use cultmesh_integration::EPIPHANY_CULTMESH_CONTINUITY_CONTRACT_TYPE; pub use cultmesh_integration::EPIPHANY_CULTMESH_COORDINATOR_RUN_RECEIPT_LATEST_KEY; @@ -237,11 +243,13 @@ pub use cultmesh_integration::EPIPHANY_CULTMESH_WORK_LOOP_TELEMETRY_LATEST_KEY; pub use cultmesh_integration::EPIPHANY_CULTMESH_WORK_LOOP_TELEMETRY_SCHEMA_VERSION; pub use cultmesh_integration::EPIPHANY_CULTMESH_WORK_LOOP_TELEMETRY_TYPE; pub use cultmesh_integration::EpiphanyCultMeshAgentStateSoaSummaryEntry; +pub use cultmesh_integration::EpiphanyCultMeshBifrostArtifactAcceptanceReceiptEntry; pub use cultmesh_integration::EpiphanyCultMeshBifrostBodyChangePublicationIntentEntry; pub use cultmesh_integration::EpiphanyCultMeshBifrostBodyChangePublicationReceiptEntry; pub use cultmesh_integration::EpiphanyCultMeshBifrostCollaborationFeedbackEntry; pub use cultmesh_integration::EpiphanyCultMeshBifrostContractEntry; pub use cultmesh_integration::EpiphanyCultMeshBifrostGithubPublicationReceiptEntry; +pub use cultmesh_integration::EpiphanyCultMeshBifrostMetricsReceiptEntry; pub use cultmesh_integration::EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry; pub use cultmesh_integration::EpiphanyCultMeshClusterTopologyEntry; pub use cultmesh_integration::EpiphanyCultMeshContinuityContractEntry; @@ -294,11 +302,13 @@ pub use cultmesh_integration::default_epiphany_cultmesh_operator_status; pub use cultmesh_integration::default_epiphany_cultmesh_swarm_brake; pub use cultmesh_integration::epiphany_cluster_service_execution_audit_report; pub use cultmesh_integration::epiphany_cultmesh_agent_state_soa_summary_from_entry; +pub use cultmesh_integration::epiphany_cultmesh_bifrost_artifact_acceptance_receipt_for_map_entry; pub use cultmesh_integration::epiphany_cultmesh_bifrost_body_change_publication_intent; pub use cultmesh_integration::epiphany_cultmesh_bifrost_body_change_publication_receipt_for_intent; pub use cultmesh_integration::epiphany_cultmesh_bifrost_collaboration_feedback; pub use cultmesh_integration::epiphany_cultmesh_bifrost_contracts; pub use cultmesh_integration::epiphany_cultmesh_bifrost_github_publication_receipt_for_publication; +pub use cultmesh_integration::epiphany_cultmesh_bifrost_metrics_receipt_for_map_entry; pub use cultmesh_integration::epiphany_cultmesh_bifrost_public_proof_publication_receipt_for_proof; pub use cultmesh_integration::epiphany_cultmesh_continuity_contracts; pub use cultmesh_integration::epiphany_cultmesh_coordinator_run_receipt_from_summary_json; @@ -344,10 +354,12 @@ pub use cultmesh_integration::load_epiphany_cultmesh_repo_work_readiness_reviews pub use cultmesh_integration::load_epiphany_cultmesh_status; pub use cultmesh_integration::load_epiphany_cultmesh_swarm_brake; pub use cultmesh_integration::load_latest_epiphany_cultmesh_agent_state_soa_summary; +pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_artifact_acceptance_receipt; pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_body_change_publication_intent; pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_body_change_publication_receipt; pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_collaboration_feedback; pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_github_publication_receipt; +pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_metrics_receipt; pub use cultmesh_integration::load_latest_epiphany_cultmesh_bifrost_public_proof_publication_receipt; pub use cultmesh_integration::load_latest_epiphany_cultmesh_coordinator_run_receipt; pub use cultmesh_integration::load_latest_epiphany_cultmesh_daemon_poke_intent; @@ -377,11 +389,13 @@ pub use cultmesh_integration::open_epiphany_cultmesh_node; pub use cultmesh_integration::query_epiphany_local_verse_context; pub use cultmesh_integration::seed_epiphany_local_verse_context; pub use cultmesh_integration::write_epiphany_cultmesh_agent_state_soa_summary; +pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_artifact_acceptance_receipt; pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_body_change_publication_intent; pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_body_change_publication_receipt; pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_collaboration_feedback; pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_contracts; pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_github_publication_receipt; +pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_metrics_receipt; pub use cultmesh_integration::write_epiphany_cultmesh_bifrost_public_proof_publication_receipt; pub use cultmesh_integration::write_epiphany_cultmesh_continuity_contracts; pub use cultmesh_integration::write_epiphany_cultmesh_coordinator_run_receipt; diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 00dbee34..d65980a3 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -192,7 +192,8 @@ 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-ledger` is the compact Bifrost/Imagination readback rite; use it after collaboration or publication writes to see the latest body-change, public-proof, GitHub, feedback, consensus, credit/review-count, and accounting closure rows without opening the full local Verse. +- `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. Direct proofs used `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-125053` and `.epiphany-smoke\repo-metrics-request-family-20260621-125549`; wrapper proof `local-20260621-135823-262-c40f73b6` read the closed metrics row with `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`. - 2026-06-19: The Self service tool readbacks now carry Idunn ownership at the top-level tool mouth, not only inside action rows. `serviceHealthReadback` and `swarmOnlineRunbookReadback` both include `lifecycleOwner=Idunn` and `hostedBody=Epiphany`; source smoke guards both fields; wrapper `tool-invoke` summaries print `owner=Idunn:hostedBody=Epiphany`. Live proofs `local-20260619-034243-246-b5704cd8` (`service-health`) and `local-20260619-034148-683-ea6c0ed6` (`swarm-online-runbook`) stayed non-mutating and `privateStateExposed=False`. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index c4eb59e62db9376a3985e51a0c6a336ee17cae5f..32638a8ea9f8a12b64a8957f18c8c753f934292c 100644 GIT binary patch delta 457 zcmZXOyGjE=6o%czEd<3TEU3)^6(Q`Jy_gtNT8eg7BFH#%VwNO3lbH!|3khQ318CS< z5Nrhn$qU%|7Gh!N8#qaf2o^sB^Iy(4{BYhrokz!7h-!XN3#&)3Gxl@wY1Qgj*2UEz zcRk2iMx!@xH2X5h+4qly+hOR370<7DVQ?5sx;J-UD|_#|ab0qyO9v!Qv=K@ml%mkc zJR)^mCsYGT7_?E#m@1$xuDTLIBE?u}1uf$ut7TsgIj7%~u|@?t706)PKbb6&gyP9h z?eFC8ALCTHa5^FKTFA}}&FG$4l-TK_(ja+H0Z&>f816RchH-yc+y}MCEE2d0{2==$2pKj!r9}G)XbLoX;2X$Tq(LK9!y{ delta 53 zcmX^6N^Ivdu?=F3)7NffWoL^z#=yEsY_l?BAtPf=^HiqxsZ5MO45FEVm}UD^Ce|ez E01Imagination` / `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, 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, and Bifrost 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 now 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 become `open` when a Mind-admitted `repo.artifact_acceptance_request` or `repo.metrics_request` map entry exists, carrying the latest Mind commit receipt, Bifrost gate, commit ref, closure review count, and changed-path count without granting final acceptance, metrics, credit, publication, merge, upstream sync, deployment, service lifecycle, Hands, or private-state authority. Native proofs `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-122343` and `.epiphany-smoke\repo-metrics-request-family-20260621-122503` reported open request rows; wrapper proof `local-20260621-132626-365-878a1113` printed the open metrics request row from the repo-local Verse target. Native proof `.epiphany-smoke\repo-work-readiness-20260621-120755` remains provenance for the closed readiness-review row; wrapper proof `local-20260621-131113-240-be2b19f2` proved `bifrost-ledger` honors explicit repo-local Verse read targets. + - `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. Native proofs `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-125053` and `.epiphany-smoke\repo-metrics-request-family-20260621-125549` proved open request rows become closed receipt rows without private-state exposure; wrapper proof `local-20260621-135823-262-c40f73b6` printed the closed metrics row from the repo-local Verse target. - `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. @@ -649,5 +649,5 @@ current_status: - `tools/epiphany_local_run.ps1 -Mode swarm-online-runbook` now emits an explicit Idunn preflight summary before the operator elevation boundary. Its JSON and one-line summary report `preflightStatus`, child artifact present/hash-verified/mismatch/missing counts, aggregate service execution failed/missing check counts, child preflight rows with expected/actual SHA-256s, and private-state exposure. Live proof `local-20260619-025627-410-9724e2f6` generated the non-mutating parent artifact with `preflightStatus=ready-for-elevated-operator`, two child runbooks present, two hashes verified, zero mismatches, zero missing artifacts, eleven failed sealed service checks, zero missing checks, explicit aftercare audits, and `privateStateExposed=false`. The remaining scar is still explicit elevated operator execution followed by complete Idunn audits, not missing parent/child artifact readiness. - 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: Bifrost ledger accounting now sees artifact-acceptance and metrics requests as open external-work request lanes without treating them as final acceptance or metrics truth. `epiphany-verse-query bifrost-ledger` derives six accounting rows; the new `artifact-acceptance-request` and `metrics-request` rows come from Mind-admitted repo-work map entries for safe families `repo.artifact_acceptance_request` and `repo.metrics_request`, carry the latest Mind commit receipt, Bifrost gate, commit ref, closure review count, changed-path artifact count, and `privateStateExposed=false`, and grant no artifact acceptance, metrics ledger, credit, publication, merge, upstream sync, deployment, service lifecycle, or Hands authority. Native proofs `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-122343` and `.epiphany-smoke\repo-metrics-request-family-20260621-122503` reported `accountingRowCount=6`, `status=open`, `reviewReceiptCount=3`, and `publicArtifactCount=1` for the relevant lane; wrapper proof `local-20260621-132626-365-878a1113` printed the open metrics request row from the repo-local Verse target. - next_action: Continue repo-swarm MVP work from `notes/epiphany-repo-swarm-mvp-contract.md`. Useful next cuts are final accepted-artifact/metrics ledger receipt surfaces, another useful repo-owned safe action family if needed, or explicit elevated/operator Idunn execution proof only when the human grants that authority. 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 open artifact/metrics request rows, 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, and readiness review/adoption receipt validation 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. + last_completed_repo_swarm_cut: Bifrost/Maintainer final closure receipts now exist for accepted-artifact and metrics accounting. `epiphany-verse-query bifrost-artifact-acceptance` writes typed artifact acceptance receipts from explicit artifact/public-proof/ledger/review refs; `epiphany-verse-query bifrost-metrics` writes typed metrics receipts from accepted-artifact, model-spend, review-load, credit-readback, public-proof, and summary refs; `bifrost-ledger` counts those receipts and closes the `artifact-acceptance-request` and `metrics-request` accounting rows only when the receipt evidence is present and private-state sealed. Wrapper modes `bifrost-artifact-acceptance`, `bifrost-metrics`, and `bifrost-ledger` expose the same safe-family closure/readback path. Native proofs `.epiphany-smoke\repo-artifact-acceptance-request-family-20260621-125053` and `.epiphany-smoke\repo-metrics-request-family-20260621-125549` closed the rows; wrapper proof `local-20260621-135823-262-c40f73b6` printed the closed metrics row with `privateStateExposed=False`. + next_action: Continue repo-swarm MVP work from `notes/epiphany-repo-swarm-mvp-contract.md`. Useful next cuts are another useful repo-owned safe action family if needed, broader fresh-repo proof bundling around the now-closed Bifrost accounting path, or explicit elevated/operator Idunn execution proof only when the human grants that authority. 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, and readiness review/adoption receipt validation 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. diff --git a/tools/epiphany_local_run.ps1 b/tools/epiphany_local_run.ps1 index f2e428e6..2e0047f8 100644 --- a/tools/epiphany_local_run.ps1 +++ b/tools/epiphany_local_run.ps1 @@ -1,5 +1,5 @@ param( - [ValidateSet("status", "plan", "smoke", "run", "mvp", "agent-state-soa", "swarm-status", "swarm-poke-down", "swarm-triage", "cluster-topology", "eve-surfaces", "eve-connect", "collaboration-feedback", "bifrost-publication", "bifrost-public-proof", "bifrost-ledger", "receipt-directory", "tool-directory", "tool-invoke", "swarm-overview", "gjallar", "repo-persona-intake", "repo-swarm-run", "repo-work-queue-run", "repo-work-readiness", "repo-work-readiness-review", "repo-deployment-config-audit", "repo-deployment-runbook", "repo-deployment-aftercare-audit", "repo-work-service-plan", "repo-work-service-runbook", "repo-work-service-launch", "repo-work-service-audit", "swarm-online-runbook", "service-policy-directory", "service-plan", "service-launch", "service-runbook", "cluster-service-runbook", "cluster-service-install-plan", "cluster-service-install-execute", "cluster-service-audit", "cluster-service-start-plan", "cluster-service-stop-plan", "cluster-service-start-execute", "cluster-service-stop-execute", "cluster-service-execution-readiness", "cluster-service-execution-runbook", "cluster-service-execution-audit", "service-execution-runbook", "service-install-plan", "service-install-execute", "service-tick", "service-status", "service-reconcile", "service-execution-readiness", "service-execution-audit", "service-start-plan", "service-stop-plan", "service-start-execute", "service-stop-execute")] + [ValidateSet("status", "plan", "smoke", "run", "mvp", "agent-state-soa", "swarm-status", "swarm-poke-down", "swarm-triage", "cluster-topology", "eve-surfaces", "eve-connect", "collaboration-feedback", "bifrost-publication", "bifrost-public-proof", "bifrost-artifact-acceptance", "bifrost-metrics", "bifrost-ledger", "receipt-directory", "tool-directory", "tool-invoke", "swarm-overview", "gjallar", "repo-persona-intake", "repo-swarm-run", "repo-work-queue-run", "repo-work-readiness", "repo-work-readiness-review", "repo-deployment-config-audit", "repo-deployment-runbook", "repo-deployment-aftercare-audit", "repo-work-service-plan", "repo-work-service-runbook", "repo-work-service-launch", "repo-work-service-audit", "swarm-online-runbook", "service-policy-directory", "service-plan", "service-launch", "service-runbook", "cluster-service-runbook", "cluster-service-install-plan", "cluster-service-install-execute", "cluster-service-audit", "cluster-service-start-plan", "cluster-service-stop-plan", "cluster-service-start-execute", "cluster-service-stop-execute", "cluster-service-execution-readiness", "cluster-service-execution-runbook", "cluster-service-execution-audit", "service-execution-runbook", "service-install-plan", "service-install-execute", "service-tick", "service-status", "service-reconcile", "service-execution-readiness", "service-execution-audit", "service-start-plan", "service-stop-plan", "service-start-execute", "service-stop-execute")] [string]$Mode = "smoke", [string]$Root = (Resolve-Path ".").Path, [string]$Workspace = "", @@ -44,6 +44,15 @@ param( [string]$BifrostPublicProofCreditReceipt = "credit-public-proof-local-proof", [string]$BifrostPublicProofRoomId = "epiphany-global/repo-work/public-proofs", [string]$BifrostPublicProofPublicationUrl = "", + [string]$BifrostArtifactRef = "artifact://epiphany/local-proof", + [string]$BifrostArtifactAcceptanceReceiptId = "", + [string]$BifrostArtifactAcceptanceReviewReceipt = "artifact-acceptance-review-local-proof", + [string]$BifrostArtifactAcceptedBy = "Maintainer/Bifrost", + [string]$BifrostMetricsReceiptId = "", + [string]$BifrostModelSpendReceipt = "model-spend-local-proof", + [string]$BifrostReviewLoadReceipt = "review-load-local-proof", + [string]$BifrostCreditReadbackReceipt = "credit-readback-local-proof", + [string]$BifrostMetricsSummary = "model spend, review load, accepted artifact, and credit readback recorded", [string]$ToolCapabilityId = "epiphany.cluster.hands.tool.repo-action", [string]$ToolRequestingAgentId = "epiphany.Persona", [string]$ToolRequestingClusterId = "epiphany.cluster.persona", @@ -365,7 +374,7 @@ $runtimeStore = Join-Path $Workspace "state\runtime-spine.msgpack" $liveRuntimeMode = @("run", "mvp") -contains $Mode if (-not $SkipBuild) { - if ($Mode -ne "status" -and $Mode -ne "agent-state-soa" -and $Mode -ne "swarm-status" -and $Mode -ne "swarm-poke-down" -and $Mode -ne "swarm-triage" -and $Mode -ne "cluster-topology" -and $Mode -ne "eve-surfaces" -and $Mode -ne "eve-connect" -and $Mode -ne "collaboration-feedback" -and $Mode -ne "bifrost-publication" -and $Mode -ne "bifrost-public-proof" -and $Mode -ne "bifrost-ledger" -and $Mode -ne "receipt-directory" -and $Mode -ne "tool-directory" -and $Mode -ne "tool-invoke" -and $Mode -ne "swarm-overview" -and $Mode -ne "gjallar" -and $Mode -ne "repo-persona-intake" -and $Mode -ne "repo-swarm-run" -and $Mode -ne "repo-work-queue-run" -and $Mode -ne "repo-work-readiness" -and $Mode -ne "repo-work-readiness-review" -and $Mode -ne "repo-deployment-config-audit" -and $Mode -ne "repo-deployment-runbook" -and $Mode -ne "repo-deployment-aftercare-audit" -and $Mode -ne "repo-work-service-plan" -and $Mode -ne "repo-work-service-runbook" -and $Mode -ne "repo-work-service-launch" -and $Mode -ne "repo-work-service-audit" -and $Mode -ne "swarm-online-runbook" -and $Mode -ne "service-policy-directory" -and $Mode -ne "service-plan" -and $Mode -ne "service-launch" -and $Mode -ne "service-runbook" -and $Mode -ne "cluster-service-runbook" -and $Mode -ne "cluster-service-install-plan" -and $Mode -ne "cluster-service-install-execute" -and $Mode -ne "cluster-service-audit" -and $Mode -ne "cluster-service-start-plan" -and $Mode -ne "cluster-service-stop-plan" -and $Mode -ne "cluster-service-start-execute" -and $Mode -ne "cluster-service-stop-execute" -and $Mode -ne "cluster-service-execution-readiness" -and $Mode -ne "cluster-service-execution-runbook" -and $Mode -ne "cluster-service-execution-audit" -and $Mode -ne "service-execution-runbook" -and $Mode -ne "service-install-plan" -and $Mode -ne "service-install-execute" -and $Mode -ne "service-tick" -and $Mode -ne "service-status" -and $Mode -ne "service-reconcile" -and $Mode -ne "service-execution-readiness" -and $Mode -ne "service-execution-audit" -and $Mode -ne "service-start-plan" -and $Mode -ne "service-stop-plan" -and $Mode -ne "service-start-execute" -and $Mode -ne "service-stop-execute") { + if ($Mode -ne "status" -and $Mode -ne "agent-state-soa" -and $Mode -ne "swarm-status" -and $Mode -ne "swarm-poke-down" -and $Mode -ne "swarm-triage" -and $Mode -ne "cluster-topology" -and $Mode -ne "eve-surfaces" -and $Mode -ne "eve-connect" -and $Mode -ne "collaboration-feedback" -and $Mode -ne "bifrost-publication" -and $Mode -ne "bifrost-public-proof" -and $Mode -ne "bifrost-artifact-acceptance" -and $Mode -ne "bifrost-metrics" -and $Mode -ne "bifrost-ledger" -and $Mode -ne "receipt-directory" -and $Mode -ne "tool-directory" -and $Mode -ne "tool-invoke" -and $Mode -ne "swarm-overview" -and $Mode -ne "gjallar" -and $Mode -ne "repo-persona-intake" -and $Mode -ne "repo-swarm-run" -and $Mode -ne "repo-work-queue-run" -and $Mode -ne "repo-work-readiness" -and $Mode -ne "repo-work-readiness-review" -and $Mode -ne "repo-deployment-config-audit" -and $Mode -ne "repo-deployment-runbook" -and $Mode -ne "repo-deployment-aftercare-audit" -and $Mode -ne "repo-work-service-plan" -and $Mode -ne "repo-work-service-runbook" -and $Mode -ne "repo-work-service-launch" -and $Mode -ne "repo-work-service-audit" -and $Mode -ne "swarm-online-runbook" -and $Mode -ne "service-policy-directory" -and $Mode -ne "service-plan" -and $Mode -ne "service-launch" -and $Mode -ne "service-runbook" -and $Mode -ne "cluster-service-runbook" -and $Mode -ne "cluster-service-install-plan" -and $Mode -ne "cluster-service-install-execute" -and $Mode -ne "cluster-service-audit" -and $Mode -ne "cluster-service-start-plan" -and $Mode -ne "cluster-service-stop-plan" -and $Mode -ne "cluster-service-start-execute" -and $Mode -ne "cluster-service-stop-execute" -and $Mode -ne "cluster-service-execution-readiness" -and $Mode -ne "cluster-service-execution-runbook" -and $Mode -ne "cluster-service-execution-audit" -and $Mode -ne "service-execution-runbook" -and $Mode -ne "service-install-plan" -and $Mode -ne "service-install-execute" -and $Mode -ne "service-tick" -and $Mode -ne "service-status" -and $Mode -ne "service-reconcile" -and $Mode -ne "service-execution-readiness" -and $Mode -ne "service-execution-audit" -and $Mode -ne "service-start-plan" -and $Mode -ne "service-stop-plan" -and $Mode -ne "service-start-execute" -and $Mode -ne "service-stop-execute") { Invoke-Checked ` -Label "build Codex app-server compatibility organ" ` -FilePath $cargoExe ` @@ -422,7 +431,7 @@ if (-not $SkipBuild) { } $requiredBinaries = @($statusExe, $operatorRunExe, $operatorSnapshotExe, $verseQueryExe, $swarmExe, $repoWorkExe, $daemonSupervisorExe, $handsActionExe) -if ($Mode -ne "status" -and $Mode -ne "agent-state-soa" -and $Mode -ne "swarm-status" -and $Mode -ne "swarm-poke-down" -and $Mode -ne "swarm-triage" -and $Mode -ne "cluster-topology" -and $Mode -ne "eve-surfaces" -and $Mode -ne "eve-connect" -and $Mode -ne "collaboration-feedback" -and $Mode -ne "bifrost-publication" -and $Mode -ne "bifrost-public-proof" -and $Mode -ne "bifrost-ledger" -and $Mode -ne "receipt-directory" -and $Mode -ne "tool-directory" -and $Mode -ne "tool-invoke" -and $Mode -ne "swarm-overview" -and $Mode -ne "gjallar" -and $Mode -ne "repo-persona-intake" -and $Mode -ne "repo-swarm-run" -and $Mode -ne "repo-work-queue-run" -and $Mode -ne "repo-work-readiness" -and $Mode -ne "repo-work-readiness-review" -and $Mode -ne "repo-deployment-config-audit" -and $Mode -ne "repo-deployment-runbook" -and $Mode -ne "repo-deployment-aftercare-audit" -and $Mode -ne "repo-work-service-plan" -and $Mode -ne "repo-work-service-runbook" -and $Mode -ne "repo-work-service-launch" -and $Mode -ne "repo-work-service-audit" -and $Mode -ne "swarm-online-runbook" -and $Mode -ne "service-policy-directory" -and $Mode -ne "service-plan" -and $Mode -ne "service-launch" -and $Mode -ne "service-runbook" -and $Mode -ne "cluster-service-runbook" -and $Mode -ne "cluster-service-install-plan" -and $Mode -ne "cluster-service-install-execute" -and $Mode -ne "cluster-service-audit" -and $Mode -ne "cluster-service-start-plan" -and $Mode -ne "cluster-service-stop-plan" -and $Mode -ne "cluster-service-start-execute" -and $Mode -ne "cluster-service-stop-execute" -and $Mode -ne "cluster-service-execution-readiness" -and $Mode -ne "cluster-service-execution-runbook" -and $Mode -ne "cluster-service-execution-audit" -and $Mode -ne "service-execution-runbook" -and $Mode -ne "service-install-plan" -and $Mode -ne "service-install-execute" -and $Mode -ne "service-tick" -and $Mode -ne "service-status" -and $Mode -ne "service-reconcile" -and $Mode -ne "service-execution-readiness" -and $Mode -ne "service-execution-audit" -and $Mode -ne "service-start-plan" -and $Mode -ne "service-stop-plan" -and $Mode -ne "service-start-execute" -and $Mode -ne "service-stop-execute") { +if ($Mode -ne "status" -and $Mode -ne "agent-state-soa" -and $Mode -ne "swarm-status" -and $Mode -ne "swarm-poke-down" -and $Mode -ne "swarm-triage" -and $Mode -ne "cluster-topology" -and $Mode -ne "eve-surfaces" -and $Mode -ne "eve-connect" -and $Mode -ne "collaboration-feedback" -and $Mode -ne "bifrost-publication" -and $Mode -ne "bifrost-public-proof" -and $Mode -ne "bifrost-artifact-acceptance" -and $Mode -ne "bifrost-metrics" -and $Mode -ne "bifrost-ledger" -and $Mode -ne "receipt-directory" -and $Mode -ne "tool-directory" -and $Mode -ne "tool-invoke" -and $Mode -ne "swarm-overview" -and $Mode -ne "gjallar" -and $Mode -ne "repo-persona-intake" -and $Mode -ne "repo-swarm-run" -and $Mode -ne "repo-work-queue-run" -and $Mode -ne "repo-work-readiness" -and $Mode -ne "repo-work-readiness-review" -and $Mode -ne "repo-deployment-config-audit" -and $Mode -ne "repo-deployment-runbook" -and $Mode -ne "repo-deployment-aftercare-audit" -and $Mode -ne "repo-work-service-plan" -and $Mode -ne "repo-work-service-runbook" -and $Mode -ne "repo-work-service-launch" -and $Mode -ne "repo-work-service-audit" -and $Mode -ne "swarm-online-runbook" -and $Mode -ne "service-policy-directory" -and $Mode -ne "service-plan" -and $Mode -ne "service-launch" -and $Mode -ne "service-runbook" -and $Mode -ne "cluster-service-runbook" -and $Mode -ne "cluster-service-install-plan" -and $Mode -ne "cluster-service-install-execute" -and $Mode -ne "cluster-service-audit" -and $Mode -ne "cluster-service-start-plan" -and $Mode -ne "cluster-service-stop-plan" -and $Mode -ne "cluster-service-start-execute" -and $Mode -ne "cluster-service-stop-execute" -and $Mode -ne "cluster-service-execution-readiness" -and $Mode -ne "cluster-service-execution-runbook" -and $Mode -ne "cluster-service-execution-audit" -and $Mode -ne "service-execution-runbook" -and $Mode -ne "service-install-plan" -and $Mode -ne "service-install-execute" -and $Mode -ne "service-tick" -and $Mode -ne "service-status" -and $Mode -ne "service-reconcile" -and $Mode -ne "service-execution-readiness" -and $Mode -ne "service-execution-audit" -and $Mode -ne "service-start-plan" -and $Mode -ne "service-stop-plan" -and $Mode -ne "service-start-execute" -and $Mode -ne "service-stop-execute") { $requiredBinaries += @($codexAppServer, $coordinatorExe) } function Assert-SwarmBrakeAllowsLiveRun { @@ -585,7 +594,7 @@ Invoke-Checked ` -StdoutPath (Join-Path $artifactRoot "operator-run-intent.stdout.json") ` -StderrPath (Join-Path $artifactRoot "operator-run-intent.stderr.log") -$compactReadOnlyModes = @("agent-state-soa", "swarm-status", "swarm-poke-down", "swarm-triage", "cluster-topology", "eve-surfaces", "eve-connect", "collaboration-feedback", "bifrost-publication", "bifrost-public-proof", "bifrost-ledger", "receipt-directory", "tool-directory", "tool-invoke", "swarm-overview", "gjallar", "swarm-online-runbook", "service-policy-directory") +$compactReadOnlyModes = @("agent-state-soa", "swarm-status", "swarm-poke-down", "swarm-triage", "cluster-topology", "eve-surfaces", "eve-connect", "collaboration-feedback", "bifrost-publication", "bifrost-public-proof", "bifrost-artifact-acceptance", "bifrost-metrics", "bifrost-ledger", "receipt-directory", "tool-directory", "tool-invoke", "swarm-overview", "gjallar", "swarm-online-runbook", "service-policy-directory") $isCompactReadOnlyMode = $compactReadOnlyModes -contains $Mode $shouldReadLocalVerse = $Mode -ne "smoke" -and -not $isCompactReadOnlyMode if ($shouldReadLocalVerse -and $Mode -ne "status" -and $Mode -ne "mvp") { @@ -883,6 +892,75 @@ if ($Mode -eq "bifrost-public-proof") { -StderrPath (Join-Path $artifactRoot "bifrost-public-proof.stderr.log") } +if ($Mode -eq "bifrost-artifact-acceptance") { + $resultPath = Join-Path $artifactRoot "bifrost-artifact-acceptance.stdout.json" + if (-not (Test-Path -LiteralPath $repoLocalVerseStore)) { + throw "repo-local Verse store not found for Bifrost artifact acceptance: $repoLocalVerseStore" + } + $receiptArgs = @( + "bifrost-artifact-acceptance", + "--store", $repoLocalVerseStore, + "--runtime-id", $RepoWorkRuntimeId, + "--artifact-ref", $BifrostArtifactRef, + "--ledger-entry-id", $BifrostLedgerEntryId, + "--review-receipt", $BifrostArtifactAcceptanceReviewReceipt, + "--source-agent-id", $BifrostArtifactAcceptedBy + ) + if ($BifrostArtifactAcceptanceReceiptId -ne "") { + $receiptArgs += @("--receipt-id", $BifrostArtifactAcceptanceReceiptId) + } + if ($BifrostPublicProofId -ne "") { + $receiptArgs += @("--public-proof-ref", $BifrostPublicProofId) + } elseif ($RepoWorkPublicProof -ne "") { + $receiptArgs += @("--public-proof-ref", $RepoWorkPublicProof) + } else { + $receiptArgs += @("--public-proof-ref", "repo-work-public-proof:latest") + } + Invoke-Checked ` + -Label "record Bifrost artifact acceptance receipt" ` + -FilePath $verseQueryExe ` + -Arguments $receiptArgs ` + -WorkingDirectory $Root ` + -StdoutPath $resultPath ` + -StderrPath (Join-Path $artifactRoot "bifrost-artifact-acceptance.stderr.log") +} + +if ($Mode -eq "bifrost-metrics") { + $resultPath = Join-Path $artifactRoot "bifrost-metrics.stdout.json" + if (-not (Test-Path -LiteralPath $repoLocalVerseStore)) { + throw "repo-local Verse store not found for Bifrost metrics: $repoLocalVerseStore" + } + $receiptArgs = @( + "bifrost-metrics", + "--store", $repoLocalVerseStore, + "--runtime-id", $RepoWorkRuntimeId, + "--model-spend-receipt", $BifrostModelSpendReceipt, + "--review-load-receipt", $BifrostReviewLoadReceipt, + "--credit-receipt", $BifrostCreditReadbackReceipt, + "--metrics-summary", $BifrostMetricsSummary + ) + if ($BifrostMetricsReceiptId -ne "") { + $receiptArgs += @("--receipt-id", $BifrostMetricsReceiptId) + } + if ($BifrostArtifactAcceptanceReceiptId -ne "") { + $receiptArgs += @("--accepted-artifact-receipt-id", $BifrostArtifactAcceptanceReceiptId) + } + if ($BifrostPublicProofId -ne "") { + $receiptArgs += @("--public-proof-ref", $BifrostPublicProofId) + } elseif ($RepoWorkPublicProof -ne "") { + $receiptArgs += @("--public-proof-ref", $RepoWorkPublicProof) + } else { + $receiptArgs += @("--public-proof-ref", "repo-work-public-proof:latest") + } + Invoke-Checked ` + -Label "record Bifrost metrics receipt" ` + -FilePath $verseQueryExe ` + -Arguments $receiptArgs ` + -WorkingDirectory $Root ` + -StdoutPath $resultPath ` + -StderrPath (Join-Path $artifactRoot "bifrost-metrics.stderr.log") +} + if ($Mode -eq "bifrost-ledger") { $resultPath = Join-Path $artifactRoot "bifrost-ledger.stdout.json" Invoke-Checked ` @@ -2458,6 +2536,26 @@ if ($resultPath -ne "" -and (Test-Path -LiteralPath $resultPath)) { Write-Host "Bifrost publication: status=$($result.status), intent=$($result.intentId), publication=$($result.publicationReceiptId), github=$($result.githubPublicationReceiptId), privateStateExposed=$($result.privateStateExposed)" } elseif ($Mode -eq "bifrost-public-proof") { Write-Host "Bifrost public proof: status=$($result.status), proof=$($result.publicProofId), receipt=$($result.receiptId), ledger=$($result.ledgerEntryId), public=$($result.publicationUrl), privateStateExposed=$($result.privateStateExposed)" + } elseif ($Mode -eq "bifrost-artifact-acceptance") { + $changedPaths = "none" + if ($null -ne $result.changedPaths -and $result.changedPaths.Count -gt 0) { + $changedPaths = ($result.changedPaths -join ",") + } + Write-Host "Bifrost artifact acceptance: status=$($result.status), item=$($result.item), receipt=$($result.receiptId), artifact=$($result.artifactRef), publicProof=$($result.publicProofRef), changedPaths=$changedPaths, privateStateExposed=$($result.privateStateExposed)" + } elseif ($Mode -eq "bifrost-metrics") { + $modelSpend = "none" + if ($null -ne $result.modelSpendReceiptIds -and $result.modelSpendReceiptIds.Count -gt 0) { + $modelSpend = ($result.modelSpendReceiptIds -join ",") + } + $reviewLoad = "none" + if ($null -ne $result.reviewLoadReceiptIds -and $result.reviewLoadReceiptIds.Count -gt 0) { + $reviewLoad = ($result.reviewLoadReceiptIds -join ",") + } + $creditReadback = "none" + if ($null -ne $result.creditReadbackReceiptIds -and $result.creditReadbackReceiptIds.Count -gt 0) { + $creditReadback = ($result.creditReadbackReceiptIds -join ",") + } + Write-Host "Bifrost metrics: status=$($result.status), item=$($result.item), receipt=$($result.receiptId), artifactAcceptance=$($result.artifactAcceptanceReceiptId), modelSpend=$modelSpend, reviewLoad=$reviewLoad, creditReadback=$creditReadback, privateStateExposed=$($result.privateStateExposed)" } elseif ($Mode -eq "bifrost-ledger") { $ledgerRows = "none" if ($null -ne $result.tuiRows -and $result.tuiRows.Count -gt 0) { @@ -2477,7 +2575,7 @@ if ($resultPath -ne "" -and (Test-Path -LiteralPath $resultPath)) { "$($_.documentKind)=${publicRef}" }) -join "; ") } - Write-Host "Bifrost ledger: status=$($result.status), rows=$($result.rowCount), publicationChain=$($result.publicationChainCount), collaborationChain=$($result.collaborationChainCount), accountingRows=$($result.accountingRowCount), closedAccounting=$($result.closedAccountingRowCount), attentionAccounting=$($result.attentionAccountingRowCount), publicRefs=$publicRefs, accounting=$accountingRows, ledgerRows=$ledgerRows, privateStateExposed=$($result.privateStateExposed)" + Write-Host "Bifrost ledger: status=$($result.status), rows=$($result.rowCount), publicationChain=$($result.publicationChainCount), publicProofPublications=$($result.publicProofPublicationCount), artifactAcceptance=$($result.artifactAcceptanceReceiptCount), metrics=$($result.metricsReceiptCount), collaborationChain=$($result.collaborationChainCount), accountingRows=$($result.accountingRowCount), closedAccounting=$($result.closedAccountingRowCount), attentionAccounting=$($result.attentionAccountingRowCount), publicRefs=$publicRefs, accounting=$accountingRows, ledgerRows=$ledgerRows, privateStateExposed=$($result.privateStateExposed)" } elseif ($Mode -eq "receipt-directory") { $artifactHashes = "none" $attentionRoutes = "none"