The routing record is 0066, not 0056
0056 is 'the authority is the control plane, not a database'. A citation pointing at the wrong decision is worse than none: it reads as corroboration. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
@@ -66,7 +66,7 @@ func nodeCommand(ctx context.Context, args []string) error {
|
||||
return nil
|
||||
|
||||
case "public-domain":
|
||||
// The domain this node composes its routed names under (novox/hq ADR 0056).
|
||||
// The domain this node composes its routed names under (novox/hq ADR 0066).
|
||||
//
|
||||
// **The form with no argument reports; clearing is asked for by name.** It used to clear —
|
||||
// so `node public-domain anchor`, which reads like a question and is what anybody types to
|
||||
@@ -88,7 +88,7 @@ const publicDomainUsage = "node public-domain <name> — what it is now; " +
|
||||
//
|
||||
// Three forms, and the destructive one is the only one that has to be asked for. Clearing is a
|
||||
// real thing to want — a machine that stops facing the outside composes no names, and
|
||||
// lab-versus-production is this one setting (novox/hq ADR 0056) — so it keeps a way to say it.
|
||||
// lab-versus-production is this one setting (novox/hq ADR 0066) — so it keeps a way to say it.
|
||||
// What it does not keep is being the thing that happens when nothing was said at all.
|
||||
func publicDomain(ctx context.Context, inv *inventory.Inventory, args []string) error {
|
||||
set := flag.NewFlagSet("node public-domain", flag.ContinueOnError)
|
||||
@@ -335,7 +335,7 @@ func showNode(ctx context.Context, inv *inventory.Inventory, name string) error
|
||||
fmt.Printf("%s\n", node.Name)
|
||||
fmt.Printf(" last heard from %s\n", heardFrom(node))
|
||||
|
||||
// The domain its routed names are composed under, when it has one (novox/hq ADR 0056). Shown
|
||||
// The domain its routed names are composed under, when it has one (novox/hq ADR 0066). Shown
|
||||
// only when set: a machine that serves nothing to the outside has no domain, and saying so of
|
||||
// every internal node would be noise.
|
||||
domain, err := inv.PublicDomainOf(ctx, name)
|
||||
|
||||
@@ -69,7 +69,7 @@ func planFor(ctx context.Context, open *stores, nodeName string) (catalogue.Reso
|
||||
return catalogue.Resolution{}, nil, err
|
||||
}
|
||||
|
||||
// The domain this node composes its routed names under (novox/hq ADR 0056). A route
|
||||
// The domain this node composes its routed names under (novox/hq ADR 0066). A route
|
||||
// contribution carries only a label; the resolver joins <label>.<public-domain> for this node,
|
||||
// so the fact travels on the node it belongs to rather than being looked up where the name is
|
||||
// composed.
|
||||
@@ -435,7 +435,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// And every routed name → the node that serves it (novox/hq ADR 0056). Alongside the
|
||||
// And every routed name → the node that serves it (novox/hq ADR 0066). Alongside the
|
||||
// `<node>.internal` names above, so a container — or an internal ACME validator — resolves a
|
||||
// routed name to the proxy that serves it, mesh-wide. The mesh publishes the names it was told
|
||||
// to serve and knows nothing about what they mean.
|
||||
@@ -453,7 +453,7 @@ func declarationWith(ctx context.Context, open *stores, node string,
|
||||
}
|
||||
|
||||
// routeNamesInTheMesh is every routed name and the address of the node that serves it (novox/hq
|
||||
// ADR 0056).
|
||||
// ADR 0066).
|
||||
//
|
||||
// **Mesh-wide, so any container resolves any routed name to its proxy** — including an internal
|
||||
// ACME validator, which cannot complete a challenge for a name it cannot reach. A routed name is
|
||||
|
||||
@@ -313,7 +313,7 @@ type readyNode struct {
|
||||
// composeEach works out what each named machine should be, and never lets one machine's answer
|
||||
// decide another's.
|
||||
//
|
||||
// **A machine whose set cannot be worked out is that machine's problem** (novox/hq ADR 0056). A
|
||||
// **A machine whose set cannot be worked out is that machine's problem** (novox/hq ADR 0066). A
|
||||
// whole-mesh push used to refuse outright when any one node failed to resolve, so a single
|
||||
// unanswerable requirement on a single machine — one module requiring a provision nobody had
|
||||
// assigned a provider for — left every other machine in the mesh unconverged, including machines
|
||||
|
||||
@@ -211,7 +211,7 @@ func run() error {
|
||||
root = read
|
||||
// An empty bundle means the issuer's root is already in the system trust store — a public
|
||||
// authority whose root ships with the OS, pointed at by a provider that serves an empty
|
||||
// root (novox/hq ADR 0056). The mesh always writes the bundle file, so it exists and holds
|
||||
// root (novox/hq ADR 0066). The mesh always writes the bundle file, so it exists and holds
|
||||
// nothing; that is the signal to fall back to the system roots, the same as if nothing had
|
||||
// named a bundle at all. A file that holds bytes but no certificate is still a
|
||||
// misconfiguration and is refused, because there the operator meant to trust something.
|
||||
@@ -257,7 +257,7 @@ func run() error {
|
||||
// forThisAuthority is where one ACME authority's account and certificates are kept.
|
||||
//
|
||||
// **A cached ACME account belongs to the authority that issued it, and nothing in the cache says
|
||||
// so** (novox/hq ADR 0056). autocert keeps its account key at one fixed name — `acme_account+key` —
|
||||
// so** (novox/hq ADR 0066). autocert keeps its account key at one fixed name — `acme_account+key` —
|
||||
// in whatever directory it is given, and reuses it for ever. That is right while the authority stays
|
||||
// the same and silently wrong the moment it does not: an internal CA that is re-initialised is a new
|
||||
// authority with a new root, it has never heard of the account in the cache, and every attempt to
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A provider and its consumer on ONE machine, which is what ADR 0056's anchor is.
|
||||
// A provider and its consumer on ONE machine, which is what ADR 0066's anchor is.
|
||||
//
|
||||
// **Every fault in this file is the same shape: the same-node path diverging from the cross-node
|
||||
// one.** A provider on another machine is walked by the control plane — its served facts are
|
||||
|
||||
@@ -142,7 +142,7 @@ func (r Resolution) Declaration(with Rendering) ([]map[string]any, error) {
|
||||
}
|
||||
|
||||
// A workload on THIS machine contributes the port it declared, and the machine may have
|
||||
// published it somewhere else (novox/hq ADR 0056). The mirror of the redirect below: 038 fixed
|
||||
// published it somewhere else (novox/hq ADR 0066). The mirror of the redirect below: 038 fixed
|
||||
// what a consumer is TOLD about a provider, and this is what a workload TELLS the provider about
|
||||
// itself — gitea declaring 3000, published as 20000:3000, and the co-located proxy dialling 3000,
|
||||
// where nothing listens, for every request.
|
||||
@@ -162,7 +162,7 @@ func (r Resolution) Declaration(with Rendering) ([]map[string]any, error) {
|
||||
}
|
||||
|
||||
// A provider answered on this same machine never passed through the walk that works out what a
|
||||
// provider on ANOTHER machine serves (novox/hq 04-ISSUES/038, ADR 0056). That walk does two
|
||||
// provider on ANOTHER machine serves (novox/hq 04-ISSUES/038, ADR 0066). That walk does two
|
||||
// things — it derives the served facts with the provider node's port assignments, and it settles
|
||||
// them with that node's settings layers — and the same-node paths (resolve.go's servedHere, and
|
||||
// here() below) did neither, because both run while resolving, before either is known.
|
||||
@@ -449,7 +449,7 @@ func (r Resolution) Declaration(with Rendering) ([]map[string]any, error) {
|
||||
// And what the module could not have written: the machine it turned out to be
|
||||
// assigned to. Beside the bound values because it is the same kind of fact — the
|
||||
// mesh's own, held in the clear — and because a module that must name itself to
|
||||
// something else has no binding to learn it from (novox/hq ADR 0056).
|
||||
// something else has no binding to learn it from (novox/hq ADR 0066).
|
||||
if err := machineInto(copied, thisMachine, m.Module); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -795,7 +795,7 @@ func here(r Resolution, requirement string, with Rendering) (*Needed, error) {
|
||||
// theRestOfTheMesh). A provider on the consumer's own machine never passes through that walk, so
|
||||
// every step of it has to be repeated here — and each step that was not repeated was a promise the
|
||||
// co-located arrangement quietly broke: first the port (novox/hq 04-ISSUES/038), then the settled
|
||||
// values (ADR 0056, an internal CA's root arriving empty).
|
||||
// values (ADR 0066, an internal CA's root arriving empty).
|
||||
//
|
||||
// Here rather than in the resolver, because here is the first moment both halves exist: resolving
|
||||
// runs before a machine's ports are assigned and knows nothing of settings.
|
||||
@@ -975,7 +975,7 @@ func asPort(v any) (int, bool) {
|
||||
}
|
||||
|
||||
// atMachinePort redirects a `port` written by a module on this machine to where this machine
|
||||
// actually published it (novox/hq 04-ISSUES/038, ADR 0056).
|
||||
// actually published it (novox/hq 04-ISSUES/038, ADR 0066).
|
||||
//
|
||||
// **A module writes the port its software uses; only the mesh knows where the machine put it.** A
|
||||
// bare `ports` mapping is assigned a host port when the declaration is composed, which is after
|
||||
|
||||
@@ -15,12 +15,12 @@ import (
|
||||
// module is assigned, long after the manifest was written, and until now nothing carried it into a
|
||||
// file.
|
||||
//
|
||||
// The case that found this is a certificate authority inside the mesh (novox/hq ADR 0056). A proxy
|
||||
// The case that found this is a certificate authority inside the mesh (novox/hq ADR 0066). A proxy
|
||||
// reaches it at the address the mesh handed over, `<machine>.internal` — so the authority's own
|
||||
// certificate has to be issued for that name, or the first thing that happens is the proxy refusing
|
||||
// to talk to it. The authority is the one thing that cannot be told its name by a binding: it
|
||||
// provides, it does not require. Written as a literal it would be a manifest carrying one
|
||||
// deployment's machine name, which is the shape [ADR 0056] exists to remove.
|
||||
// deployment's machine name, which is the shape [ADR 0066] exists to remove.
|
||||
//
|
||||
// Two facts, both the mesh's own vocabulary — the same `node` and `at` a contribution already
|
||||
// carries. Nothing about what a machine is *for*: that would be the mesh learning what a module
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// novox/hq ADR 0056 — a module that must name ITSELF to something else.
|
||||
// novox/hq ADR 0066 — a module that must name ITSELF to something else.
|
||||
//
|
||||
// The authority inside the mesh is the case. A proxy reaches it at the address the mesh handed
|
||||
// over, so its certificate has to be issued for that name — and it has no binding to learn the name
|
||||
|
||||
@@ -25,7 +25,7 @@ type Node struct {
|
||||
// tell whether it can reach the node answering its requirements at all.
|
||||
At string
|
||||
// PublicDomain is the domain this node composes its routed names under, empty if it has none
|
||||
// (novox/hq ADR 0056). A route contribution carries only a label — the subdomain — and the mesh
|
||||
// (novox/hq ADR 0066). A route contribution carries only a label — the subdomain — and the mesh
|
||||
// joins <label>.<public-domain> to make the name it grants, interpreting neither half.
|
||||
PublicDomain string
|
||||
}
|
||||
@@ -107,7 +107,7 @@ type Resolution struct {
|
||||
// where it is — the answer being local does not make the port guessable.
|
||||
At string
|
||||
// PublicDomain is the domain this node composes its routed names under, empty if it has none
|
||||
// (novox/hq ADR 0056). Carried from the node so that composing <label>.<public-domain> for a
|
||||
// (novox/hq ADR 0066). Carried from the node so that composing <label>.<public-domain> for a
|
||||
// route contribution needs no store lookup here — the join is a fact about this one machine.
|
||||
PublicDomain string
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// novox/hq ADR 0056 — public routing is name-agnostic.
|
||||
// novox/hq ADR 0066 — public routing is name-agnostic.
|
||||
//
|
||||
// A route contribution carries a label (the subdomain the operator chose); the node carries its
|
||||
// public domain; the mesh composes <label>.<public-domain> and interprets neither half. The
|
||||
@@ -133,7 +133,7 @@ func TestALabelWithNoPublicDomainComposesNothing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestARoutedNameResolvesToTheServingNode(t *testing.T) {
|
||||
// novox/hq ADR 0056 propagate: a granted route name is published into internal resolution,
|
||||
// novox/hq ADR 0066 propagate: a granted route name is published into internal resolution,
|
||||
// mapped to the node that serves it, alongside the `<node>.internal` names — so every
|
||||
// container, and an in-mesh ACME validator, resolves a routed name to the proxy that serves it.
|
||||
// The names map is what withMeshNames writes into every container as `--add-host`; a route name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- The public domain a node's routed names are composed under.
|
||||
--
|
||||
-- novox/hq ADR 0056. A public route used to carry its whole hostname in the module manifest, so
|
||||
-- novox/hq ADR 0066. A public route used to carry its whole hostname in the module manifest, so
|
||||
-- running the same catalogue against a different domain — a lab standing in for production, a
|
||||
-- second operator's mesh — meant overriding that literal on every routed module. That made the
|
||||
-- mesh hold a map of names to services: the one thing it must not, because the subdomain is the
|
||||
|
||||
@@ -352,7 +352,7 @@ func (i *Inventory) SealingKeyOf(ctx context.Context, name string) (string, erro
|
||||
|
||||
// SetPublicDomain records the domain a node's routed names are composed under.
|
||||
//
|
||||
// A node-level fact (novox/hq ADR 0056), kept beside the node's other node-level configuration
|
||||
// A node-level fact (novox/hq ADR 0066), kept beside the node's other node-level configuration
|
||||
// rather than in a module's settings: the subdomain is a module's to choose and the domain is the
|
||||
// node's, and the mesh joins the two without interpreting either. An empty domain clears it — a
|
||||
// node that stops facing the outside composes no names — which is why this writes null rather than
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// novox/hq ADR 0056 — a node's public domain is a node-level fact, held here beside its other
|
||||
// novox/hq ADR 0066 — a node's public domain is a node-level fact, held here beside its other
|
||||
// node-level configuration rather than in a module's settings. These check it round-trips, that a
|
||||
// node with none reports empty rather than failing, and that clearing it works — the setting the
|
||||
// ADR names as the whole of moving a catalogue between a lab and production.
|
||||
|
||||
Reference in New Issue
Block a user