--- status: accepted date: 2026-08-26 deciders: jochen reconstructed: false extends: 0037-the-host-applies-it-does-not-decide.md --- # 41. The host depends on nothing that must be installed first ## Context [ADR 0030](0030-the-repository-structure.md) calls tier 0 *"the one binary installed by hand"*, and [research 006](../01-RESEARCH/006-mesh-from-scratch/00-overview.md) states the property the whole tier rests on: *"a binary whose whole argument is that it has no dependencies"*. Building it forced the question that phrase had been carrying unexamined. Everything else in the mesh is TypeScript, and `how-we-build` §8 says so. A TypeScript host needs a runtime present before it can run — so the thing installed by hand becomes **two** things, and the second must be installed by the means the host exists to replace. ## Considered options 1. **TypeScript, with a runtime installed first.** Simplest, and matches every other repository. Rejected: it breaks the property the tier is built on. A host that cannot run until something else has been installed by hand is not the bottom of the stack. 2. **TypeScript, bundled as a single executable.** Preserves the language and produces one file. Rejected on two grounds: it carries roughly ninety megabytes of runtime to preserve a language choice, and single-executable bundling is a young feature — tier 0 is the worst place in the system to discover its edges. 3. **A statically linked binary in a language built for it.** Chosen; Go. ## Decision **The host is a single statically linked binary that requires nothing to be present.** Copy it onto a machine and run it. That is the whole installation. **It is written in Go.** The job is system-level — run commands, write files, speak to the firewall, the overlay, the service manager and the package manager — which is what Go's ecosystem is for, and it cross-compiles to every architecture the mesh might reach, including the lighter devices requirement 6 anticipates. **The second language costs less here than anywhere else it could appear**, and the reason is architectural rather than convenient. [ADR 0037](0037-the-host-applies-it-does-not-decide.md) means the host never queries the mesh database. [ADR 0039](0039-the-link-is-the-security-boundary.md) means it only ever receives declarations. So the host shares **no code** with any other tier — not a client, not a schema, not the SDK. It is joined to the mesh by a message contract and nothing else. The language boundary therefore falls exactly on an architectural boundary that already exists. A second language usually costs duplicated logic; here there is none to duplicate. ## Consequences - **`how-we-build` §8 needs a scope.** It reads *"TypeScript throughout"*, which was true when everything was a service or a surface. It is now scoped to those, with tier 0 named as the exception and this record as the reason. That is a constitution change, and the sync it owes is part of it. - **Agents must write Go to work on the host.** A real cost, and the one genuine argument against this. It is bounded by the host being the only thing in tier 0 — nothing else in the mesh acquires a second language because of this. - **The dependency-direction lint the design calls for gets easier, not harder.** A Go module cannot accidentally import a TypeScript control-plane client; the boundary is enforced by there being no path across it. - **Cross-compilation replaces per-node builds.** The host is built once per architecture and copied, rather than built on the machine it runs on — which is what makes *"copy it and run it"* true rather than nearly true. - **Two toolchains in the lab.** Scenarios that place a host need a Go build available, and the lab is TypeScript. The binary is built before the scenario runs, not inside it. - **This is reversible at a cost that will only grow.** It is being taken at the moment the first line is written, which is the cheapest point it will ever be taken. ## References - [ADR 0030](0030-the-repository-structure.md) — *the one binary installed by hand*. - [ADR 0037](0037-the-host-applies-it-does-not-decide.md) — why the host shares no code. - [ADR 0039](0039-the-link-is-the-security-boundary.md) — why it receives declarations only. - [`05-the-node-host.md`](../03-DESIGN/01-to-be/05-the-node-host.md) — the design this serves.