Numbers are identity; the reading order is a generated, checked index

Decided after measuring what renumbering actually costs: 96 references in code
comments across two repositories, none of which would have failed to compile.
They would have pointed at the wrong reasoning, which is worse than a broken
link because nothing reports it.

So a number identifies a record and never changes. It cannot also be a
position -- a position moves when the set changes, and an identity that moves
is not one.

The reading order moves into an index generated from each record's `topic:`.
Six topics, in the order somebody learns the system.

The index is WRITTEN rather than only generated on demand, which reverses what
this repository previously said. The reason it said otherwise is that a
hand-written index drifts -- but a reader looking at the folder on a forge sees
the folder, not a command, and the drift objection is answered by checking
rather than by refusing to write one. That is §5's own rule: a rule states how
it is checked.

Two checks, both confirmed to bite. index.py fails when the written order no
longer matches the records. records.py fails when a record has no topic or one
nobody defined -- the quiet failure being a record that vanishes from the order
rather than appearing in the wrong place.
This commit is contained in:
2026-08-28 23:39:18 +02:00
parent 333356cff3
commit b4607dfc03
27 changed files with 234 additions and 9 deletions
@@ -1,4 +1,5 @@
---
topic: the mesh
status: accepted
date: 2026-08-22
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: the mesh
status: accepted
date: 2026-02-25
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: the mesh
status: accepted
date: 2026-07-12
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: the tiers
status: accepted
date: 2026-08-28
deciders: jochen
+1
View File
@@ -1,4 +1,5 @@
---
topic: the tiers
status: accepted
date: 2026-08-28
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: the tiers
status: accepted
date: 2026-08-28
deciders: jochen
+1
View File
@@ -1,4 +1,5 @@
---
topic: the tiers
status: accepted
date: 2026-08-28
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: the tiers
status: accepted
date: 2026-08-26
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: what runs on it
status: accepted
date: 2026-08-28
deciders: jochen
+1
View File
@@ -1,4 +1,5 @@
---
topic: what runs on it
status: accepted
date: 2026-08-28
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: building it
status: accepted
date: 2026-04-03
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: building it
status: accepted
date: 2026-08-23
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: building it
status: accepted
date: 2026-05-14
deciders: jochen
+1
View File
@@ -1,4 +1,5 @@
---
topic: building it
status: accepted
date: 2026-06-04
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: building it
status: accepted
date: 2026-07-10
deciders: jochen
+1
View File
@@ -1,4 +1,5 @@
---
topic: building it
status: accepted
date: 2026-08-28
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: checking it
status: accepted
date: 2026-08-24
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: checking it
status: accepted
date: 2026-08-24
deciders: jochen
+20 -5
View File
@@ -1,4 +1,5 @@
---
topic: how we work
status: accepted
date: 2026-08-28
deciders: jochen
@@ -77,11 +78,25 @@ settled. Everything else belongs in the design document, where the reasoning is
**There is no ledger** — no separate document summarising, ranking or tracking decisions. A
chronological view is generated from frontmatter, which is what a ledger was actually for.
**The numbering is the flow here too.** Records are ordered the way somebody would learn the
system — what the mesh is, then its tiers from the bottom up, then what runs on them and how it
gets there, then how it is built, how it is checked, and how we work. **Not chronologically**: the
date is in the frontmatter and a consolidated record holds decisions taken across a week, so
ordering by age would order by an accident that no longer exists.
**A number identifies a record and never changes.** It is not a position, and it cannot be
both — a position moves when the set changes, and an identity that moves is not one.
That is not a preference. Records are referenced from **outside** this repository: code
comments, commit messages, the knowledge base. Renumbering once cost 96 references across two
code repositories, and nothing in either would have failed to compile — the comments would
simply have pointed at the wrong reasoning, which is worse than a broken link because nothing
reports it.
**So the reading order lives in a generated index**, from each record's `topic:` — what the mesh
is, then its tiers from the bottom up, then what runs on them and how it gets there, then how it
is built, how it is checked, and how we work.
**And the index is written, not only generated on demand.** A reader looking at the folder on a
forge sees the folder, not a command. The objection to a written index is that it drifts, and
that is answered by **checking** it rather than by refusing to write one — which is §5's own
rule: a rule states how it is checked. A record with no topic, or a topic nobody defined, fails
the same check, because the quiet failure is a record that vanishes from the order rather than
appearing in the wrong place.
**The design layer is what you read.** These records explain *why* a thing is as it is. They are
not a description of the system, and needing to read them to understand it would mean the design
@@ -1,4 +1,5 @@
---
topic: how we work
status: accepted
date: 2026-07-10
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: how we work
status: accepted
date: 2026-08-23
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: how we work
status: accepted
date: 2026-08-26
deciders: jochen
@@ -1,4 +1,5 @@
---
topic: how we work
status: accepted
date: 2026-08-26
deciders: jochen
+59 -3
View File
@@ -62,6 +62,62 @@ rather than guessing.
## Index
The index is **generated, not maintained** — run the `hq-status` skill, which reads the
frontmatter of every record. A hand-written index drifts from the folder it describes, and
this one had already done so after a single addition.
**A number identifies a record and never changes.** Records are referenced from outside this
repository — code comments, commit messages — so a number that moves invalidates them silently.
Renumbering once cost 96 references across two code repositories, and that is why the numbers
are now fixed.
So the folder is in creation order, and **the reading order lives here.** It is generated from
each record's `topic:` and written, because a reader looking at the folder on a forge sees the
folder rather than a command. The objection to a written index is that it drifts — which is
answered by checking it rather than by refusing to write one:
```
python3 00-META/checks/index.py --write regenerate
python3 00-META/checks/index.py fail if stale
```
<!-- index:start -->
### What the mesh is
- **0001** — [The mesh brokers capabilities; nodes host; agents think](0001-mesh-brokers-nodes-host-agents-think.md)
- **0002** — [Nodes communicate over a message broker, not over HTTP](0002-nodes-communicate-over-a-broker.md)
- **0003** — [An agent is a persistent employee, not an instance of a pool](0003-agents-are-persistent-employees.md)
### Its tiers, from the bottom up
- **0004** — [A node, and how it joins](0004-a-node-and-how-it-joins.md)
- **0005** — [The node host](0005-the-node-host.md)
- **0006** — [The substrate and the control plane](0006-the-substrate-and-the-control-plane.md)
- **0007** — [Connectivity](0007-connectivity.md)
- **0008** — [A context owns its store, exclusively](0008-a-context-owns-its-store.md)
### What runs on them, and how it gets there
- **0009** — [Modules and the graph](0009-modules-and-the-graph.md)
- **0010** — [Delivery](0010-delivery.md)
### How it is built
- **0011** — [Managed files are generated onto nodes and never edited there](0011-managed-files-are-generated-never-edited.md)
- **0012** — [The mesh creates no symlinks — a derived file is a copy](0012-the-mesh-creates-no-symlinks.md)
- **0013** — [Schema and state changes are numbered migrations, in the same language as the code](0013-schema-changes-are-numbered-migrations.md)
- **0014** — [No workspace — each module is a standalone package consuming published dependencies](0014-no-npm-workspace.md)
- **0015** — [Applications live in their own repository; the monorepo is for the mesh](0015-applications-live-in-their-own-repository.md)
- **0016** — [The lab](0016-the-lab.md)
### How it is checked
- **0017** — [A test defends a decision](0017-a-test-defends-a-decision.md)
- **0018** — [A picture of a system is read from the system, never from what asked for it](0018-a-picture-is-read-from-what-runs.md)
### How we work
- **0019** — [How this repository works](0019-how-this-repository-works.md)
- **0020** — [The mesh is governed by a constitution, injected where work is decided](0020-the-mesh-is-governed-by-a-constitution.md)
- **0021** — [HQ is the source of the mesh constitution](0021-hq-is-the-source-of-the-constitution.md)
- **0022** — [The constitution absorbs what is already enforced](0022-the-constitution-absorbs-what-is-enforced.md)
- **0023** — [The approval is the checkpoint, not the second pair of hands](0023-approval-is-the-checkpoint.md)
<!-- index:end -->