ADR 0030: the repository structure, and the rule that names them
The tiers were settled and the product was named, but the repositories themselves existed only in a research sketch. That had already caused two problems. ADR 0029 makes the lab phase 0 of the migration and could not say where it lives, because no record named a repository. And the sketch contradicted an accepted record: it listed mesh-hq while ADR 0028 had decided novox/hq and explicitly rejected that name. A design resting on research is resting on something that can change without a decision. Corrected in the research too. The naming rule, which both earlier records implied and neither stated: a repository belonging to a product carries that product's prefix; a company-scoped one does not. That is why this repository is hq and the mesh's are mesh-*. Seven repositories recorded — host, substrate, control, surfaces, sdk, lab, and this one. The lab gets its own: it ships to nobody, outlives any single tier, and drives virtualisation on a workstation, which nothing else does. Inside the host it would couple development tooling to a shipped component; inside the control plane the bootstrap scenario would depend on a tier that does not exist when it is needed. Tier 4 is deliberately not decided. Whether the catalogue is one repository, one per domain or one per application stays open from ADR 0015 and is blocked on research 005 — how many repositories hold domains cannot be answered before knowing what the domains are. mesh-catalog appears in the sketch and is not decided by this record. The cost is stated rather than glossed: seven release cadences where there is one, and cross-repository changes that used to be one commit.
This commit is contained in:
@@ -18,6 +18,23 @@ and a forge address is an operational detail (see [`README`](../README.md)).
|
|||||||
| `hq` | This repository, under the company organisation — mission, research, design, decisions, issue diagnosis. Company-scoped ([ADR 0028](../02-DECISIONS/0028-hq-is-company-scoped.md)); the mesh is its first product. The source of truth for *why*. Carries no implementation. |
|
| `hq` | This repository, under the company organisation — mission, research, design, decisions, issue diagnosis. Company-scoped ([ADR 0028](../02-DECISIONS/0028-hq-is-company-scoped.md)); the mesh is its first product. The source of truth for *why*. Carries no implementation. |
|
||||||
| *(one per application)* | Every standalone application, site or side-project gets its own repository, with `module.yml` at the root. Registered with the mesh as a build source; built and deployed by the same pipeline as anything in the monorepo. |
|
| *(one per application)* | Every standalone application, site or side-project gets its own repository, with `module.yml` at the root. Registered with the mesh as a build source; built and deployed by the same pipeline as anything in the monorepo. |
|
||||||
|
|
||||||
|
## What the mesh becomes
|
||||||
|
|
||||||
|
[ADR 0030](../02-DECISIONS/0030-the-repository-structure.md) records the repositories the
|
||||||
|
monorepo decomposes into. **None exist yet** — they are the target, not the present.
|
||||||
|
|
||||||
|
| Repository | Tier | Holds |
|
||||||
|
|---|---|---|
|
||||||
|
| `mesh-host` | 0 | the node host — the one binary installed by hand |
|
||||||
|
| `mesh-substrate` | 1 | the four pinned services, as declarations |
|
||||||
|
| `mesh-control` | 2 | the control plane and its contexts |
|
||||||
|
| `mesh-surfaces` | 3 | tools, web, cli |
|
||||||
|
| `mesh-sdk` | — | contracts shared across tiers |
|
||||||
|
| `mesh-lab` | — | the lab — built first, per [ADR 0029](../02-DECISIONS/0029-the-labs-first-scenario-has-no-pipeline.md) |
|
||||||
|
|
||||||
|
Tier 4's shape is open, and deliberately so: see ADR 0030 and
|
||||||
|
[research 005](../01-RESEARCH/005-domain-grouping/00-overview.md).
|
||||||
|
|
||||||
## What lives where inside the monorepo
|
## What lives where inside the monorepo
|
||||||
|
|
||||||
Named by role, because the layout is itself part of the as-is design — see
|
Named by role, because the layout is itself part of the as-is design — see
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ mesh-surfaces/ TIER 3
|
|||||||
mesh-catalog/ TIER 4
|
mesh-catalog/ TIER 4
|
||||||
<domain>/<module>/ layout as above
|
<domain>/<module>/ layout as above
|
||||||
|
|
||||||
mesh-lab/ mesh-sdk/ mesh-hq/
|
mesh-lab/ mesh-sdk/ hq/ (company-scoped — ADR 0028)
|
||||||
```
|
```
|
||||||
|
|
||||||
## What this does not settle
|
## What this does not settle
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ mesh-catalog/ TIER 4 — what the mesh hosts
|
|||||||
|
|
||||||
mesh-lab/ the whole mesh, disposable, on one machine
|
mesh-lab/ the whole mesh, disposable, on one machine
|
||||||
mesh-sdk/ contracts shared across tiers — types, not behaviour
|
mesh-sdk/ contracts shared across tiers — types, not behaviour
|
||||||
mesh-hq/ this repository
|
|
||||||
|
hq/ company-scoped, not a mesh repository — ADR 0028
|
||||||
```
|
```
|
||||||
|
|
||||||
## The dependency rule
|
## The dependency rule
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ enough to state directly.
|
|||||||
a lab node is a virtual machine, and the scale argument for system containers was found to
|
a lab node is a virtual machine, and the scale argument for system containers was found to
|
||||||
have been invented rather than required. The design text did not follow the decision. It does
|
have been invented rather than required. The design text did not follow the decision. It does
|
||||||
now.
|
now.
|
||||||
|
- The lab's home is `novox/mesh-lab`, recorded in
|
||||||
|
[ADR 0030](0030-the-repository-structure.md) — written after this record, because this one
|
||||||
|
needed a repository that no decision had yet named.
|
||||||
- The bootstrap scenario's fidelity is its whole value, and also its risk: if it diverges from
|
- The bootstrap scenario's fidelity is its whole value, and also its risk: if it diverges from
|
||||||
how a real node is raised, it certifies something that does not happen. That is the same
|
how a real node is raised, it certifies something that does not happen. That is the same
|
||||||
hazard the existing design names for the full scenario, and the same answer applies —
|
hazard the existing design names for the full scenario, and the same answer applies —
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
status: accepted
|
||||||
|
date: 2026-08-23
|
||||||
|
deciders: jochen
|
||||||
|
reconstructed: false
|
||||||
|
---
|
||||||
|
|
||||||
|
# 30. The repository structure, and the rule that names them
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The tiers are settled ([research 006](../01-RESEARCH/006-mesh-from-scratch/code-skeleton.md))
|
||||||
|
and the product is named ([ADR 0027](0027-the-product-is-novox-mesh.md)), but the repositories
|
||||||
|
themselves were only ever sketched in research. Two consequences had already appeared.
|
||||||
|
|
||||||
|
[ADR 0029](0029-the-labs-first-scenario-has-no-pipeline.md) makes the lab phase 0 of the entire
|
||||||
|
migration and **could not say where it lives**, because no record named a repository.
|
||||||
|
|
||||||
|
And the research contradicted an accepted record: it listed `mesh-hq` for this repository, while
|
||||||
|
[ADR 0028](0028-hq-is-company-scoped.md) had decided `novox/hq` and explicitly rejected that
|
||||||
|
name. A design resting on research is a design resting on something that can change without a
|
||||||
|
decision.
|
||||||
|
|
||||||
|
There is also an implied naming rule that has never been written down. ADR 0027 says
|
||||||
|
repository names take `mesh`; ADR 0028 gives this repository no prefix at all. Both are right,
|
||||||
|
for a reason neither states.
|
||||||
|
|
||||||
|
## Considered options
|
||||||
|
|
||||||
|
Only the naming rule had genuine alternatives; the tier repositories follow from the tiers.
|
||||||
|
|
||||||
|
1. **No prefix — `novox/host`, `novox/control`.** The organisation already says Novox, so the
|
||||||
|
prefix reads as stutter. Rejected once it was established that Novox delivers more than the
|
||||||
|
mesh: with several products the prefix is not stutter, it is the product namespace doing
|
||||||
|
real work, and the forge has no nested groups to do it instead.
|
||||||
|
2. **An organisation per product — `novox-mesh/host`.** Puts the product boundary where the
|
||||||
|
forge's only real grouping primitive lives, so permissions and teams attach to it. Rejected
|
||||||
|
for now as premature: no per-product access boundary exists yet, and it costs `novox-`
|
||||||
|
repeated across every organisation.
|
||||||
|
3. **Product-prefixed repositories in the company organisation.** Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
**The naming rule:** a repository that belongs to a product carries that product's prefix. A
|
||||||
|
repository that is company-scoped does not.
|
||||||
|
|
||||||
|
That is why this one is `hq` and the mesh's are `mesh-*`. Both records were already correct;
|
||||||
|
the rule connecting them is stated here.
|
||||||
|
|
||||||
|
**The repositories:**
|
||||||
|
|
||||||
|
| Repository | Tier | Holds |
|
||||||
|
|---|---|---|
|
||||||
|
| `novox/mesh-host` | 0 | the node host — the one binary installed by hand |
|
||||||
|
| `novox/mesh-substrate` | 1 | the four pinned services, as declarations |
|
||||||
|
| `novox/mesh-control` | 2 | the control plane and its contexts |
|
||||||
|
| `novox/mesh-surfaces` | 3 | tools, web, cli — thin, no logic |
|
||||||
|
| `novox/mesh-sdk` | — | contracts shared across tiers: types, not behaviour |
|
||||||
|
| `novox/mesh-lab` | — | the lab: scenario lifecycle, networking, placement |
|
||||||
|
| `novox/hq` | — | this repository. Company-scoped ([ADR 0028](0028-hq-is-company-scoped.md)) |
|
||||||
|
|
||||||
|
**The lab is its own repository.** Its lifecycle differs from everything else in the list: it
|
||||||
|
is never shipped to a node, it outlives any single tier, and it drives virtualisation on a
|
||||||
|
workstation — which nothing else in the mesh does. Putting it inside the host would couple
|
||||||
|
development tooling to a shipped component; putting it inside the control plane would make the
|
||||||
|
bootstrap scenario depend on a tier that does not exist when it is needed.
|
||||||
|
|
||||||
|
**Tier 4 is deliberately not decided here.** Whether the catalogue is one repository, one per
|
||||||
|
domain, or one per application remains open from
|
||||||
|
[ADR 0015](0015-mesh-brokers-nodes-host-agents-think.md) and is blocked on
|
||||||
|
[research 005](../01-RESEARCH/005-domain-grouping/00-overview.md): how many repositories hold
|
||||||
|
domains cannot be answered before what the domains are. Recording the gap is the point —
|
||||||
|
`mesh-catalog` appears in the research sketch and is **not** decided by this record.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- [ADR 0029](0029-the-labs-first-scenario-has-no-pipeline.md) can name its target. Phase 0 has
|
||||||
|
a home, which was the immediate blocker.
|
||||||
|
- The research sketch stops being load-bearing. It remains what it is — a sketch — and the
|
||||||
|
design layer can now cite a record instead.
|
||||||
|
- **Seven repositories where there is currently one**, for a mesh that today lives in a single
|
||||||
|
monorepo. That is the cost, and it is not small: seven release cadences, seven sets of
|
||||||
|
dependencies, and cross-repository changes that were previously one commit. The offsetting
|
||||||
|
argument is the tier rule — a boundary that only points downward is enforceable across
|
||||||
|
repositories and merely conventional inside one.
|
||||||
|
- The prefix will read as redundant for as long as the mesh is the only product with
|
||||||
|
repositories. That is accepted deliberately: the alternative is renaming everything at the
|
||||||
|
moment a second product appears, which is the class of migration this project is trying to
|
||||||
|
stop performing.
|
||||||
|
- Nothing is created yet. This records what the repositories *are*; creating them is part of
|
||||||
|
phase 0 and after.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [ADR 0027](0027-the-product-is-novox-mesh.md) — the product name the prefix comes from.
|
||||||
|
- [ADR 0028](0028-hq-is-company-scoped.md) — why this repository has no prefix.
|
||||||
|
- [ADR 0029](0029-the-labs-first-scenario-has-no-pipeline.md) — the lab, and why it is first.
|
||||||
|
- [Research 006](../01-RESEARCH/006-mesh-from-scratch/code-skeleton.md) — the tiers, and the
|
||||||
|
sketch this supersedes as a source.
|
||||||
Reference in New Issue
Block a user