From 1f5f8d1d64294f22cea8cb8a27858d3a65ca0fc9 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 13 Jul 2026 04:38:07 +0100 Subject: [PATCH] Separate metrics accounting and review evidence --- epiphany-core/src/bin/epiphany-verse-query.rs | 8 ++++---- epiphany-core/src/bin/epiphany-work.rs | 9 +++++++-- .../closure_contracts/external_governance.rs | 18 ++++++++++++++---- .../external_governance_tests.rs | 9 +++++++-- epiphany-core/src/cultmesh_integration.rs | 4 ++-- ...onceptual-substitution-audit-2026-07-12.md | 10 ++++++++++ notes/epiphany-current-algorithmic-map.md | 1 + notes/fresh-workspace-handoff.md | 5 +++++ state/ledgers.msgpack | Bin 476221 -> 476640 bytes state/map.yaml | 2 +- 10 files changed, 51 insertions(+), 15 deletions(-) diff --git a/epiphany-core/src/bin/epiphany-verse-query.rs b/epiphany-core/src/bin/epiphany-verse-query.rs index 24a49cf8..e654be91 100644 --- a/epiphany-core/src/bin/epiphany-verse-query.rs +++ b/epiphany-core/src/bin/epiphany-verse-query.rs @@ -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(), diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index 4c07fd9e..9a347f01 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -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(), diff --git a/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance.rs b/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance.rs index 06f962bc..133f7e42 100644 --- a/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance.rs +++ b/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance.rs @@ -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 { diff --git a/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance_tests.rs b/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance_tests.rs index 847c5d96..ef4690be 100644 --- a/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance_tests.rs +++ b/epiphany-core/src/bin/epiphany_work/closure_contracts/external_governance_tests.rs @@ -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()); diff --git a/epiphany-core/src/cultmesh_integration.rs b/epiphany-core/src/cultmesh_integration.rs index 3d1d0f45..1c13c8e3 100644 --- a/epiphany-core/src/cultmesh_integration.rs +++ b/epiphany-core/src/cultmesh_integration.rs @@ -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(), ], } } diff --git a/notes/conceptual-substitution-audit-2026-07-12.md b/notes/conceptual-substitution-audit-2026-07-12.md index ec75bc72..945286fc 100644 --- a/notes/conceptual-substitution-audit-2026-07-12.md +++ b/notes/conceptual-substitution-audit-2026-07-12.md @@ -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. diff --git a/notes/epiphany-current-algorithmic-map.md b/notes/epiphany-current-algorithmic-map.md index b1333dac..4b1b0691 100644 --- a/notes/epiphany-current-algorithmic-map.md +++ b/notes/epiphany-current-algorithmic-map.md @@ -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. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index fc9bf79b..80fe694d 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -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. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 9861ddf01acf12c9e399b5ec16d42f5cac68e1d9..ff9971deee07d06629be4b33bb32feb81eff3549 100644 GIT binary patch delta 378 zcmYk1zfJ-{5XQYj*~Ey}7KBM?5lu*p!HPiZpJ1g8S@uR;bGLiU&VkraSZHEmNA3Y^ zEKMw|XpN7-qqtz9#V<3-H#6Ti^QZFSx%|ExY#uca4zIq}L}&g{4TeE5ewc-ivoP>1 zYr(Vb+3*xUXQ6m&<>v*lU1&5L`QkDx?*#55jWt7pOj^0T(iYYHyCq7wX^XAtiPVNY zNMOgt0pUpFcrUgx0^dex6dr?1(L^9U|8+uzI%Nlv&IxNNjBxxU>&-c*pc7v>ua)(dzO01U$nC>3?w5+35gpe+ zS;Hh1gOV&`JIJuMGPWs_WJ{2ey+yT3REJalEZ`j@85!rLj;Q1>uSHRWR61Ax0U<_( At^fc4 delta 60 zcmaFRExWfvc7r4%mx+~;Mbt3{c4w*0%8Z4KjAhMJncAl^F#<7&W(HywAZ7((w(V1y I*jG3L05mfZ`~Uy| diff --git a/state/map.yaml b/state/map.yaml index 18d5e4e5..1d1e4ce6 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -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.