An artifact's system is checked and then nothing uses it
Asked whether the host is built for more than one architecture. It is not, and the reason is worse than a missing feature. A bundle in a compiled language must name a system, must name one of alpine, android or arch, and is refused with a careful message if it gets that wrong. The field is then read by nothing: it does not reach the compiler, no machine is matched against it, and nothing chooses between two artifacts by it. The compile runs with no target named and produces a binary for whatever the build machine happens to be. The host is x86-64 because the build machine is, not because the declaration said so. Correct for this mesh by coincidence — four machines, all x86-64 Arch. A module declaring two systems would get two identical binaries, both published and both pinned, and the one sent to the machine it was not built for would fail at exec. android is the sharp end: not an x86-64 platform, and an artifact declared for it today would be an x86-64 binary wearing the label. A field that is checked and ignored is worse than one that does not exist, because the check is what persuades you it works. Also noted: the processor is a second dimension the manifest has no word for, so even implementing the present field would not answer the question that found this. And since the Go toolchain builds statically, one binary would run on all three systems anyway — so the pin is a policy rather than a necessity, which is a decision and not a fix.
This commit is contained in:
@@ -89,3 +89,9 @@ work on.
|
||||
two of them is a C library, not a kernel" — and a static Go binary has no C library. So one build would
|
||||
in fact run on all three. The pin is then a policy (a host refuses a machine it was not built for)
|
||||
rather than a necessity, which is a reasonable thing to keep and is worth knowing is a choice.
|
||||
|
||||
**And a sharper one, asked as a question and worth its own record.** The artifact's system is validated
|
||||
and then read by nothing: it does not reach the compiler, no machine is matched against it, and nothing
|
||||
chooses between two artifacts by it. The host built here is x86-64 because the build machine is, not
|
||||
because anything in the declaration said so — correct for this mesh by coincidence. That is
|
||||
[issue 159](../159-an-artifacts-system-is-checked-and-then-ignored/00-report.md).
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
status: located
|
||||
opened: 2026-09-30
|
||||
located-in:
|
||||
- mesh-controller internal/catalogue/build.go (System is validated and read by nothing else)
|
||||
- mesh-controller internal/builder (the compile invocation names no target)
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 159 — An artifact's system is checked, and then nothing uses it
|
||||
|
||||
## What was observed
|
||||
|
||||
Asked whether the host is built for more than one architecture, 2026-09-30, having just built it
|
||||
through the new Go toolchain.
|
||||
|
||||
[ADR 0142](../../02-DECISIONS/0142-the-mesh-delivers-its-own-components-as-binaries.md) says an
|
||||
artifact declares what it targets, and that one artifact per target is one build each. The manifest
|
||||
layer enforces the first half strictly: a bundle in a language that compiles to a binary **must** name
|
||||
a system, must name one of `alpine`, `android`, `arch`, and must not name one at all if its language is
|
||||
interpreted. A manifest that gets any of that wrong is refused with a reason.
|
||||
|
||||
**The field is then read by nothing.** Every use of it in the control plane is in the function that
|
||||
validates it. It does not reach the compiler, no machine is matched against it, and nothing chooses
|
||||
between two artifacts by it.
|
||||
|
||||
So the compile runs with no target named and produces a binary for whatever the build machine happens
|
||||
to be. The host, declared `system: arch` and built on this mesh's only build machine:
|
||||
|
||||
```
|
||||
mesh-host: ELF 64-bit LSB executable, x86-64, statically linked, stripped
|
||||
```
|
||||
|
||||
Correct for every machine in this mesh, which are all x86-64 Arch — and correct by coincidence rather
|
||||
than by anything the declaration did.
|
||||
|
||||
## Why it matters
|
||||
|
||||
**A module declaring two systems would get two identical binaries.** Both would be published, both
|
||||
pinned, both delivered, and the one sent to the machine it was not built for would fail at exec with a
|
||||
message about a format — which is the shape ADR 0005's link-time pin exists to prevent, arriving
|
||||
because the pin was never applied.
|
||||
|
||||
`android` in the list is the sharp end: it is not an x86-64 platform, and an artifact declared for it
|
||||
today would be an x86-64 binary wearing the label. Nothing would say so until a machine tried to run
|
||||
it.
|
||||
|
||||
**And the field reads as implemented.** It is required, validated against a closed list, and refused
|
||||
with a careful message — every signal a manifest author gets says the mesh is acting on it. A field
|
||||
that is checked and ignored is worse than one that does not exist, because the check is what persuades
|
||||
you it works.
|
||||
|
||||
## Two things this is not
|
||||
|
||||
- **Not the same axis as the distribution.** `alpine`, `android`, `arch` are what a machine reports
|
||||
itself to be, and the comment on the list says why: "the difference between two of them is a C
|
||||
library, not a kernel". The processor is a second dimension and the manifest has no word for it at
|
||||
all — so even a correct implementation of the current field would not answer the question that
|
||||
started this.
|
||||
- **Not urgent for this mesh.** Four machines, all x86-64 Arch, one build machine. Nothing is broken
|
||||
today and nothing will be until a machine differs — which is exactly how long a field like this stays
|
||||
invisible.
|
||||
|
||||
## Where to look
|
||||
|
||||
The compile invocation is assembled in `mesh-controller internal/builder`, and for Go it would need
|
||||
`GOOS`/`GOARCH` set from the artifact rather than inherited from the build machine. That needs the
|
||||
manifest to carry a processor as well as a system, or the systems list to mean both — which is a
|
||||
decision, not a fix, and belongs with whoever answers whether one static binary should serve several
|
||||
distributions at all.
|
||||
|
||||
**That last question is live.** The Go toolchain builds statically, so a single binary has no C library
|
||||
to differ about and would in fact run on Alpine and Arch alike. The per-system pin is then a policy — a
|
||||
host refuses a machine it was not built for — rather than a technical necessity, and worth knowing is a
|
||||
choice.
|
||||
|
||||
## How a fix is checked
|
||||
|
||||
An artifact declared for a system the build machine is not produces a binary for that system, shown by
|
||||
reading the file rather than by the build reporting success; and two artifacts declared for two systems
|
||||
do not have the same digest.
|
||||
Reference in New Issue
Block a user