From bc373797c7ec4a4abfc243f8987199263baef69d Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 21 Sep 2026 22:16:15 +0200 Subject: [PATCH] Issue 076 opened: a served fact made at first start cannot be served; ADR 0097's refusal of an undeclared base is live --- ...-vendor-image-is-a-declared-build-input.md | 9 ++-- 03-DESIGN/01-to-be/18-building-a-module.md | 4 +- .../01-diagnosis.md | 3 ++ .../00-report.md | 42 +++++++++++++++++++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 04-ISSUES/076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md diff --git a/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md b/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md index 7b0131c..2237aea 100644 --- a/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md +++ b/02-DECISIONS/0097-a-vendor-image-is-a-declared-build-input.md @@ -36,10 +36,11 @@ image the manifest did not declare is refused before the build, naming the image its own stages, declared arguments and `scratch` are not fetches. An unpinned vendor image is refused: a tag is what somebody else can move. -A recipe whose `FROM` names an undeclared base is **said, not yet refused**: the mesh's own images -— the control plane's, the builder's, the tool runtime's — start from a public base and declare -none, and refusing those refuses genesis. They declare their bases next; until then every build -names the undeclared base and the remedy. +A recipe whose `FROM` names an undeclared base was at first said, not refused: the mesh's own +images — the control plane's, the tool runtime's, the route proxy's — started from a public base +and declared none, and refusing those refuses genesis. *Amended the same day:* those three declare +their bases now, and an undeclared `FROM` is refused like an undeclared copy. The builder's own +image and the examples are built by `make`, not by the mesh, and take arguments with defaults. The package half of the issue is not decided here: the mesh's package registry already proxies the public one, and the failure the report saw has to be run again to be placed. diff --git a/03-DESIGN/01-to-be/18-building-a-module.md b/03-DESIGN/01-to-be/18-building-a-module.md index 752e14c..0076a36 100644 --- a/03-DESIGN/01-to-be/18-building-a-module.md +++ b/03-DESIGN/01-to-be/18-building-a-module.md @@ -221,8 +221,8 @@ and nothing uploaded on a second copy. entry is a module's artifact or an image published elsewhere, pinned by digest, read from one build argument; the image is copied into the mesh's registry before the build and the recipe is handed the copy. A recipe whose `COPY --from` names a registry image the manifest did not declare -is refused before the build, naming it and the remedy; an undeclared `FROM` is said, not yet -refused, because the mesh's own images start from a public base and declare none. *How it is +is refused before the build, naming it and the remedy, and so is an undeclared `FROM`: the mesh's +own images declare the bases they start from. *How it is checked:* builder tests on a declared and an unpinned vendor image, and a recipe test on what counts as a copy and what as a base. diff --git a/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md b/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md index 8621a08..7d1437f 100644 --- a/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md +++ b/04-ISSUES/074-a-mesh-test-wears-a-catalogue-modules-name/01-diagnosis.md @@ -27,3 +27,6 @@ sidecar beds proved a sidecar alone, which the module beds prove whole; the mini grant beds proved a grant with a second store beside the foundation's, which the grant bed and the vault bed prove against the catalogue. Retired, with their scenarios. Two remain declared: route-forwarding, which needs the certificate authority beside the proxy, and the large mesh test. + +*Route-forwarding's conversion is blocked:* the catalogue's authority cannot be raised as written +([issue 076](../076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md)). diff --git a/04-ISSUES/076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md b/04-ISSUES/076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md new file mode 100644 index 0000000..4494234 --- /dev/null +++ b/04-ISSUES/076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md @@ -0,0 +1,42 @@ +--- +status: located +opened: 2026-09-21 +located-in: [mesh-catalog modules/step-ca, mesh-controller internal/catalogue (serves)] +fixed-by: +amended-design: +--- + +# A served fact made at first start cannot be served, so the catalogue's authority cannot start + +## Symptom, as observed + +The catalogue's certificate authority module declares its root certificate, its root key and +that key's password as its own secrets, and writes each into a file the container is told to +initialise from. The mesh mints an own secret as random bytes. Random bytes are not a +certificate: as written, the authority cannot initialise, and no bed has ever raised it — the +whole-mesh bed that names it has not run since it was converted. Found while converting the +route-forwarding bed to the catalogue's proxy, which requires the authority beside it. + +The authority can make its own root at first start — the certificate bed raises it that way and +it issues within a second. What it cannot do then is tell the mesh what that root is: a +consumer of `acme-ca` is given `${bound:acme-ca:root}` from the provider's `serves`, which is +written in the manifest before anything runs. + +## Why it matters beyond this instance + +- **Two kinds of secret the vocabulary does not distinguish.** A value the mesh may invent (a + password) and a value only the module can produce (a key pair, a certificate) are both + "own secrets", and the mesh invents both. +- **A served fact that exists only after first start** has no way into a binding. Anything a + module generates and its consumers must trust — a root, a public key, a fingerprint — is in + the same position. +- Every consumer of `acme-ca`, which today is the route proxy, is blocked with it. + +## What would close it + +Either a module may say a secret is *made by the module* — the mesh reserves the name, the +module writes the value once, the mesh takes custody of it and delivers it where it is bound — +or a served fact may be *contributed at run time* by the provider's runtime rather than written +in its manifest. The first is the smaller change and covers the root certificate; the second is +what a fingerprint or a public key wants. Decided, then the authority raised in the lab beside +the proxy, which is the route-forwarding bed's conversion.