Tier 0: the questions answered, the decisions taken, and the design #9

Merged
jschoubben merged 16 commits from design/close-the-record into main 2026-08-25 22:56:07 +00:00
Owner

Sixteen commits. More than one change, which breaks one change per pull request — recorded here rather than hidden, and merged on an explicit instruction.

Supersedes #8, whose commits are included.

The blocking questions, answered

Research 006 held two open questions that were the tier 0 design, and playbook 04 says an open question is a reason to research rather than to build around.

Is the host too large? Measured against origin/main rather than argued. The absorption is smaller than the machinery that already applies state — 2 755 lines of adapters against 3 059 of meshware, env-sync and config-sync. Eight of ten adapters already receive derived state and only apply it. Two — wireguard and traefik — open a Postgres connection to the control plane, which inside tier 0 is the one thing the tier rule exists to forbid. And the split had already been happening unnamed: dnsmasq-app needs the same node data as wireguard and does not query for it, because hand-duplicated state went wrong once.

So the absorption is a split, not a move. The host carries one concern.

Does an unprivileged node earn a place in the inventory? The question posed a class distinction. There is none — a node is a managed machine, and disconnection is a situation.

Decisions

0036 a node is a managed machine; disconnection is state, not class
0037 the host applies, it does not decide
0038 a node joins by linking first — one behaviour, two sources
0039 the link is the security boundary; a node owns no password
0040 the constitution absorbs what is already enforced
0041 the host depends on nothing that must be installed first

0018, 0034 and 0035 move to accepted; 0011 is superseded by 0018.

What the record now says that it did not

  • The lab has an as-is document, including the parts nobody would choose: that place: was refused so it raised empty machines, that the drawing shipped with no design behind it, and that the integration suite raises two of five scenarios while both faults found so far lived in the three it does not.
  • Research 004 graduates. Its one open item was "not yet stood up".
  • Research 011 opens — the module graph, and the question that decides whether it is progress: what does the graph delete?
  • The node host is designed, staged so each stage is verifiable in the lab before the next exists.

The constitution sync, which went wrong first

Reading the target before overwriting it found the source and the enforced copy had diverged for six weeks. A literal republish would have deleted rules the mesh enforces — the live §4 held SOLID, layering and TypeScript strictness, present in no decision record anywhere.

Removal was not the safe alternative either: the orchestrator reads "when absent, no constitution is injected", so deleting the page would have silently injected nothing.

And the read-back earned its place in the playbook. The first publish reported success and changed nothing — new revision, new title, body dropped silently. §5 demonstrating itself during its own publication.

Left open, deliberately

  • 0017 stays proposed — research 011 will supersede it or leave it standing, and deciding now means deciding twice.
  • What a declaration is. Blocks stage 2, not stage 1.
  • Whether one host can raise the substrate alone — Move 1 assumes it and stage 2 tests it.
  • Nothing detects constitution divergence. Six weeks passed unnoticed; 0040 names it and does not fix it.
Sixteen commits. More than one change, which breaks *one change per pull request* — recorded here rather than hidden, and merged on an explicit instruction. Supersedes #8, whose commits are included. ## The blocking questions, answered Research 006 held two open questions that **were** the tier 0 design, and playbook 04 says an open question is a reason to research rather than to build around. **Is the host too large?** Measured against `origin/main` rather than argued. The absorption is *smaller* than the machinery that already applies state — 2 755 lines of adapters against 3 059 of meshware, env-sync and config-sync. Eight of ten adapters already receive derived state and only apply it. Two — wireguard and traefik — open a Postgres connection to the control plane, which inside tier 0 is the one thing the tier rule exists to forbid. And the split had already been happening unnamed: `dnsmasq-app` needs the same node data as `wireguard` and does not query for it, because hand-duplicated state went wrong once. So the absorption is a **split**, not a move. The host carries one concern. **Does an unprivileged node earn a place in the inventory?** The question posed a class distinction. There is none — a node is a managed machine, and disconnection is a *situation*. ## Decisions | | | |---|---| | 0036 | a node is a managed machine; disconnection is state, not class | | 0037 | the host applies, it does not decide | | 0038 | a node joins by linking first — one behaviour, two sources | | 0039 | the link is the security boundary; a node owns no password | | 0040 | the constitution absorbs what is already enforced | | 0041 | the host depends on nothing that must be installed first | 0018, 0034 and 0035 move to accepted; 0011 is superseded by 0018. ## What the record now says that it did not - **The lab has an as-is document**, including the parts nobody would choose: that `place:` was refused so it raised empty machines, that the drawing shipped with no design behind it, and that the integration suite raises two of five scenarios while both faults found so far lived in the three it does not. - **Research 004 graduates.** Its one open item was *"not yet stood up"*. - **Research 011 opens** — the module graph, and the question that decides whether it is progress: what does the graph *delete*? - **The node host is designed**, staged so each stage is verifiable in the lab before the next exists. ## The constitution sync, which went wrong first Reading the target before overwriting it found the source and the enforced copy had diverged for six weeks. A literal republish would have **deleted rules the mesh enforces** — the live §4 held SOLID, layering and TypeScript strictness, present in no decision record anywhere. Removal was not the safe alternative either: the orchestrator reads *"when absent, no constitution is injected"*, so deleting the page would have silently injected nothing. And the read-back earned its place in the playbook. **The first publish reported success and changed nothing** — new revision, new title, body dropped silently. §5 demonstrating itself during its own publication. ## Left open, deliberately - 0017 stays `proposed` — research 011 will supersede it or leave it standing, and deciding now means deciding twice. - What a declaration is. Blocks stage 2, not stage 1. - Whether one host can raise the substrate alone — Move 1 assumes it and stage 2 tests it. - Nothing detects constitution divergence. Six weeks passed unnoticed; 0040 names it and does not fix it.
jschoubben closed this pull request 2026-08-25 22:56:07 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/hq#9