Separate metrics accounting and review evidence

This commit is contained in:
Meta Vens 2026-07-13 04:38:07 +01:00
commit 1f5f8d1d64
10 changed files with 51 additions and 15 deletions

View file

@ -1083,7 +1083,7 @@ fn run_cli() -> Result<()> {
|| args.receipt_status.is_some()
{
anyhow::bail!(
"bifrost-metrics inspects a pending repo request only; Bifrost/Maintainer owns accepted artifact, spend, review load, credit, proof, summary, and receipt result fields"
"bifrost-metrics inspects a pending request only; Bifrost owns accounting fields and Maintainer owns review-load evidence"
);
}
@ -1110,7 +1110,7 @@ fn run_cli() -> Result<()> {
"creditReadbackReceiptIds": [],
"publicProofRef": null,
"metricsSummary": null,
"responseOwner": "Bifrost/Maintainer",
"responseOwner": "Bifrost",
"commands": {
"swarmOverview": WRAPPER_OVERVIEW_COMMAND,
"bifrostMetrics": WRAPPER_BIFROST_METRICS_COMMAND,
@ -7802,7 +7802,7 @@ fn bifrost_ledger_report(
&mut tui_rows,
BifrostLedgerRow {
document_kind: "metrics-receipt".to_string(),
owner: "Bifrost/Maintainer".to_string(),
owner: "Bifrost".to_string(),
id: receipt.receipt_id.clone(),
status: receipt.status.clone(),
route: receipt.artifact_acceptance_receipt_id.clone(),
@ -8323,7 +8323,7 @@ fn push_metrics_accounting_row(
tui_rows,
BifrostAccountingRow {
lane: "metrics-request".to_string(),
owner: "Bifrost/Maintainer".to_string(),
owner: "Bifrost".to_string(),
status: bifrost_accounting_status(
false,
latest_request.is_some() || latest_receipt.is_some(),

View file

@ -4834,7 +4834,11 @@ fn derive_repo_metrics_request_plan(
"[request]".to_string(),
format!("id = {}", toml_basic_string(&request_id)),
"status = \"awaiting-metrics-review\"".to_string(),
"requested_owner = \"Bifrost/Maintainer\"".to_string(),
"routing_owner = \"Self\"".to_string(),
"accounting_owner = \"Bifrost\"".to_string(),
"review_evidence_owner = \"Maintainer\"".to_string(),
"spend_receipt_required = true".to_string(),
"review_load_receipt_required = true".to_string(),
"requested_effect = \"record-compute-review-and-artifact-accounting\"".to_string(),
format!(
"publication_request_ref = {}",
@ -4889,7 +4893,8 @@ fn derive_repo_metrics_request_plan(
"service_lifecycle_authority = false".to_string(),
"cross_body_mutation_authorized = false".to_string(),
"private_verse_rummaging = false".to_string(),
"bifrost_or_maintainer_metrics_authority_required = true".to_string(),
"bifrost_accounting_required = true".to_string(),
"maintainer_review_evidence_required = true".to_string(),
String::new(),
"[verification]".to_string(),
"asks = [".to_string(),

View file

@ -114,7 +114,11 @@ impl RepoMetricsRequest {
pub(super) fn awaits_owned_review(&self) -> bool {
self.request.status == "awaiting-metrics-review"
&& self.request.requested_owner == "Bifrost/Maintainer"
&& self.request.routing_owner == "Self"
&& self.request.accounting_owner == "Bifrost"
&& self.request.review_evidence_owner == "Maintainer"
&& self.request.spend_receipt_required
&& self.request.review_load_receipt_required
&& self.request.requested_effect == "record-compute-review-and-artifact-accounting"
&& !self.request.publication_request_ref.is_empty()
&& !self.request.credit_request_ref.is_empty()
@ -169,14 +173,19 @@ impl RepoMetricsRequest {
&& !a.service_lifecycle_authority
&& !a.cross_body_mutation_authorized
&& !a.private_verse_rummaging
&& a.bifrost_or_maintainer_metrics_authority_required
&& a.bifrost_accounting_required
&& a.maintainer_review_evidence_required
}
}
#[derive(Debug, Deserialize)]
struct RepoMetricsRequestBody {
status: String,
requested_owner: String,
routing_owner: String,
accounting_owner: String,
review_evidence_owner: String,
spend_receipt_required: bool,
review_load_receipt_required: bool,
requested_effect: String,
publication_request_ref: String,
credit_request_ref: String,
@ -231,7 +240,8 @@ struct RepoMetricsAuthority {
service_lifecycle_authority: bool,
cross_body_mutation_authorized: bool,
private_verse_rummaging: bool,
bifrost_or_maintainer_metrics_authority_required: bool,
bifrost_accounting_required: bool,
maintainer_review_evidence_required: bool,
}
pub(super) fn parse_repo_metrics_request(text: &str) -> Result<RepoMetricsRequest> {

View file

@ -85,7 +85,11 @@ summary = "summary"
private_state_exposed = false
[request]
status = "awaiting-metrics-review"
requested_owner = "Bifrost/Maintainer"
routing_owner = "Self"
accounting_owner = "Bifrost"
review_evidence_owner = "Maintainer"
spend_receipt_required = true
review_load_receipt_required = true
requested_effect = "record-compute-review-and-artifact-accounting"
publication_request_ref = "publication"
credit_request_ref = "credit"
@ -129,7 +133,8 @@ hands_action_authorized = false
service_lifecycle_authority = false
cross_body_mutation_authorized = false
private_verse_rummaging = false
bifrost_or_maintainer_metrics_authority_required = true
bifrost_accounting_required = true
maintainer_review_evidence_required = true
"#;
let request = parse_repo_metrics_request(text).expect("fixture is typed TOML");
assert!(!request.has_authority_seals());

View file

@ -4681,7 +4681,7 @@ pub fn epiphany_cultmesh_bifrost_artifact_acceptance_receipt_for_map_entry(
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(),
"Repo-work request cargo may ask for this receipt; Maintainer owns acceptance and Bifrost owns accounting.".to_string(),
],
}
}
@ -4743,7 +4743,7 @@ pub fn epiphany_cultmesh_bifrost_metrics_receipt_for_map_entry(
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(),
"Repo-work request cargo may ask for this receipt; Bifrost owns accounting and Maintainer owns review-load evidence.".to_string(),
],
}
}

View file

@ -1289,6 +1289,16 @@ with an explicit acceptance-receipt requirement. Operator projections label
artifact-acceptance receipts Maintainer-owned and the accounting lane
Bifrost-owned.
## Review-load evidence as Bifrost metrics ownership
`repo.metrics_request` named `Bifrost/Maintainer` and carried a
`bifrost_or_maintainer` authority gate. The request now assigns Self routing,
Bifrost accounting, and Maintainer review-load evidence separately. Model-spend
and review-load receipts are required observations; recording them grants no
spend, review-load, or ledger mutation authority. Metrics receipts and
accounting lanes are Bifrost-owned, while the contract catalogue explicitly
leaves review evidence with Maintainer.
The same inspection found 33 consecutive duplicate `#[cfg(test)]` attributes
on provider constructors/writers and their re-exports. One gate already makes
each item test-only; the second owned nothing. The duplicates are removed.

View file

@ -61,6 +61,7 @@
- Deployment requests split Self routing from independent Maintainer/Soul/Mind/Bifrost review and Idunn-only execution. Maintainer review cannot impersonate Idunn deployment; only Idunn deployment and aftercare receipts prove outcomes.
- PR requests split Self routing, Bifrost publication gating, Hands execution, and GitHub provider outcomes. GitHub receipt authorship does not grant publication-policy authority.
- Artifact acceptance requests split Self routing, Maintainer acceptance decisions, and Bifrost accounting. Acceptance receipts and accounting ledger rows no longer claim one composite owner.
- Metrics requests split Self routing, Bifrost accounting custody, and Maintainer review-load evidence. Spend/review receipts are observations and grant no spend or ledger authority.
- `repo.planning_brief` is deleted. It contained no candidate work-item records and let copied global catalog/schema/closure constants self-attest as per-item planning and readiness evidence. The live preparation chain is consensus draft -> interpretation request -> objective draft -> Mind adoption.
- There is no aggregate repo-swarm MVP gate. The former smoke manually aggregated fixture summaries into green rows and `demoReady=true`; it and its wrapper are deleted. Whole-organism readiness requires a live-fire path whose claimed consequences are observed at their owning boundaries.
- Persona owner: `collaboration-feedback` writes public, bounded feedback only after that provider receipt exists.

View file

@ -452,4 +452,9 @@ Bifrost records accounting, and the typed request requires the acceptance
receipt. Operator receipt and accounting rows report those separate owners.
Nine external-governance fixtures, 259 library tests, and all binaries pass.
Metrics/accounting no longer has a `Bifrost/Maintainer` composite or OR gate.
Self routes, Bifrost accounts, Maintainer owns review-load evidence, and spend/
review-load receipts are required observations without authorizing spend or
ledger mutation. Contract catalogue and operator rows use the same ownership.
The last completed code pass had 259 library tests passing and all binaries compiling. Re-run focused checks for the next touched surface; use the full library/binary baseline before committing a new architectural cut.

Binary file not shown.

View file

@ -660,4 +660,4 @@ current_status:
- Service lifecycle receipt history is now event-only: `load_epiphany_cultmesh_daemon_service_lifecycle_receipts` filters out the `epiphany-local/daemon-service-lifecycle-receipt/latest` mirror, while `load_latest_epiphany_cultmesh_daemon_service_lifecycle_receipt` remains the latest-state reader. Focused unit test `service_lifecycle_receipt_history_excludes_latest_mirror` proves two per-receipt writes return exactly two history records and latest points at the second. Fresh smoke `verse-query-lifecycle-history-filter-smoke` and live overview/triage `local-20260618-145632-497-efac6f0d` / `local-20260618-145632-321-867947af` prove compact swarm sights still expose service lifecycle attention plus the present elevated runbook artifact without daemon pokes or service mutation. Do not use a broad unscoped cargo test filter for this check on Windows; it fans out across bin harnesses and hit a broken pipe during this pass.
- `epiphany-verse-query seed-compact` is the compact seed receipt for wrappers and read-only rites. The older `seed` command still prints the full local Verse context for explicit debugging, but compact wrapper modes now avoid full `seed`/final `query` readback after the combined overview proof exposed Windows debug stack overflow from full-context serialization pressure.
last_completed_repo_swarm_cut: Huginn live-fire has crossed the first real repo Body from Persona pressure to branch-local Hands commit and Soul/Mind closure, and now has repeatable closure and redacted-public-proof mouths. On `E:\Projects\Huginn` branch `epiphany/huginn/first-awakening`, `tools/epiphany_local_run.ps1 -Mode repo-persona-intake` accepted item `huginn-inspection-readback-livefire`, Weksa/Persona intake remained sealed, and `epiphany-work derive-plan` lowered it to model-authored safe family `repo.status_section` for `README.md` only. `tools/epiphany_local_run.ps1 -Mode repo-swarm-run` advanced four bounded pulses: run-from-plan, adopt-from-plan, execute-from-plan, and close-from-execute. Huginn commit `e9b07c38fceabbdc89ea35c2156326c80c0393a2` updated only `README.md`; closure receipt `.epiphany\work\work-close-huginn-inspection-readback-livefire.json` records status `closed`, Soul verdict `passed`, Mind state commit `repo-work-close-huginn-inspection-readback-livefire-mind-commit`, safe family `repo.status_section`, path scope `README.md`, Bifrost publication gate, and `privateStateExposed=false`. Verification also ran Huginn's TypeScript compiler through concrete Node path: `C:\Program Files\nodejs\node.exe E:\Projects\Huginn\node_modules\typescript\bin\tsc -p tsconfig.json` passed. Native verifier `epiphany-repo-livefire-closure-smoke --workspace E:\Projects\Huginn --item huginn-inspection-readback-livefire --expected-path README.md --expected-family repo.status_section --expected-gate awaiting-publication --expected-blocker bifrost-publication-missing` checks closure receipt, Mind map entry, overview gate/blocker, authority seals, and `git show` changed paths, returning `status=ok`, `soulVerdict=passed`, `publicationGate=Bifrost`, and `privateStateExposed=false`. Wrapper `tools/epiphany_local_run.ps1 -Mode repo-livefire-closure -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exposes the same read-only proof through the local operator mouth; artifact `local-20260621-190156-803-2f85ba15` printed commit, path, gate, blocker, Soul verdict, Mind commit receipt, and `privateStateExposed=False` without push, merge, publication, or target mutation. New wrapper `tools/epiphany_local_run.ps1 -Mode repo-work-public-proof -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exports the redacted proof bundle and repo-local Verse index without publishing; artifact `local-20260621-190645-345-4555b1dc` wrote `.epiphany\public\proof-bundles\repo-work-public-proof-huginn-inspection-readback-livefire.json`, proof id `repo-work-public-proof-huginn-inspection-readback-livefire`, SHA-256 `857545b199f3e37eb06c2e757e5cfc201958e46667bb1f8403fd333a22620f63`, nine artifact rows, zero publication rows, and `privateStateExposed=False`. swarm overview readback `local-20260621-190701-140-b9519ec6` sees the `REPO-WORK-PUBLIC-PROOF` row and action row from Huginn's repo-local Verse with the same SHA-256 while Bifrost publication remains missing. Launcher compact modes are now named compact operator-context modes instead of read-only modes, and `bifrost-public-proof` summaries print item, target public Verse, room, proof SHA-256, review receipts, and credit receipts so publication receipts are auditable without claiming upstream sync.
next_action: Continue the beyond-closure composite-owner purge. Deployment, PR, and artifact acceptance are split: Self routes; Bifrost gates publication/accounts; Hands performs PR action; GitHub supplies provider receipts; Idunn executes deployment; Maintainer decides artifact acceptance. Remaining production findings include Bifrost/Maintainer metrics/accounting, Maintainer/Soul/Bifrost security/dependency policy, plus composite owner labels in epiphany-verse-query projections. Map and cut metrics/accounting next; keep closure's zero-substring invariant intact.
next_action: Continue the beyond-closure composite-owner purge. Deployment, PR, artifact acceptance, and metrics are split: Self routes; Bifrost gates/accounts; Maintainer accepts artifacts and owns review-load evidence; Hands performs PR action; GitHub supplies provider receipts; Idunn executes deployment. Remaining production findings include Maintainer/Soul/Bifrost security/dependency policy plus composite owner labels in epiphany-verse-query projections. Map and cut secret/dependency policy review next; keep closure's zero-substring invariant intact.