Renumber the records 1 to 23

The consolidation left a sparse sequence -- 1, 4, 6, 7, 9, 10, 12, 15, 16, 18,
19, 25, 34, 35, 36, 37, 40, 42, 44, 45, 48, 49, 58 -- where the gaps were only
the archaeology of what used to be there.

Renumbered contiguously. Renames run in ascending order, so every target number
is already free and no two files ever collide.

The reference rewrite is one simultaneous pass rather than a sequence of
replacements. Numbers moved into slots other numbers were vacating -- the node
host went 37 to 16 while the lab went 16 to 9 -- so replacing one at a time
would have cascaded and silently pointed things at the wrong record.

Seven plain-text references survived the merges as prose rather than links,
naming records that no longer existed: the enrolment token, the link boundary,
what a declaration is, reachability, the repository structure. Each mapped to
the consolidated record that now holds it.

Verified rather than assumed: every [ADR NNNN](path) link now has matching text
and target, checked across the whole repository, and the checker passes.

Frontmatter `consolidates:` lists dropped -- they named records that are gone,
and each consolidated record already says in prose what it absorbed.
This commit is contained in:
2026-08-28 23:28:34 +02:00
parent 77f3a4cea7
commit e1febe8e0f
84 changed files with 441 additions and 449 deletions
@@ -5,13 +5,13 @@ deciders: jochen
reconstructed: true
---
# 4. Managed files are generated onto nodes and never edited there
# 2. Managed files are generated onto nodes and never edited there
> Reconstructed after the fact from the evidence cited below.
## Context
[ADR 0048](0048-the-substrate-and-the-control-plane.md) put every binding in the mesh
[ADR 0021](0021-the-substrate-and-the-control-plane.md) put every binding in the mesh
database. But the things that consume those bindings — environment files, service
definitions, daemon configuration, firewall rules — are files on a node's disk, because that
is what the software reading them requires.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: true
---
# 6. Schema and state changes are numbered migrations, in the same language as the code
# 3. Schema and state changes are numbered migrations, in the same language as the code
> Reconstructed after the fact from the evidence cited below.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: true
---
# 7. No workspace — each module is a standalone package consuming published dependencies
# 4. No workspace — each module is a standalone package consuming published dependencies
> Reconstructed after the fact from the evidence cited below.
@@ -47,7 +47,7 @@ its dependencies' freshly published versions.
- Development and the pipeline resolve imports identically. The divergence is gone by
construction rather than by discipline.
- A module in its own repository is not a special case. It builds exactly as a module in the
monorepo does — which is what makes [ADR 0010](0010-applications-live-in-their-own-repository.md)
monorepo does — which is what makes [ADR 0006](0006-applications-live-in-their-own-repository.md)
cheap.
- A cross-package change costs a publish-and-consume round trip. This is the real price, paid
on every shared-library change.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: true
---
# 9. The mesh is governed by a constitution, injected where work is decided
# 5. The mesh is governed by a constitution, injected where work is decided
> Reconstructed after the fact from the evidence cited below.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: true
---
# 10. Applications live in their own repository; the monorepo is for the mesh
# 6. Applications live in their own repository; the monorepo is for the mesh
> Reconstructed after the fact from the evidence cited below.
@@ -46,7 +46,7 @@ reject it.
- An application's cadence is its own. It is not reviewed as mesh code and does not queue
behind mesh work.
- The separation is safe **only because** the pipeline and provisioning are identical either
side of it — which [ADR 0007](0007-no-npm-workspace.md) is what makes true. Without
side of it — which [ADR 0004](0004-no-npm-workspace.md) is what makes true. Without
standalone packages this decision would fork the build.
- The monorepo stops being an inventory of the installation, which is a precondition for
publishing anything about it.
@@ -59,6 +59,6 @@ reject it.
- The rule is stated in the governed constitution page authored 2026-07-10, §3, as a
convention violation reviewers must reject.
- [ADR 0015](0015-mesh-brokers-nodes-host-agents-think.md) decision 4 extends this from *new*
- [ADR 0008](0008-mesh-brokers-nodes-host-agents-think.md) decision 4 extends this from *new*
applications to the modules already in the monorepo.
- Knowledge base: `troubleshooting/unregistered-module-source`.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: true
---
# 12. An agent is a persistent employee, not an instance of a pool
# 7. An agent is a persistent employee, not an instance of a pool
> Reconstructed after the fact from the evidence cited below.
@@ -59,7 +59,7 @@ itself is an agent of a kind exempt from the hiring lifecycle.
or another agent is hired — both deliberate acts.
- The transition was not free. Lifecycle columns had to reach every query that selects an
agent, and the ones that were missed failed at the moment of hiring rather than at startup.
- This is the decision [ADR 0015](0015-mesh-brokers-nodes-host-agents-think.md) generalises:
- This is the decision [ADR 0008](0008-mesh-brokers-nodes-host-agents-think.md) generalises:
one kind of participant, differing only in modality.
## References
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: false
---
# 15. The mesh brokers capabilities; nodes host; agents think
# 8. The mesh brokers capabilities; nodes host; agents think
## Context
@@ -182,7 +182,7 @@ existing pipeline. Nothing here requires a flag day, and nothing here is cheap.
- `modules/hal/sdk/src/feature-handlers/index.ts` — `FEATURE_HANDLERS`, the fixed handler
array that makes a feature a singleton per module
- `modules/postgres/tools/index.ts` — the adoption path that rotates a shared credential
- Mediahuis `papa-hq`, ADR 0009 *Composable, independently-shippable modules* — the
- Mediahuis `papa-hq`, ADR 0005 *Composable, independently-shippable modules* — the
constraints that make a unit independently shippable, applicable unchanged to features
- impire.io / soulstream — *the record* as integration substrate, personas over services,
and "cheap awareness and expensive thinking"
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0029, 0031, 0032, 0033]
---
# 16. The lab
# 9. The lab
*Consolidated 2026-08-28 from five records. The lab is one design and was split across five
decisions taken over three days; the reasoning is kept, the fragmentation is not.*
@@ -5,11 +5,11 @@ deciders: jochen
reconstructed: false
---
# 18. The mesh creates no symlinks — a derived file is a copy
# 10. The mesh creates no symlinks — a derived file is a copy
## Context
[ADR 0018](0018-the-mesh-creates-no-symlinks.md) responded to production data loss — a hand-made
[ADR 0010](0010-the-mesh-creates-no-symlinks.md) responded to production data loss — a hand-made
link, resolved through a container engine's volume handling, pointing a mount somewhere it
should not have — by centralising linking in the installer and forbidding it everywhere else.
@@ -24,7 +24,7 @@ Two things have changed since, and together they remove the argument that kept i
silently while the catalogue moves on, so a link was the cheap way to guarantee the running
node reads a current definition. That argument assumes the node's copy is unmanaged.
**It is not.** [ADR 0004](0004-managed-files-are-generated-never-edited.md) established that
**It is not.** [ADR 0002](0002-managed-files-are-generated-never-edited.md) established that
everything on a node's disk is derived from the mesh and regenerated when its inputs change,
and the installer already **reconciles** links rather than assuming them — repointing stale
ones, adopting real files it finds where a link belongs. Reconciling content is the same
@@ -33,7 +33,7 @@ operation as reconciling a pointer, plus a comparison.
So the mesh already has the machinery that makes a copy safe, and is using a link to solve a
problem that machinery solves better. Worse, a link is conceptually the wrong shape: it makes
the node's runtime state a *pointer into source*, which is the one thing
[ADR 0048](0048-the-substrate-and-the-control-plane.md) and ADR 0004 exist to prevent.
[ADR 0021](0021-the-substrate-and-the-control-plane.md) and ADR 0002 exist to prevent.
State is derived onto nodes; it does not reach back.
## Considered options
@@ -53,7 +53,7 @@ State is derived onto nodes; it does not reach back.
**The mesh creates no symlinks.** A file a node needs is placed on that node as a real file,
derived from the mesh and reconciled by the installer like every other managed file
([ADR 0004](0004-managed-files-are-generated-never-edited.md)).
([ADR 0002](0002-managed-files-are-generated-never-edited.md)).
The prohibition in ADR 0011 stands and widens: it ceases to be "only the installer may link"
and becomes "nothing links, the installer included".
@@ -72,7 +72,7 @@ the rule exists at all, and the incident behind it is the reason anyone believes
cost, and it is the whole cost: today a link cannot be stale, and a copy can. The answer has
to be detection — the installer comparing what is on disk against what the mesh says should
be — and it must be loud, because a silently stale definition is exactly the failure shape
this mesh keeps producing ([ADR 0058](0058-delivery.md)).
this mesh keeps producing ([ADR 0023](0023-delivery.md)).
- Reconciliation gets more expensive: comparing content rather than checking a pointer's
target, on every module, on every node.
- Disk usage rises, trivially, and is not a consideration.
@@ -93,8 +93,8 @@ Until those are answered this record stays `proposed`, and ADR 0011 remains the
## References
- [ADR 0018](0018-the-mesh-creates-no-symlinks.md) — the incident, and the rule this widens.
- [ADR 0004](0004-managed-files-are-generated-never-edited.md) — the machinery that makes a
- [ADR 0010](0010-the-mesh-creates-no-symlinks.md) — the incident, and the rule this widens.
- [ADR 0002](0002-managed-files-are-generated-never-edited.md) — the machinery that makes a
copy safe.
- [`03-DESIGN/00-as-is/05-runtime-and-installation.md`](../03-DESIGN/00-as-is/05-runtime-and-installation.md)
— what the installer does today, including reconciliation and adoption.
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0020, 0021, 0022, 0023, 0024, 0026, 0027, 0028, 0030]
---
# 19. How this repository works
# 11. How this repository works
*Consolidated 2026-08-28 from ten records that were one decision seen from ten angles. The
reasoning is kept; the fragmentation is not.*
@@ -37,7 +36,7 @@ company-scoped one does not. So this is `hq` and the mesh's are `mesh-*`.
| `novox/mesh-substrate` | 1 | the pinned tier-1 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` | — | the mesh's own domain ([ADR 0044](0044-modules-and-the-graph.md)) |
| `novox/mesh-sdk` | — | the mesh's own domain ([ADR 0019](0019-modules-and-the-graph.md)) |
| `novox/mesh-lab` | — | the lab: scenario lifecycle, networking, placement |
| `novox/hq` | — | this one |
@@ -5,11 +5,11 @@ deciders: jochen
reconstructed: false
---
# 25. HQ is the source of the mesh constitution
# 12. HQ is the source of the mesh constitution
## Context
[ADR 0009](0009-the-mesh-is-governed-by-a-constitution.md) established a canonical rule set,
[ADR 0005](0005-the-mesh-is-governed-by-a-constitution.md) established a canonical rule set,
injected into every eligible design session and checked before output is accepted. It lives in
the knowledge base, where the orchestrator reads it.
@@ -39,7 +39,7 @@ directly.
Publishing is a playbook step, not a manual act, and it ends with **reading the page back and
verifying the change is present**. A publish that reported success and did nothing is exactly
the failure class this mesh keeps producing
([ADR 0058](0058-delivery.md)).
([ADR 0023](0023-delivery.md)).
Section numbering is stable, because the orchestrator and the review fragments cite sections by
number.
@@ -47,7 +47,7 @@ number.
## Consequences
- One source, many surfaces — the same argument HQ's separation already rests on
([ADR 0019](0019-how-this-repository-works.md)), applied to the rules themselves.
([ADR 0011](0011-how-this-repository-works.md)), applied to the rules themselves.
- Each rule keeps the incident that earned it, in a place that is reviewed as a diff.
- An edit to the derived page survives until the next sync and then vanishes. The playbook says
so, and nothing mechanically prevents it.
@@ -63,5 +63,5 @@ number.
- [`00-META/process/05-constitution-sync.md`](../00-META/process/05-constitution-sync.md) —
the sync, including the read-back.
- [ADR 0009](0009-the-mesh-is-governed-by-a-constitution.md) — the governed page and why it
- [ADR 0005](0005-the-mesh-is-governed-by-a-constitution.md) — the governed page and why it
exists.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: false
---
# 34. A test defends a decision
# 13. A test defends a decision
## Context
@@ -3,16 +3,16 @@ status: accepted
date: 2026-08-24
deciders: jochen
reconstructed: false
extends: 0034-a-test-defends-a-decision.md
extends: 0013-a-test-defends-a-decision.md
---
# 35. A picture of a system is read from the system, never from what asked for it
# 14. A picture of a system is read from the system, never from what asked for it
## Context
A scenario declaration is a file. A raised scenario is a set of machines, links and rulesets.
The two are supposed to correspond, and the entire value of the lab rests on noticing when
they do not — [ADR 0034](0034-a-test-defends-a-decision.md) says a claim nothing checks is a
they do not — [ADR 0013](0013-a-test-defends-a-decision.md) says a claim nothing checks is a
claim that will quietly stop being true.
Drawing a scenario makes that concrete, and forces a choice that looks cosmetic and is not.
@@ -91,8 +91,8 @@ difference read off directly.
## References
- [ADR 0034](0034-a-test-defends-a-decision.md) — a claim nothing checks stops being true.
- [ADR 0016](0016-the-lab.md) — why the lab must not supply what the
- [ADR 0013](0013-a-test-defends-a-decision.md) — a claim nothing checks stops being true.
- [ADR 0009](0009-the-lab.md) — why the lab must not supply what the
mesh is responsible for; the same instinct, applied to facts rather than to configuration.
- [04-ISSUES/003](../04-ISSUES/003-firewall-scope-is-read-by-no-code/00-report.md) — the fault in production
form.
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0038, 0039, 0051]
---
# 36. A node, and how it joins
# 15. A node, and how it joins
*Consolidated 2026-08-28 from four records.*
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0041, 0043, 0047, 0057, 0060, 0061, 0062]
---
# 37. The node host
# 16. The node host
*Consolidated 2026-08-28 from eight records. Tier 0 is one component and was decided over a
week; the reasoning is kept, the fragmentation is not.*
@@ -5,11 +5,11 @@ deciders: jochen
reconstructed: false
---
# 40. The constitution absorbs what is already enforced
# 17. The constitution absorbs what is already enforced
## Context
[ADR 0025](0025-hq-is-the-source-of-the-constitution.md) makes this repository the source
[ADR 0012](0012-hq-is-the-source-of-the-constitution.md) makes this repository the source
and the knowledge base a derived copy, and playbook
[05](../00-META/process/05-constitution-sync.md) publishes the copy whenever a rule changes.
@@ -97,8 +97,8 @@ trusting the second success message either.
## References
- [ADR 0025](0025-hq-is-the-source-of-the-constitution.md) — source and copy.
- [ADR 0009](0009-the-mesh-is-governed-by-a-constitution.md) — why the copy is injected at all.
- [ADR 0012](0012-hq-is-the-source-of-the-constitution.md) — source and copy.
- [ADR 0005](0005-the-mesh-is-governed-by-a-constitution.md) — why the copy is injected at all.
- [Playbook 05](../00-META/process/05-constitution-sync.md) — the sync this record interrupts.
- [ADR 0034](0034-a-test-defends-a-decision.md), [ADR 0035](0035-a-picture-is-read-from-what-runs.md),
[ADR 0018](0018-the-mesh-creates-no-symlinks.md) — the three rules whose sync surfaced this.
- [ADR 0013](0013-a-test-defends-a-decision.md), [ADR 0014](0014-a-picture-is-read-from-what-runs.md),
[ADR 0010](0010-the-mesh-creates-no-symlinks.md) — the three rules whose sync surfaced this.
@@ -5,7 +5,7 @@ deciders: jochen
reconstructed: false
---
# 42. The approval is the checkpoint, not the second pair of hands
# 18. The approval is the checkpoint, not the second pair of hands
## Context
@@ -73,5 +73,5 @@ the previous sync reported success and changed nothing.
## References
- [`how-we-build.md`](../00-META/how-we-build.md) §2 — the rule, now carrying this.
- [ADR 0058](0058-delivery.md) — the standard a checkpoint is held to: a
- [ADR 0023](0023-delivery.md) — the standard a checkpoint is held to: a
step that reports success without doing anything is the fault, not the shortcut.
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0002, 0005, 0017, 0054, 0064, 0065]
---
# 44. Modules and the graph
# 19. Modules and the graph
*Consolidated 2026-08-28 from six records.*
@@ -3,14 +3,14 @@ status: accepted
date: 2026-08-26
deciders: jochen
reconstructed: false
extends: 0044-modules-and-the-graph.md
extends: 0019-modules-and-the-graph.md
---
# 45. A context owns its store, exclusively
# 20. A context owns its store, exclusively
## Context
[ADR 0044](0044-modules-and-the-graph.md) settles what a module
[ADR 0019](0019-modules-and-the-graph.md) settles what a module
declares. This settles what a grant may be, and it is the half that **removes** things.
`how-we-build` §4 already says *contexts integrate through the record, never through a shared
@@ -45,7 +45,7 @@ modules is the mesh showing its own data, not a boundary crossing. What is forbi
### Asking or subscribing is derived, not chosen
[ADR 0036](0036-a-node-and-how-it-joins.md) makes disconnection an ordinary situation. So:
[ADR 0015](0015-a-node-and-how-it-joins.md) makes disconnection an ordinary situation. So:
- **Anything that must keep working while disconnected cannot ask** — there is nobody to ask. It
keeps a local copy, which means subscribing.
@@ -79,7 +79,7 @@ The first clear list of what the design deletes rather than adds:
- **Three contexts must move out of the registry database**, taking thirteen tables with them.
Their dependency on the registry then shrinks to almost nothing — one of them needs a single
table.
- **The node appliers were already handled.** [ADR 0037](0037-the-node-host.md)
- **The node appliers were already handled.** [ADR 0016](0016-the-node-host.md)
stopped the host querying the mesh database for tier reasons unrelated to this, and it removes
most of the remaining direct readers as a side effect.
- **What a consumer does about events missed while disconnected is not decided** — replay from a
@@ -90,4 +90,4 @@ The first clear list of what the design deletes rather than adds:
- [`how-we-build.md`](../00-META/how-we-build.md) §4 — the rule this makes enforceable.
- [Research 011](../01-RESEARCH/011-the-module-graph/worked-provider.md) — the count, the worked
provider, and the dashboard case.
- [ADR 0036](0036-a-node-and-how-it-joins.md) — why asking or subscribing is derived.
- [ADR 0015](0015-a-node-and-how-it-joins.md) — why asking or subscribing is derived.
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0003, 0046, 0053, 0055, 0056]
---
# 48. The substrate and the control plane
# 21. The substrate and the control plane
*Consolidated 2026-08-28 from six records.*
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0050, 0052]
---
# 49. Connectivity
# 22. Connectivity
*Consolidated 2026-08-28 from three records. Overlay, resolution, exposure, filtering and
certificates are one design.*
@@ -3,10 +3,9 @@ status: accepted
date: 2026-08-28
deciders: jochen
reconstructed: false
consolidates: [0008, 0013, 0014, 0063]
---
# 58. Delivery
# 23. Delivery
*Consolidated 2026-08-28 from five records.*
+1 -1
View File
@@ -15,7 +15,7 @@ The records run in the order the decisions were taken, oldest first.
**Every decision is a record.** There is no ledger and no index file — if a decision is worth
recording it is worth a record, and if it is not worth a record it is not recorded
([ADR 0019](0019-how-this-repository-works.md)). A "decision" small enough to be one line is
([ADR 0011](0011-how-this-repository-works.md)). A "decision" small enough to be one line is
almost always a **rule**, and a rule belongs in
[`00-META/how-we-build.md`](../00-META/how-we-build.md), where it is enforced and keeps the
incident that earned it.