Add Bifrost ledger accounting readback

This commit is contained in:
Meta Vens 2026-06-21 09:13:30 +01:00
commit 0cee46932e
6 changed files with 302 additions and 5 deletions

View file

@ -1212,12 +1212,17 @@ fn run_cli() -> Result<()> {
"publicationChainCount": report.publication_chain_count,
"publicProofPublicationCount": report.public_proof_publication_count,
"collaborationChainCount": report.collaboration_chain_count,
"accountingRowCount": report.accounting_rows.len(),
"closedAccountingRowCount": report.closed_accounting_row_count,
"attentionAccountingRowCount": report.attention_accounting_row_count,
"latestBifrostPublicationIntent": report.latest_publication_intent_id,
"latestBifrostPublicationReceipt": report.latest_publication_receipt_id,
"latestBifrostGithubReceipt": report.latest_github_receipt_id,
"latestBifrostPublicProofPublicationReceipt": report.latest_public_proof_publication_receipt_id,
"latestBifrostCollaborationFeedback": report.latest_feedback_id,
"latestImaginationConsensusReceipt": report.latest_consensus_receipt_id,
"accountingTuiRows": report.accounting_tui_rows,
"accountingRows": report.accounting_rows,
"tuiRows": report.tui_rows,
"rows": report.rows,
"commands": {
@ -2690,6 +2695,9 @@ fn run_cli() -> Result<()> {
if bifrost_ledger_report.status != "ok"
|| bifrost_ledger_report.publication_chain_count != 3
|| bifrost_ledger_report.collaboration_chain_count != 2
|| bifrost_ledger_report.accounting_rows.len() != 3
|| bifrost_ledger_report.closed_accounting_row_count != 2
|| bifrost_ledger_report.attention_accounting_row_count != 0
|| bifrost_ledger_report.rows.len() != 5
|| bifrost_ledger_report.private_state_exposed
|| !bifrost_ledger_report.tui_rows.iter().any(|row| {
@ -2708,6 +2716,26 @@ fn run_cli() -> Result<()> {
)
&& row.contains("private=false")
})
|| !bifrost_ledger_report.accounting_tui_rows.iter().any(|row| {
row.contains("BIFROST-ACCOUNTING | body-change-publication")
&& row.contains("status=closed")
&& row.contains("intent=present publication=present github=present")
&& row.contains("review=1")
&& row.contains("credit=1")
&& row.contains("private=false")
})
|| !bifrost_ledger_report.accounting_tui_rows.iter().any(|row| {
row.contains("BIFROST-ACCOUNTING | public-proof-publication")
&& row.contains("status=missing")
&& row.contains("proof=missing")
&& row.contains("private=false")
})
|| !bifrost_ledger_report.accounting_tui_rows.iter().any(|row| {
row.contains("BIFROST-ACCOUNTING | collaboration-consensus")
&& row.contains("status=closed")
&& row.contains("feedback=present consensus=present")
&& row.contains("private=false")
})
{
anyhow::bail!("local Verse query smoke lost compact Bifrost ledger readback");
}
@ -4746,9 +4774,13 @@ struct BifrostLedgerReport {
status: String,
rows: Vec<BifrostLedgerRow>,
tui_rows: Vec<String>,
accounting_rows: Vec<BifrostAccountingRow>,
accounting_tui_rows: Vec<String>,
publication_chain_count: usize,
public_proof_publication_count: usize,
collaboration_chain_count: usize,
closed_accounting_row_count: usize,
attention_accounting_row_count: usize,
latest_publication_intent_id: Option<String>,
latest_publication_receipt_id: Option<String>,
latest_github_receipt_id: Option<String>,
@ -4808,6 +4840,22 @@ struct BifrostLedgerRow {
private_state_exposed: bool,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct BifrostAccountingRow {
lane: String,
owner: String,
status: String,
closure: String,
ledger_entry_id: String,
latest_receipt_id: String,
public_ref: String,
review_receipt_count: usize,
credit_receipt_count: usize,
public_artifact_count: usize,
private_state_exposed: bool,
}
#[derive(Clone, Serialize)]
#[serde(rename_all = "camelCase")]
struct DaemonToolDirectoryRow {
@ -8039,6 +8087,22 @@ fn bifrost_ledger_report(
let public_proof_publication_count = usize::from(latest_public_proof_publication.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(
latest_intent,
latest_publication,
latest_github,
latest_public_proof_publication,
latest_feedback,
latest_consensus,
);
let closed_accounting_row_count = accounting_rows
.iter()
.filter(|row| row.status == "closed")
.count();
let attention_accounting_row_count = accounting_rows
.iter()
.filter(|row| row.status == "attention" || row.private_state_exposed)
.count();
let private_state_exposed = rows.iter().any(|row| row.private_state_exposed);
let status = if rows.is_empty() {
"empty"
@ -8053,9 +8117,13 @@ fn bifrost_ledger_report(
status,
rows,
tui_rows,
accounting_rows,
accounting_tui_rows,
publication_chain_count,
public_proof_publication_count,
collaboration_chain_count,
closed_accounting_row_count,
attention_accounting_row_count,
latest_publication_intent_id: latest_intent.map(|intent| intent.intent_id.clone()),
latest_publication_receipt_id: latest_publication.map(|receipt| receipt.receipt_id.clone()),
latest_github_receipt_id: latest_github.map(|receipt| receipt.receipt_id.clone()),
@ -8089,6 +8157,220 @@ fn push_bifrost_ledger_row(
rows.push(row);
}
fn bifrost_accounting_rows(
latest_intent: Option<&EpiphanyCultMeshBifrostBodyChangePublicationIntentEntry>,
latest_publication: Option<&EpiphanyCultMeshBifrostBodyChangePublicationReceiptEntry>,
latest_github: Option<&EpiphanyCultMeshBifrostGithubPublicationReceiptEntry>,
latest_public_proof_publication: Option<
&EpiphanyCultMeshBifrostPublicProofPublicationReceiptEntry,
>,
latest_feedback: Option<&EpiphanyCultMeshBifrostCollaborationFeedbackEntry>,
latest_consensus: Option<&EpiphanyCultMeshImaginationConsensusReceiptEntry>,
) -> (Vec<BifrostAccountingRow>, Vec<String>) {
let mut rows = Vec::new();
let mut tui_rows = Vec::new();
let body_private = latest_intent
.map(|intent| intent.private_state_included)
.unwrap_or(false)
|| latest_publication
.map(|receipt| receipt.private_state_exposed)
.unwrap_or(false)
|| latest_github
.map(|receipt| receipt.private_state_exposed)
.unwrap_or(false);
let body_review_count = latest_publication
.map(|receipt| receipt.reviewer_ids.len())
.or_else(|| latest_intent.map(|intent| intent.review_receipt_ids.len()))
.unwrap_or(0);
let body_credit_count = latest_github
.map(|receipt| receipt.credit_receipt_ids.len())
.or_else(|| latest_publication.map(|receipt| receipt.credit_receipt_ids.len()))
.or_else(|| latest_intent.map(|intent| intent.credit_subjects.len()))
.unwrap_or(0);
let body_chain_closed = latest_intent.is_some()
&& latest_publication.is_some()
&& latest_github.is_some()
&& body_review_count > 0
&& body_credit_count > 0
&& !body_private;
push_bifrost_accounting_row(
&mut rows,
&mut tui_rows,
BifrostAccountingRow {
lane: "body-change-publication".to_string(),
owner: "Bifrost".to_string(),
status: bifrost_accounting_status(
body_chain_closed,
latest_intent.is_some() || latest_publication.is_some() || latest_github.is_some(),
body_private,
),
closure: format!(
"intent={} publication={} github={} review={} credit={}",
present_word(latest_intent.is_some()),
present_word(latest_publication.is_some()),
present_word(latest_github.is_some()),
body_review_count,
body_credit_count
),
ledger_entry_id: latest_publication
.map(|receipt| receipt.bifrost_ledger_entry_id.clone())
.or_else(|| latest_github.map(|receipt| receipt.ledger_entry_id.clone()))
.unwrap_or_else(|| "none".to_string()),
latest_receipt_id: latest_github
.map(|receipt| receipt.receipt_id.clone())
.or_else(|| latest_publication.map(|receipt| receipt.receipt_id.clone()))
.or_else(|| latest_intent.map(|intent| intent.intent_id.clone()))
.unwrap_or_else(|| "none".to_string()),
public_ref: latest_github
.map(|receipt| receipt.pull_request_url.clone())
.or_else(|| latest_publication.map(|receipt| receipt.publication_url.clone()))
.or_else(|| latest_intent.map(|intent| intent.target_branch.clone()))
.unwrap_or_else(|| "none".to_string()),
review_receipt_count: body_review_count,
credit_receipt_count: body_credit_count,
public_artifact_count: usize::from(latest_github.is_some()),
private_state_exposed: body_private,
},
);
let proof_private = latest_public_proof_publication
.map(|receipt| receipt.private_state_exposed)
.unwrap_or(false);
let proof_review_count = latest_public_proof_publication
.map(|receipt| receipt.reviewer_ids.len())
.unwrap_or(0);
let proof_credit_count = latest_public_proof_publication
.map(|receipt| receipt.credit_receipt_ids.len())
.unwrap_or(0);
let proof_closed = latest_public_proof_publication.is_some()
&& proof_review_count > 0
&& proof_credit_count > 0
&& !proof_private;
push_bifrost_accounting_row(
&mut rows,
&mut tui_rows,
BifrostAccountingRow {
lane: "public-proof-publication".to_string(),
owner: "Bifrost".to_string(),
status: bifrost_accounting_status(
proof_closed,
latest_public_proof_publication.is_some(),
proof_private,
),
closure: format!(
"proof={} review={} credit={}",
present_word(latest_public_proof_publication.is_some()),
proof_review_count,
proof_credit_count
),
ledger_entry_id: latest_public_proof_publication
.map(|receipt| receipt.bifrost_ledger_entry_id.clone())
.unwrap_or_else(|| "none".to_string()),
latest_receipt_id: latest_public_proof_publication
.map(|receipt| receipt.receipt_id.clone())
.unwrap_or_else(|| "none".to_string()),
public_ref: latest_public_proof_publication
.map(|receipt| receipt.publication_url.clone())
.unwrap_or_else(|| "none".to_string()),
review_receipt_count: proof_review_count,
credit_receipt_count: proof_credit_count,
public_artifact_count: usize::from(latest_public_proof_publication.is_some()),
private_state_exposed: proof_private,
},
);
let collaboration_private = latest_feedback
.map(|feedback| feedback.private_state_included)
.unwrap_or(false)
|| latest_consensus
.map(|receipt| receipt.private_state_exposed)
.unwrap_or(false);
let collaboration_public_count = latest_feedback
.map(|feedback| feedback.public_discussion_refs.len())
.unwrap_or(0)
+ latest_consensus
.map(|receipt| receipt.public_feedback_refs.len())
.unwrap_or(0);
let collaboration_closed =
latest_feedback.is_some() && latest_consensus.is_some() && !collaboration_private;
push_bifrost_accounting_row(
&mut rows,
&mut tui_rows,
BifrostAccountingRow {
lane: "collaboration-consensus".to_string(),
owner: "Persona->Imagination".to_string(),
status: bifrost_accounting_status(
collaboration_closed,
latest_feedback.is_some() || latest_consensus.is_some(),
collaboration_private,
),
closure: format!(
"feedback={} consensus={} publicRefs={}",
present_word(latest_feedback.is_some()),
present_word(latest_consensus.is_some()),
collaboration_public_count
),
ledger_entry_id: "none".to_string(),
latest_receipt_id: latest_consensus
.map(|receipt| receipt.receipt_id.clone())
.or_else(|| latest_feedback.map(|feedback| feedback.feedback_id.clone()))
.unwrap_or_else(|| "none".to_string()),
public_ref: latest_feedback
.map(|feedback| feedback.public_room_id.clone())
.unwrap_or_else(|| "none".to_string()),
review_receipt_count: 0,
credit_receipt_count: 0,
public_artifact_count: collaboration_public_count,
private_state_exposed: collaboration_private,
},
);
(rows, tui_rows)
}
fn push_bifrost_accounting_row(
rows: &mut Vec<BifrostAccountingRow>,
tui_rows: &mut Vec<String>,
row: BifrostAccountingRow,
) {
let private = if row.private_state_exposed {
"private=true"
} else {
"private=false"
};
tui_rows.push(format!(
"BIFROST-ACCOUNTING | {} | owner={} | status={} | {} | ledger={} | receipt={} | public={} | review={} | credit={} | artifacts={} | {private}",
row.lane,
row.owner,
row.status,
row.closure,
row.ledger_entry_id,
row.latest_receipt_id,
row.public_ref,
row.review_receipt_count,
row.credit_receipt_count,
row.public_artifact_count
));
rows.push(row);
}
fn bifrost_accounting_status(closed: bool, present: bool, private_state_exposed: bool) -> String {
if private_state_exposed {
"attention".to_string()
} else if closed {
"closed".to_string()
} else if present {
"open".to_string()
} else {
"missing".to_string()
}
}
fn present_word(present: bool) -> &'static str {
if present { "present" } else { "missing" }
}
fn collaboration_feedback_tui_rows(
feedback: &EpiphanyCultMeshBifrostCollaborationFeedbackEntry,
consensus: &EpiphanyCultMeshImaginationConsensusReceiptEntry,

View file

@ -1552,6 +1552,17 @@ published `repo-work-public-proof-checklist-request` to
`bifrost-public-proof-publication-checklist-request`, `status=ok`, and
`privateStateExposed=false`.
Bifrost ledger readback now also emits derived external-work accounting rows
without creating a rival ledger. `epiphany-verse-query bifrost-ledger` returns
`accountingRows` and `accountingTuiRows` for `body-change-publication`,
`public-proof-publication`, and `collaboration-consensus`, carrying closure
status, ledger/receipt/public refs, review and credit receipt counts, artifact
count, and the private-state seal. Wrapper proof
`local-20260621-091019-297-aaf2ad07` reported `accountingRows=3`,
`closedAccounting=2`, `attentionAccounting=0`, closed body-change and
collaboration rows, a visible missing public-proof-publication row, and
`privateStateExposed=False`.
Wrapper mode `tools/epiphany_local_run.ps1 -Mode bifrost-public-proof` now
exposes the same Bifrost mouth for operators and agents. It reads the latest
repo-local public proof row from `<workspace>\.epiphany\local-verse.ccmp` when

View file

@ -57,7 +57,7 @@ remembers doctrine; the branch remembers the blade.
- `epiphany-verse-query connect-eve` and `tools/epiphany_local_run.ps1 -Mode eve-connect` are the compact Odin-to-Eve connection receipt rite. The command now selects its target from the narrow Eve surface directory and verifies latest intent/receipt keys through narrow CultMesh loaders instead of serializing the full local Verse. The wrapper defaults to `epiphany.cluster.persona`, records intent `eve-connection-intent` plus receipt `eve-connection-receipt`, targets `eve://epiphany/persona`, and keeps `privateStateExposed=false`. Verified: direct temp proof and wrapper proof both returned `status=ok`.
- `epiphany-verse-query collaboration-feedback` and `tools/epiphany_local_run.ps1 -Mode collaboration-feedback` are the compact public Persona feedback to Imagination consensus receipt rite. The command verifies latest feedback/consensus keys through narrow CultMesh loaders and emits follow-on commands for wrapper feedback, Eve connection, direct Bifrost publication, and wrapper Bifrost publication. It returns TUI rows for the feedback and Imagination consensus receipt with `owner=Persona->Imagination`, `owner=Imagination`, `public=<ref>`, candidate action refs, consensus packet ref, adoption gate, and `private=false`. The wrapper first records the prerequisite Eve connection receipt, then writes feedback `collaboration-feedback` plus consensus `imagination-consensus-receipt`; proof `local-20260618-224207-941-2ca01b41` printed both compact rows in `feedbackRows`, including Persona public discussion feedback routed to Imagination consensus discovery, with `privateStateExposed=False`.
- `epiphany-verse-query bifrost-publication` and `tools/epiphany_local_run.ps1 -Mode bifrost-publication` are the compact non-mutating body-change publication proof rite. The command verifies latest Bifrost intent/publication/GitHub receipt keys through narrow CultMesh loaders and now emits follow-on commands for swarm overview, tool directory, and wrapper Bifrost publication readback. The wrapper supplies explicit proof defaults for target repo, changed path, verification/review receipts, credit subject, ledger id, Hands PR receipt id, and publication URL, then writes Bifrost intent, Bifrost publication receipt, and GitHub publication receipt with `privateStateExposed=false`. Verified: direct proof and wrapper proof both returned `status=ok`, and wrapper artifact `local-20260618-072118-704-3c5ae3da` carried the command hints.
- `epiphany-verse-query bifrost-ledger` and `tools/epiphany_local_run.ps1 -Mode bifrost-ledger` are the compact read-only Bifrost ledger sight rite. The command reads only the latest Bifrost body-change intent, Bifrost publication receipt, GitHub publication receipt, collaboration feedback, and Imagination consensus receipt through narrow CultMesh loaders, then returns five TUI rows when both chains exist. TUI rows include explicit `owner=<organ>`, `public=<ref>`, and `private=false`, and wrapper proof `local-20260618-223951-549-747c02f9` prints all five rows in `ledgerRows`: `owner=Bifrost` body-change intent/publication receipt, `owner=Bifrost/GitHub` GitHub publication receipt, `owner=Persona->Imagination` collaboration feedback, and `owner=Imagination` consensus receipt. Verified: source smoke and live wrapper both returned `status=ok`, `publicationChainCount=3`, `collaborationChainCount=2`, `rowCount=5`, and `privateStateExposed=false`.
- `epiphany-verse-query bifrost-ledger` and `tools/epiphany_local_run.ps1 -Mode bifrost-ledger` are the compact read-only Bifrost ledger sight rite. The command reads only the latest Bifrost body-change intent, Bifrost publication receipt, GitHub publication receipt, public-proof publication receipt, collaboration feedback, and Imagination consensus receipt through narrow CultMesh loaders. It returns raw ledger rows plus three derived `BIFROST-ACCOUNTING` rows for body-change publication, public-proof publication, and collaboration consensus, with closure status, ledger/receipt/public refs, review and credit receipt counts, artifact count, and private-state seal. Wrapper proof `local-20260621-091019-297-aaf2ad07` returned `accountingRows=3`, `closedAccounting=2`, `attentionAccounting=0`, closed body-change and collaboration rows, a visible missing public-proof-publication row, and `privateStateExposed=False`.
- `epiphany-verse-query receipt-directory` and `tools/epiphany_local_run.ps1 -Mode receipt-directory` are the compact latest-witness directory over local Verse. The command indexes typed projections for 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 without exposing raw payloads or private worker context. It treats sealed service lifecycle failure states such as `not-elevated`, `execution-refused-not-elevated`, and `incomplete` as operator attention instead of private-state exposure, routes cluster lifecycle wounds to `cluster-service-execution-audit`, preserves `service-execution-audit` for single-service receipts, and exposes the runbook witnesses as separate display-only `cluster-service-execution-runbook` and `service-execution-runbook` rows. 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 renders service lifecycle routes as `service-id::action` so compact rows name the owning lifecycle action without exposing raw audit payloads. Compact TUI rows append `followUp=<command>`, artifact status, and SHA-256; wrapper proof `local-20260618-205920-451-383b0da7` printed all seventeen rows in `receiptRows`, including missing Hands/role/work-loop gates, Bifrost/Imagination witnesses, scheduler follow-up, runbook hashes, and service lifecycle attention. `missingRowCount` remains as a compatibility alias for absent witnesses, not a fault signal. Attention routing is now Rust-owned too: JSON includes `attentionRouteRows` derived from the same predicate as `attentionRowCount`, and the wrapper prints that field instead of matching arbitrary status strings. Live proof `local-20260618-212134-758-c7c56240` showed the stale degraded Hands daemon-poke receipt remains an `OK` historical row while `attentionRoutes` names only the active cluster/single-service lifecycle wounds. Daemon-poke rows now also resolve historical receipt status against current daemon liveness: source smoke proves degraded remains degraded before heartbeat recovery and becomes `resolved` after ready status returns, and live wrapper proof `local-20260618-212649-563-48647018` printed the old Hands poke receipt as `OK | Self | daemon-poke | resolved`.
- Public doctrine source `https://gamecult.org/Blog/purge-the-heretek-from-our-daemonic-swarm` sharpens the current swarm audit: Odin sees but must not own, Gjallar is Odin's herald for whole-Verse sight, Idunn-like ledgers must advance instead of freezing old wounds, and Bifrost is the ledger gate for cross-repo purification receipts rather than transcript archaeology.
- `tools/epiphany_local_run.ps1` now stamps local run ids as `local-YYYYMMDD-HHMMSS-fff-<guid8>` instead of second-resolution ids, so concurrent operator rites get separate artifact roots and run receipts. Verified: `collaboration-feedback` and `bifrost-publication` launched in parallel in the same second and completed as `local-20260618-064814-171-dc0b8dd9` and `local-20260618-064814-149-2946d675`.
@ -181,7 +181,7 @@ remembers doctrine; the branch remembers the blade.
- `eve-connect` is the compact connection actuator for the advertised Eve surface; use it when the operator wants a typed collaboration receipt for Persona's public surface without opening the whole local Verse.
- `collaboration-feedback` is the compact public-feedback actuator; use it after or instead of manual `eve-connect` when Persona/human discussion should be routed to Imagination consensus discovery as typed local Verse receipts. Its JSON now points the next agent at Eve and Bifrost follow-on rites.
- `bifrost-publication` is the compact non-mutating Bifrost publication proof; use it to prove body-change routing, credit, and GitHub publication receipt state without performing GitHub mutation. Its JSON now points back to compact swarm overview and tool-directory readback.
- `bifrost-ledger` is the compact Bifrost/Imagination readback rite; use it after collaboration or publication writes to see the latest body-change, GitHub, feedback, and consensus receipts without opening the full local Verse.
- `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.
- `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`.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -2329,6 +2329,10 @@ if ($resultPath -ne "" -and (Test-Path -LiteralPath $resultPath)) {
if ($null -ne $result.tuiRows -and $result.tuiRows.Count -gt 0) {
$ledgerRows = ($result.tuiRows -join "; ")
}
$accountingRows = "none"
if ($null -ne $result.accountingTuiRows -and $result.accountingTuiRows.Count -gt 0) {
$accountingRows = ($result.accountingTuiRows -join "; ")
}
$publicRefs = "none"
if ($null -ne $result.rows -and $result.rows.Count -gt 0) {
$publicRefs = (($result.rows | ForEach-Object {
@ -2339,7 +2343,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), publicRefs=$publicRefs, ledgerRows=$ledgerRows, privateStateExposed=$($result.privateStateExposed)"
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)"
} elseif ($Mode -eq "receipt-directory") {
$artifactHashes = "none"
$attentionRoutes = "none"