Jochen: a normal application has 3-5 ADRs, maybe 10 for a large one, and we are at 65. Fair, and the cause is mine -- I recorded every FINDING as a decision rather than every fork in the road. Two merges, both cases where one decision had been split across many records because it was taken over several days rather than at once. 0019 absorbs ten records about how this repository works: what it is and that it is public, the folder flow, the two design layers, the issue front door, status in frontmatter, playbooks, the naming rule, the product name. Those were never ten decisions -- they were one, seen from ten angles as the repository took shape. 0016 absorbs the five about the lab: a node is a virtual machine, a router is scenery, a scenario declares the underlay, a scenario is a closed address space, and the two scenario classes. Same pattern -- one design, split by the order it was worked out in. The consolidated 0019 also raises the bar for what earns a record, since that is what produced 65: a record is warranted when there is a genuine fork -- a direction reversed, an alternative that will be proposed again, something contested. A finding is not a decision, and a bug is certainly not. Everything else belongs in the design document where the reasoning is actually read. The checker earned its place here. Deleting nine records left 13 dangling links across the repository and it named every one, including in AGENTS.md. Nothing was found by reading. Remaining clusters worth the same treatment: the host (8 records), delivery (5), modules (6), connectivity (4), substrate and control plane (4). That would be 52 down to roughly 30.
4.0 KiB
status, updated
| status | updated |
|---|---|
| canonical | 2026-08-23 |
The Novox repositories
The map of where implementation lives. Humans use it for orientation; agents use it for issue
triage (playbook process/03-issues.md). The code: frontmatter
field in design documents points at entries here.
Repository names are recorded; hosts, URLs and owners are not — this repository is public,
and a forge address is an operational detail (see README).
| Repository | Owns |
|---|---|
hal |
The monorepo — the node runtime, the module catalogue, the delivery machinery, and the bootstrap scripts. Every core module lives here. |
hq |
This repository, under the company organisation — mission, research, design, decisions, issue diagnosis. Company-scoped (ADR 0019); 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. |
What the mesh becomes
ADR 0019 records the repositories the
monorepo decomposes into. mesh-lab and mesh-host exist so far — the lab is built first
(ADR 0016); the rest are the
target, not the present.
| Repository | Tier | Holds |
|---|---|---|
mesh-host |
0 | exists. The node host — one statically linked binary, requiring nothing present (ADR 0041) |
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 |
— | exists. The lab — scenario lifecycle, networking, placement. Ships to nobody; runs on a workstation. |
Tier 4's shape is open, and deliberately so: see ADR 0030 and research 005.
What lives where inside the monorepo
Named by role, because the layout is itself part of the as-is design — see
03-DESIGN/00-as-is/.
| Area | Holds |
|---|---|
| Module catalogue | One directory per module, each with a manifest. Core modules sit under the mesh's own namespace; everything else at the top level. |
| Node runtime | The daemon and interactive runtime that every node runs. |
| Bootstrap scripts | First-node initialisation, joining an existing mesh, and node rescue. |
| Shared library | The SDK every module builds against. |
| Pipeline test harness | End-to-end coverage of the delivery pipeline. Currently unbuildable — see 04-ISSUES/005. |
Why applications do not live in the monorepo
A standalone application in the monorepo is a convention violation, and reviewers reject it.
The reasoning is recorded in 02-DECISIONS/0010:
the mesh installs, provisions for, and ships an application through exactly the same machinery
whether or not its source sits beside the mesh's own — so co-location buys nothing and costs
the monorepo's review cadence.
There is no npm workspace
Each module is a standalone package that consumes its dependencies from the private registry,
not from a sibling directory. The workspace was removed after it caused build-versus-development
divergence — a workspace member importing another resolved to local unbuilt source in the
pipeline and to a published version in development. Recorded in
02-DECISIONS/0007.
Consequence, and it is a real one: a cross-package change is two steps — publish, then consume
— and a repository-wide npm install does not exist.