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 c4eb59e6..32638a8e 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 3bb93b41..005ded4a 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -627,7 +627,7 @@ current_status: - `epiphany-verse-query connect-eve` and `tools/epiphany_local_run.ps1 -Mode eve-connect` provide the compact Odin-to-Eve collaboration receipt. The command selects the daemon-published surface through the narrow Eve directory, writes connection intent/receipt documents, verifies latest receipt keys through narrow CultMesh loaders, defaults the wrapper target to `epiphany.cluster.persona`, and exposes no private state. - `epiphany-verse-query collaboration-feedback` and `tools/epiphany_local_run.ps1 -Mode collaboration-feedback` provide the public Persona feedback to Imagination consensus receipt path. The wrapper records the prerequisite Eve connection receipt, writes feedback plus Imagination consensus receipt documents, verifies latest keys through narrow CultMesh loaders, publishes follow-on command hints for wrapper feedback, Eve connection, direct Bifrost publication, and wrapper Bifrost publication, and exposes no private state. The command returns compact TUI rows for the feedback and Imagination consensus receipt with explicit `owner=Persona->Imagination` / `owner=Imagination`, `public=`, candidate action refs, consensus packet ref, adoption gate, and `private=false`; wrapper proof `local-20260618-224207-941-2ca01b41` prints both rows in `feedbackRows`, including Persona public discussion feedback routed to Imagination consensus discovery before Mind/Bifrost adoption. - `epiphany-verse-query bifrost-publication` and `tools/epiphany_local_run.ps1 -Mode bifrost-publication` provide the non-mutating Bifrost body-change publication proof path. It writes Bifrost intent, Bifrost publication receipt, and GitHub publication receipt documents from explicit review/verification/credit inputs, verifies latest keys through narrow CultMesh loaders, publishes follow-on command hints for swarm overview, tool directory, and wrapper Bifrost publication readback, and exposes no private state. - - `epiphany-verse-query bifrost-ledger` and `tools/epiphany_local_run.ps1 -Mode bifrost-ledger` provide the compact Bifrost ledger sight organ. It reads only the latest Bifrost body-change intent, Bifrost publication receipt, GitHub publication receipt, public-proof publication receipt, 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"