Stop edge snapshots promoting tool receipts

This commit is contained in:
Meta Vens 2026-07-12 20:20:04 +01:00
commit ff862872d6
8 changed files with 44 additions and 29 deletions

View file

@ -1,14 +1,11 @@
use anyhow::Context;
use anyhow::Result;
use chrono::Utc;
use epiphany_core::epiphany_cultmesh_daemon_tool_invocation_from_status_json;
use epiphany_core::epiphany_cultmesh_operator_snapshot_from_status_json;
use epiphany_core::load_latest_epiphany_cultmesh_operator_snapshot;
use epiphany_core::write_epiphany_cultmesh_daemon_tool_invocation_intent;
use epiphany_core::write_epiphany_cultmesh_daemon_tool_invocation_receipt;
use epiphany_core::write_epiphany_cultmesh_operator_snapshot;
use serde_json::Value;
use serde_json::json;
use serde_json::Value;
use std::env;
use std::fs;
use std::path::PathBuf;
@ -31,34 +28,13 @@ fn main() -> Result<()> {
&status_json,
)?;
let written = write_epiphany_cultmesh_operator_snapshot(&args.store, snapshot)?;
let latest_tool_invocation = epiphany_cultmesh_daemon_tool_invocation_from_status_json(
args.runtime_id.clone(),
input.to_string_lossy(),
&status_json,
)?;
let mut written_tool_intent = None;
let mut written_tool_receipt = None;
if let Some((intent, receipt)) = latest_tool_invocation {
written_tool_intent = Some(write_epiphany_cultmesh_daemon_tool_invocation_intent(
&args.store,
args.runtime_id.clone(),
intent,
)?);
if let Some(receipt) = receipt {
written_tool_receipt =
Some(write_epiphany_cultmesh_daemon_tool_invocation_receipt(
&args.store,
args.runtime_id.clone(),
receipt,
)?);
}
}
print_json(json!({
"status": "written",
"store": args.store,
"snapshot": written,
"toolInvocationIntent": written_tool_intent,
"toolInvocationReceipt": written_tool_receipt,
"toolInvocationIntent": null,
"toolInvocationReceipt": null,
"toolInvocationAuthority": "runtime-spine-only",
}))?;
}
"latest" => {

View file

@ -2788,6 +2788,7 @@ pub fn epiphany_cultmesh_operator_snapshot_from_status_json(
})
}
#[cfg(test)]
pub fn epiphany_cultmesh_daemon_tool_invocation_from_status_json(
requesting_cluster_id: impl Into<String>,
status_path: impl Into<String>,

View file

@ -391,6 +391,7 @@ pub use cultmesh_integration::epiphany_cultmesh_daemon_poke_intent_from_status;
pub use cultmesh_integration::epiphany_cultmesh_daemon_poke_receipt_for_intent;
pub use cultmesh_integration::epiphany_cultmesh_daemon_statuses;
pub use cultmesh_integration::epiphany_cultmesh_daemon_tool_capabilities;
#[cfg(test)]
pub use cultmesh_integration::epiphany_cultmesh_daemon_tool_invocation_from_status_json;
pub use cultmesh_integration::epiphany_cultmesh_daemon_tool_invocation_intent_from_capability;
pub use cultmesh_integration::epiphany_cultmesh_daemon_tool_invocation_receipt_for_intent;

View file

@ -70,6 +70,14 @@
- Forbidden metrics writers: caller cannot provide accepted artifact, model spend, review load, credit, proof, summary, receipt, or status results.
- Negative proof: missing requests fail without receipt mutation and response-shaped arguments fail before lookup or write.
## Operator snapshot authority boundary (2026-07-12)
- Owner: operator snapshot adapter owns only a bounded summary of an edge status artifact.
- Runtime spine owns daemon-tool execution intent and receipt truth.
- Forbidden projection: `/tools/invocations` JSON cannot be promoted into canonical daemon-tool schemas by snapshot import.
- Output explicitly returns null tool intent/receipt fields and `toolInvocationAuthority=runtime-spine-only`.
- Negative proof: forged accepted tool JSON produced a snapshot but no canonical intent or receipt.
This is the source-grounded map of the live machine. Historical route and
bridge anatomy belongs in git history and evidence ledgers, not here.

View file

@ -32,6 +32,10 @@ Single poke, batch poke, and swarm triage now write only `epiphany.cultmesh.daem
`bifrost-artifact-acceptance` and `bifrost-metrics`, plus their wrappers, now inspect the latest Mind-admitted `repo.artifact_acceptance_request` / `repo.metrics_request` map entry and report `pending-maintainer-bifrost` / `pending-bifrost-maintainer`. They write no provider receipts. Artifact/proof/review/ledger/accepted-by/status fields and accepted-artifact/spend/review-load/credit/proof/summary/status fields are rejected respectively. The canonical local Verse currently contains neither request family, so negative proof showed clean missing-request failure, no receipt mutation, and rejection of counterfeit result fields. The original conceptual-substitution audit now records all confirmed substitutions as structurally cut; next audit every remaining production receipt-writer call site for provider provenance.
## 2026-07-12 receipt-writer provenance audit
The first call-site audit found a new canonical-promotion substitution in `epiphany-operator-snapshot from-status`: arbitrary edge JSON under `/tools/invocations` could be converted into canonical daemon-tool intent and receipt documents. That promotion is removed. The adapter writes only `operator_snapshot`, returns null tool intent/receipt fields, and states `runtime-spine-only` authority; the conversion helper is compiled only for tests. Forgery proof imported an `accepted` fake receipt and confirmed both canonical latest tool intent and receipt remained absent. See `notes/receipt-writer-provenance-audit-2026-07-12.md`. Next quarantine smoke writers, then inspect operator-run and daemon-supervisor evidence binding.
This is the re-entry rite for `E:\Projects\EpiphanyAgent`: the waking chant for
the local machine-spirit before it touches the forge.

View file

@ -0,0 +1,25 @@
# Receipt Writer Provenance Audit — 2026-07-12
## Method
Inventory every production call to `write_*receipt`, then ask whether the executable is the named owner, a bounded ingest/projection boundary, a test-only fixture, or a caller able to assert the result it records.
## Classification
- `epiphany-daemon-supervisor`: owner-aligned for scheduler, lifecycle, and daemon-poke receipts. It performs or observes the lifecycle operation it records.
- `epiphany-eve-provider`: owner-aligned narrow provider receipt writer; verifies the pending intent targets its provider cluster.
- `epiphany-operator-run`: owner-aligned for operator-run receipts and coordinator receipts derived from the run it executes.
- smoke binaries and the `epiphany-verse-query smoke` arm: fixtures, not runtime evidence. They remain a quarantine risk if permitted to target canonical stores.
- `epiphany-work` Weksa lowering: a lowering projection receipt, explicitly non-publication authority; no substitution confirmed in this pass.
- `epiphany-operator-snapshot from-status`: **confirmed substitution and cut**. Arbitrary edge JSON under `/tools/invocations` could previously be converted into canonical daemon-tool intent and receipt documents. The snapshot adapter now writes the operator snapshot only; tool invocation fields return null and authority remains `runtime-spine-only`. The conversion helper is test-only.
## Negative proof
A forged operator-status artifact containing `intentId=forged-intent`, `receiptId=forged-receipt`, and `status=accepted` was imported. The operator snapshot was written, while canonical latest daemon-tool intent and receipt both remained absent.
## Remaining scrutiny
1. Quarantine smoke writers so they cannot target canonical stores.
2. Inspect `epiphany-operator-run` receipt construction against actual subprocess/runtime evidence rather than command arguments.
3. Inspect daemon-supervisor plan/rehearsal receipts separately from execution receipts so planning cannot masquerade as service mutation.
4. Distill or remove dead public receipt constructors once every named provider executable exists.

Binary file not shown.

View file

@ -70,7 +70,7 @@ data_flow:
- move historical proof to git, commits, smoke artifacts, or distilled evidence rather than plan prose
active_subgoals:
- Use `notes/conceptual-substitution-audit-2026-07-12.md` and its resolution ledger as the current authority-corrosion map. Every confirmed caller/provider dual writer in that audit is cut from caller-facing production paths. Artifact-acceptance and metrics commands now surface admitted repo requests, report pending named owners, reject all acceptance/accounting result fields, and write no receipts. Next perform a production call-site provenance audit of every response-receipt writer, then distill obsolete contaminated authority claims from this historical map.
- Use `notes/conceptual-substitution-audit-2026-07-12.md` plus `notes/receipt-writer-provenance-audit-2026-07-12.md` as the current authority-corrosion maps. The fresh call-site audit found and cut operator-snapshot canonical promotion: arbitrary edge status JSON can no longer become canonical daemon-tool intents/receipts. Snapshot output names `runtime-spine-only` authority; the old converter is test-only. Next quarantine smoke receipt writers from canonical stores, then audit operator-run and daemon-supervisor evidence provenance.
- `swarm-overview` is an Epiphany-local, renderer-neutral diagnostic projection over provider-owned typed state. It owns no lifecycle, discovery, composition, or mutation authority. Epiphany publishes clean provider-owned Eve surfaces; Odin may discover them; downstream lowerers and compositors remain outside Epiphany's concern.
- Idunn owns daemon survival and service lifecycle physiology. Codex/operator sessions may inspect, generate runbooks, and route explicit operator authority, but keeping daemons alive belongs to Idunn-owned service lifecycle receipts, scheduler policy, audits, and aftercare. Do not let Self, diagnostic projections, or ad hoc wrapper summaries become a second daemon-keeper. Global tool readbacks for Self `service-health`, `service-policy-directory`, and `swarm-online-runbook` state `lifecycleOwner=Idunn` and `hostedBody=Epiphany` without service mutation or private-state exposure.
- Use `notes/epiphany-cultmesh-dreaming-roadmap.md` as the design authority for distributed Epiphany dreaming. Public dreams are separately authored typed documents distributed through CultMesh/CultNet; private state remains local and cannot be shared by flipping a visibility flag. Foreign dreams are external thought weather until a reviewed local adoption receipt digests them into memory, planning, doctrine, or governance.