Carry a plan entry's contribution as an opaque payload in the provisioner client, so the client knows no provision's fields and route-proxy reads its routes with its own contract (issue 774, research 072 row 34)

This commit is contained in:
2026-10-31 09:45:07 +01:00
parent d959d37f8e
commit 92d6a5e9a0
2 changed files with 12 additions and 18 deletions
@@ -108,17 +108,10 @@ type PlannedProvision struct {
// CredentialTool is, for a software-issued offer, the provider's tool the vault asks for the value (issue 928);
// the vault acts on it and this client only reads it.
CredentialTool string `json:"credential-tool,omitempty"`
// Given is what this module contributes to the provision, composed, and ConsumerAt where its machine is on the
// private network (issue 774): a provider serving from the plans alone (route-proxy) reads them; the client keeps
// them, so the plan reads whole.
Given []PlannedGiven `json:"given,omitempty"`
ConsumerAt string `json:"consumer-at,omitempty"`
}
// PlannedGiven is one contribution of the module to a provision, composed: its local name among several, and its values.
type PlannedGiven struct {
Local string `json:"local,omitempty"`
Values map[string]any `json:"values"`
// Contributed is what this module gives the provider through the provision, composed, as one opaque payload
// (issue 774): the provider reads it with its own contract (route-proxy's for a route); the client keeps it unread,
// so the plan reads whole and no provision's fields are known here.
Contributed json.RawMessage `json:"contributed,omitempty"`
}
// issuedForHolder is whether the entry names a value its provider's software issued for this holder alone (issue
@@ -9,9 +9,9 @@ import (
// A plan provision carries everything the controller's PlanProvision writes (issue 954): what the consumer
// contributes, where the provider is and who the consumer is at its end (issue 788), the names the mesh calls it
// (issue 792), for a software-issued offer, the tool the vault asks (issue 928), and what the consumer contributes,
// composed, with where its machine is (issue 774: route-proxy serves its routes from them). The client still refuses a
// field nobody writes.
// (issue 792), for a software-issued offer, the tool the vault asks (issue 928), and what the consumer contributes as
// one opaque payload, carried unread (issue 774: route-proxy serves its routes from it, read with its own contract).
// The client still refuses a field nobody writes, but never looks inside the payload.
func TestAPlanProvisionWithEveryFieldTheControllerWritesIsRead(t *testing.T) {
p, err := json.Marshal(contributor(t, "shell:zsh:normal", "alias nox=mesh-cli"))
if err != nil {
@@ -19,8 +19,9 @@ func TestAPlanProvisionWithEveryFieldTheControllerWritesIsRead(t *testing.T) {
}
provision := `"provisions":[{"provision":"route","local":"web","provider":"novox","provider-module":"route-proxy",` +
`"credential-form":"pair","contributes":{"label":"git"},"at":"10.10.0.1","from":"novox","as":"gitea",` +
`"names":{"name-web":"git.example.org"},"given":[{"local":"web","values":{"name":"git.example.org","port":3000}}],` +
`"consumer-at":"10.10.0.2"},{"name":"gitea-read","provision":"gitea-read","provider":"novox",` +
`"names":{"name-web":"git.example.org"},` +
`"contributed":{"v":1,"at":"10.10.0.2","each":[{"local":"web","values":{"name":"git.example.org","anything":1}}]}},` +
`{"name":"gitea-read","provision":"gitea-read","provider":"novox",` +
`"provider-module":"gitea","credential-form":"issued","credential-tool":"gitea_agent_token",` +
`"path":"/var/lib/claude-code/gitea-read.secret"}],"items":`
value := fmt.Sprintf(`{"node":"g14","module":"mesh-cli","provisioning":%s}`,
@@ -31,8 +32,8 @@ func TestAPlanProvisionWithEveryFieldTheControllerWritesIsRead(t *testing.T) {
}
if len(got.Provisions) != 2 || got.Provisions[0].At != "10.10.0.1" || got.Provisions[0].From != "novox" ||
got.Provisions[0].As != "gitea" || got.Provisions[0].Names["name-web"] != "git.example.org" ||
got.Provisions[1].CredentialTool != "gitea_agent_token" || len(got.Provisions[0].Given) != 1 ||
got.Provisions[0].Given[0].Local != "web" || got.Provisions[0].ConsumerAt != "10.10.0.2" {
got.Provisions[1].CredentialTool != "gitea_agent_token" || string(got.Provisions[0].Contributed) !=
`{"v":1,"at":"10.10.0.2","each":[{"local":"web","values":{"name":"git.example.org","anything":1}}]}` {
t.Fatalf("the plan's provisions read as %+v", got.Provisions)
}
spoilt := strings.Replace(value, `"at":`, `"surprise":1,"at":`, 1)