Say that the seat mesh-provisioner composes route-proxy's plans, since the controller ended

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
2026-11-02 12:23:47 +01:00
parent 30cb63e29f
commit d2c5057fdf
7 changed files with 18 additions and 18 deletions
+4 -4
View File
@@ -7,8 +7,8 @@ The shipping form of the reference reverse proxy (novox/hq ADR 0007, novox/hq 08
**A route is a provision** (issue 774, research 072 row 34; the operator, 2026-10-31: "there is only 1 path, the other **A route is a provision** (issue 774, research 072 row 34; the operator, 2026-10-31: "there is only 1 path, the other
is simply deprecated/invalid"). A module that must be reachable declares `requires: ["route"]` and contributes the is simply deprecated/invalid"). A module that must be reachable declares `requires: ["route"]` and contributes the
name it wants and the port it listens on; this module provides `route`. The controller composes each consumer's plan, name it wants and the port it listens on; this module provides `route`. The seat `mesh-provisioner` composes each consumer's
and the seat `mesh-provisioner` keeps it in its state `plans`: the plan's entry for the route names this proxy as plan and keeps it in its state `plans`: the plan's entry for the route names this proxy as
its provider and carries what the consumer contributes, composed (its names joined to the node's domains, its its provider and carries what the consumer contributes, composed (its names joined to the node's domains, its
endpoint's port, its policy), and where the consumer's machine is on the private network, as one opaque payload endpoint's port, its policy), and where the consumer's machine is on the private network, as one opaque payload
(`contributed`) the seat never reads. The proxy follows the plans on the bus, reads each contribution with its own (`contributed`) the seat never reads. The proxy follows the plans on the bus, reads each contribution with its own
@@ -32,7 +32,7 @@ tree (a `replace` of `./contract` in `go.mod`), so the two never drift. It holds
`Other`, `Key`, `Split`); `Other`, `Key`, `Split`);
- **its tools' names and arguments** (`ToolRoutes`, `ToolRoute`, `ToolUnrouted`, `RoutesArgs`, `RouteArgs`). - **its tools' names and arguments** (`ToolRoutes`, `ToolRoute`, `ToolUnrouted`, `RoutesArgs`, `RouteArgs`).
The controller does not write the proxy's configuration. It composes the facts into the plans and the proxy turns them The seat mesh-provisioner does not write the proxy's configuration. It composes the facts into the plans and the proxy turns them
into whatever it runs. That boundary is why swapping this proxy for another costs nothing to the modules that publish into whatever it runs. That boundary is why swapping this proxy for another costs nothing to the modules that publish
through it. **There is no received file and no second source:** a route no plan names is not served, and a module through it. **There is no received file and no second source:** a route no plan names is not served, and a module
declaring `receives.route` is refused by the catalogue check (mesh-catalog `checks/credentialform`), but for the declaring `receives.route` is refused by the catalogue check (mesh-catalog `checks/credentialform`), but for the
@@ -113,7 +113,7 @@ traffic.
A small Go program beside the proxy (`cmd/route-provider`) runs the SDK's provider helper for `route`, with no credential, A small Go program beside the proxy (`cmd/route-provider`) runs the SDK's provider helper for `route`, with no credential,
and the offer says `"answered-by": "helper"`: a handed consumer (gitea's origins file) is filled by its machine's client and the offer says `"answered-by": "helper"`: a handed consumer (gitea's origins file) is filled by its machine's client
from this module's entry, which carries the public names the controller composed for it. The module is **not** marked from this module's entry, which carries the public names the seat mesh-provisioner composed for it. The module is **not** marked
moved: its own files, `acme.env` and the broker secret, are composed as before, and the proxy itself is unchanged. moved: its own files, `acme.env` and the broker secret, are composed as before, and the proxy itself is unchanged.
## What it says on the bus, and its tools (issue 774) ## What it says on the bus, and its tools (issue 774)
@@ -5,7 +5,7 @@ package main
// name from the entry in this module's bucket, the one its machine's client fills its files from. // name from the entry in this module's bucket, the one its machine's client fills its files from.
// //
// **It composes nothing.** A route's public name is the label its consumer chose joined to the node's public domain, // **It composes nothing.** A route's public name is the label its consumer chose joined to the node's public domain,
// which only the controller knows (the domain is placement), so the controller composes it and carries it in the // which only placement holds, so the seat mesh-provisioner composes it and carries it in the
// consumer's plan entry (`names`); the helper copies it into the entry's values unchanged. There is no credential for // consumer's plan entry (`names`); the helper copies it into the entry's values unchanged. There is no credential for
// a route and nothing to make. The proxy itself serves the same plans' entries (cmd/route-proxy plans.go), the one // a route and nothing to make. The proxy itself serves the same plans' entries (cmd/route-proxy plans.go), the one
// source of routes (issue 774, research 072 row 34). // source of routes (issue 774, research 072 row 34).
+2 -2
View File
@@ -6,7 +6,7 @@
// `plans`, names it as the route's provider. It is the mirror of a database grant: there the consumer // `plans`, names it as the route's provider. It is the mirror of a database grant: there the consumer
// supplies a name and receives credentials, here it supplies a target and receives a name. // supplies a name and receives credentials, here it supplies a target and receives a name.
// //
// **It is an example, not part of the controller.** The controller decides and never touches a // **It is an example, not part of the mesh's own parts.** The mesh decides and never touches a
// machine. A real deployment runs whatever proxy it likes — the contract is the plan's entry, not // machine. A real deployment runs whatever proxy it likes — the contract is the plan's entry, not
// this program. What lives here is that contract, written as something that runs so it can be read // this program. What lives here is that contract, written as something that runs so it can be read
// rather than described. // rather than described.
@@ -18,7 +18,7 @@
// than a closed one is to widen. // than a closed one is to widen.
// //
// What it is given, in each plan's entry for the route: every contribution the consumer makes, // What it is given, in each plan's entry for the route: every contribution the consumer makes,
// composed by the controller, and where the consumer's machine is on the private network (plans.go). // composed by the seat mesh-provisioner, and where the consumer's machine is on the private network (plans.go).
// Each contribution's values carry the name and port, and optionally: // Each contribution's values carry the name and port, and optionally:
// //
// path the path prefix this rule is scoped to; absent means every path // path the path prefix this rule is scoped to; absent means every path
+1 -1
View File
@@ -4,7 +4,7 @@ package main
// row 34, the operator on 2026-10-31: "there is only 1 path, the other is simply deprecated/invalid"). // row 34, the operator on 2026-10-31: "there is only 1 path, the other is simply deprecated/invalid").
// //
// **A route is a provision, in route-proxy's own contract.** A module that must be reachable requires `route`; the // **A route is a provision, in route-proxy's own contract.** A module that must be reachable requires `route`; the
// controller composes its plan on its node, and the plan's entry for the route names this proxy as its provider and // seat mesh-provisioner composes its plan on its node, and the plan's entry for the route names this proxy as its provider and
// carries what the module contributes, composed (its names joined to the node's domains, the machine port its // carries what the module contributes, composed (its names joined to the node's domains, the machine port its
// placement assigned its endpoint, never the software's own), and where the module's machine is on the private // placement assigned its endpoint, never the software's own), and where the module's machine is on the private
// network, as one opaque payload the seat never reads (mesh-sdk catalogue.PlanProvision.Contributed). The proxy decodes each contribution with its contract (contract.DecodeRequest) // network, as one opaque payload the seat never reads (mesh-sdk catalogue.PlanProvision.Contributed). The proxy decodes each contribution with its contract (contract.DecodeRequest)
+2 -2
View File
@@ -9,8 +9,8 @@
// package; nothing imports the repository. Standard library only, so a consumer takes nothing else with it. // package; nothing imports the repository. Standard library only, so a consumer takes nothing else with it.
// //
// **How a route travels.** A module that must be reachable requires `route` and says, in its manifest's // **How a route travels.** A module that must be reachable requires `route` and says, in its manifest's
// `contributes.route`, one Request, or several by local name; Schema is that object's JSON schema. The controller // `contributes.route`, one Request, or several by local name; Schema is that object's JSON schema. The seat
// composes each (its label joined to the node's domains into `name` and `internal-name`, its endpoint's port into // mesh-provisioner composes each (its label joined to the node's domains into `name` and `internal-name`, its endpoint's port into
// `port`) and the seat mesh-provisioner carries the result in the consumer's plan entry as an opaque payload // `port`) and the seat mesh-provisioner carries the result in the consumer's plan entry as an opaque payload
// (mesh-sdk catalogue.PlanProvision.Contributed, in the generic catalogue.ContributedForm). Neither the seat nor its // (mesh-sdk catalogue.PlanProvision.Contributed, in the generic catalogue.ContributedForm). Neither the seat nor its
// client knows a field of a route: route-proxy decodes each contribution with DecodeRequest, and refuses, saying why // client knows a field of a route: route-proxy decodes each contribution with DecodeRequest, and refuses, saying why
+5 -5
View File
@@ -9,17 +9,17 @@ import (
"strings" "strings"
) )
// Request is one route a consumer asks for, as its manifest's `contributes.route` says it and the controller composes // Request is one route a consumer asks for, as its manifest's `contributes.route` says it and the seat mesh-provisioner
// it: the object Schema describes. Every field is optional to the decoder; Validate says which a route needs. // composes it: the object Schema describes. Every field is optional to the decoder; Validate says which a route needs.
type Request struct { type Request struct {
// Name is the public name, served to anyone and certified by the public ACME directory; InternalName the name on // Name is the public name, served to anyone and certified by the public ACME directory; InternalName the name on
// the private network, served inside it alone and certified by the mesh's own authority. The controller composes // the private network, served inside it alone and certified by the mesh's own authority. The seat mesh-provisioner
// both from Label and the node's domains, as far as the endpoint reaches (novox/hq ADR 0138); a manifest writes a // composes both from Label and the node's domains, as far as the endpoint reaches (novox/hq ADR 0138); a manifest writes a
// label, never a domain. // label, never a domain.
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
InternalName string `json:"internal-name,omitempty"` InternalName string `json:"internal-name,omitempty"`
Label string `json:"label,omitempty"` Label string `json:"label,omitempty"`
// Endpoint names the manifest's endpoint the route serves; the controller fills Port from it. // Endpoint names the manifest's endpoint the route serves; the seat mesh-provisioner fills Port from it.
Endpoint string `json:"endpoint,omitempty"` Endpoint string `json:"endpoint,omitempty"`
Port int `json:"port,omitempty"` Port int `json:"port,omitempty"`
// Path is the path prefix the rule is scoped to, every path when empty; Priority which rule wins where two match, // Path is the path prefix the rule is scoped to, every path when empty; Priority which rule wins where two match,
@@ -2,7 +2,7 @@
"$schema": "https://json-schema.org/draft/2020-12/schema", "$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://git.novox.be/novox/mesh-networking/modules/route-proxy/contract/route.schema.json", "$id": "https://git.novox.be/novox/mesh-networking/modules/route-proxy/contract/route.schema.json",
"title": "route", "title": "route",
"description": "One route a consumer asks route-proxy for, as a manifest's contributes.route says it (one, or several by local name) and the controller composes it. Version 1 of route-proxy's contract.", "description": "One route a consumer asks route-proxy for, as a manifest's contributes.route says it (one, or several by local name) and the seat mesh-provisioner composes it. Version 1 of route-proxy's contract.",
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"anyOf": [ "anyOf": [
@@ -13,8 +13,8 @@
"properties": { "properties": {
"name": {"type": "string", "description": "the public name, served to anyone and certified by the public ACME directory; composed from label"}, "name": {"type": "string", "description": "the public name, served to anyone and certified by the public ACME directory; composed from label"},
"internal-name": {"type": "string", "description": "the name on the private network, served inside it alone and certified by the mesh's own authority; composed from label"}, "internal-name": {"type": "string", "description": "the name on the private network, served inside it alone and certified by the mesh's own authority; composed from label"},
"label": {"type": "string", "description": "the subdomain the module chooses; joined to the node's domains by the controller"}, "label": {"type": "string", "description": "the subdomain the module chooses; joined to the node's domains by the seat mesh-provisioner"},
"endpoint": {"type": "string", "description": "the manifest's endpoint the route serves; the controller fills port from it"}, "endpoint": {"type": "string", "description": "the manifest's endpoint the route serves; the seat mesh-provisioner fills port from it"},
"port": {"type": "integer", "minimum": 1, "maximum": 65535}, "port": {"type": "integer", "minimum": 1, "maximum": 65535},
"path": {"type": "string", "description": "the path prefix the rule is scoped to; every path when absent"}, "path": {"type": "string", "description": "the path prefix the rule is scoped to; every path when absent"},
"priority": {"type": "integer", "description": "which rule wins where two match, higher first"}, "priority": {"type": "integer", "description": "which rule wins where two match, higher first"},