From 43aed779eb89f1ee897099b1f3bf214ccca55c06 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Mon, 13 Jul 2026 05:03:30 +0100 Subject: [PATCH] Separate tool request and execution ownership --- ...epiphany-repo-tool-request-family-smoke.rs | 4 +++- epiphany-core/src/bin/epiphany-work.rs | 5 +++-- .../closure_contracts/external_governance.rs | 12 +++++++++--- .../external_governance_tests.rs | 5 ++++- ...onceptual-substitution-audit-2026-07-12.md | 13 +++++++++++++ notes/fresh-workspace-handoff.md | 8 ++++++++ state/ledgers.msgpack | Bin 478819 -> 479133 bytes state/map.yaml | 2 +- 8 files changed, 41 insertions(+), 8 deletions(-) diff --git a/epiphany-core/src/bin/epiphany-repo-tool-request-family-smoke.rs b/epiphany-core/src/bin/epiphany-repo-tool-request-family-smoke.rs index 53c9b51a..1bf364ad 100644 --- a/epiphany-core/src/bin/epiphany-repo-tool-request-family-smoke.rs +++ b/epiphany-core/src/bin/epiphany-repo-tool-request-family-smoke.rs @@ -196,6 +196,8 @@ fn run_smoke(args: Args) -> Result { )?; require_text(&request_text, "safe_action_family = \"repo.tool_request\"")?; require_text(&request_text, "[request]")?; + require_text(&request_text, "routing_owner = \"Self\"")?; + require_text(&request_text, "pressure_source = \"Persona\"")?; require_text( &request_text, "target_directory = \"gamecult-local/daemon-tool-directory\"", @@ -215,7 +217,7 @@ fn run_smoke(args: Args) -> Result { "receipt_contract = \"epiphany.cultmesh.daemon_tool_invocation_receipt.v0\"", )?; require_text(&request_text, "host_daemon_owns_execution = true")?; - require_text(&request_text, "requester_owns_request = false")?; + require_text(&request_text, "requester_owns_execution = false")?; require_text(&request_text, "requires_host_liveness_ready = true")?; require_text(&request_text, "requires_cultmesh_receipts = true")?; require_text(&request_text, "[odin]")?; diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index 5817f7de..d67f945d 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -2721,7 +2721,8 @@ fn derive_repo_tool_request_plan( "[request]".to_string(), format!("id = {}", toml_basic_string(&request_id)), format!("requester_body = {}", toml_basic_string(&requester_body)), - "requesting_agent = \"repo Persona/Self\"".to_string(), + "routing_owner = \"Self\"".to_string(), + "pressure_source = \"Persona\"".to_string(), "target_directory = \"gamecult-local/daemon-tool-directory\"".to_string(), "target_capability = \"daemon-tool-capability:selected-by-review\"".to_string(), "operation = \"submitTypedToolIntent\"".to_string(), @@ -2736,7 +2737,7 @@ fn derive_repo_tool_request_plan( toml_basic_string(receipt_contract) ), "host_daemon_owns_execution = true".to_string(), - "requester_owns_request = false".to_string(), + "requester_owns_execution = false".to_string(), "requires_host_liveness_ready = true".to_string(), "requires_cultmesh_receipts = true".to_string(), String::new(), 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 d69d599a..bec88f39 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 @@ -20,7 +20,10 @@ impl RepoToolRequest { } pub(super) fn has_request_contract(&self) -> bool { - self.request.target_directory == "gamecult-local/daemon-tool-directory" + !self.request.requester_body.is_empty() + && self.request.routing_owner == "Self" + && self.request.pressure_source == "Persona" + && self.request.target_directory == "gamecult-local/daemon-tool-directory" && self.request.target_capability == "daemon-tool-capability:selected-by-review" && self.request.operation == "submitTypedToolIntent" } @@ -30,7 +33,7 @@ impl RepoToolRequest { && self.cultmesh.receipt_contract == "epiphany.cultmesh.daemon_tool_invocation_receipt.v0" && self.cultmesh.host_daemon_owns_execution - && !self.cultmesh.requester_owns_request + && !self.cultmesh.requester_owns_execution && self.cultmesh.requires_host_liveness_ready && self.cultmesh.requires_cultmesh_receipts } @@ -55,6 +58,9 @@ impl RepoToolRequest { #[derive(Debug, Deserialize)] pub(super) struct RepoToolRequestBody { + requester_body: String, + routing_owner: String, + pressure_source: String, target_directory: String, target_capability: String, operation: String, @@ -65,7 +71,7 @@ pub(super) struct RepoToolRequestCultMesh { intent_contract: String, receipt_contract: String, host_daemon_owns_execution: bool, - requester_owns_request: bool, + requester_owns_execution: bool, requires_host_liveness_ready: bool, requires_cultmesh_receipts: bool, } 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 61584534..32b11945 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 @@ -47,6 +47,9 @@ safe_action_family = "repo.tool_request" summary = "summary" private_state_exposed = false [request] +requester_body = "repo:test" +routing_owner = "Self" +pressure_source = "Persona" target_directory = "gamecult-local/daemon-tool-directory" target_capability = "daemon-tool-capability:selected-by-review" operation = "submitTypedToolIntent" @@ -54,7 +57,7 @@ operation = "submitTypedToolIntent" intent_contract = "epiphany.cultmesh.daemon_tool_invocation_intent.v0" receipt_contract = "epiphany.cultmesh.daemon_tool_invocation_receipt.v0" host_daemon_owns_execution = true -requester_owns_request = false +requester_owns_execution = false requires_host_liveness_ready = true requires_cultmesh_receipts = true [odin] diff --git a/notes/conceptual-substitution-audit-2026-07-12.md b/notes/conceptual-substitution-audit-2026-07-12.md index 9e092892..314408ff 100644 --- a/notes/conceptual-substitution-audit-2026-07-12.md +++ b/notes/conceptual-substitution-audit-2026-07-12.md @@ -1389,3 +1389,16 @@ ledger rows name the actual source Persona id as owner and retain the requested Imagination consensus route. Bifrost owns collaboration-consensus accounting; the Persona-to-Imagination chain is what Bifrost observes, not who Bifrost is. Production source now contains no arrow-shaped owner value. + +## Request ownership is not execution ownership + +The repo tool request encoded `requesting_agent="repo Persona/Self"`, while its +typed closure ignored requester identity entirely and declared +`requester_owns_request=false`. This merged Persona pressure, Self routing, and +host execution, then denied ownership of the request because the requester did +not own execution. + +The request now carries a concrete requester body, `routing_owner=Self`, and +`pressure_source=Persona`. CultMesh separately states that the target host +daemon owns execution and the requester does not. The typed closure validates +all of these fields. Persona supplies pressure; Self routes; the provider acts. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 798498b0..1c37242f 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -509,3 +509,11 @@ publishes the Persona-to-Imagination handoff separately; feedback ledger rows use their source Persona id; Bifrost owns consensus accounting. Continue the conceptual-substitution scan beyond owner strings: look for status, route, receipt, or cache fields that borrow consequence authority from another organ. + +The first non-owner substitution is cut in `repo.tool_request`. The old +`requesting_agent="repo Persona/Self"` and `requester_owns_request=false` shape +is replaced by requester body identity, Self routing, Persona pressure +provenance, target-host execution ownership, and requester execution denial. +The typed closure now validates the identity and authority split. Continue +looking for fields where observation, request, admission, and effect ownership +are collapsed under innocent-sounding status or cache names. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 1b0c475a88ef947d6eeaff2d541aa2bcd86408ca..3254713585fb2a506424b389b5da248f6ab6216a 100644 GIT binary patch delta 322 zcmYk0u}Z{15Qa^n38>gBcQ9ZZgIui6-bN5nE4wurFTrJJZ+CO?Y_71dvkPgID|`XP z!rI1CAHo-LA}SU?GyKfQe4lsy`+5Iy-CItFgY@)mAv(Bv-t@+vH@j~9o5uGz-3&O3 zoFz{9()iK)e*3Wztpz*7?e=vZ^k%C^s0kdA1cT!Wt+Sx028&u4;qbRb180;^V>m{6 z4u&dMs!pLy{OmTK7`?l KFx{yZ)+S%eCvy(~ delta 60 zcmbO`U-t1F*$tA6Tn1Jq22sZt*nJ%~D>D`{GS)RuWon