Drawing a scenario forced a choice that looks cosmetic and is not. A diagram built from the declaration and captioned "as raised" answers "is what is running what I asked for?" with the request, which always agrees with itself. So: a picture captioned as raised reads only the running system, and where the hypervisor does not hold a fact the picture needs, the raise records it on the resource. With the rule that makes the recording worth anything — a behavioural tag is written after the behaviour works, never at creation, because a failed raise leaves wreckage standing and a picture of wreckage must not badge what the wreckage was supposed to be. It earned itself on the first comparison: every VM showed no addresses, because a container's interface carries the device's name and a VM names its own. The two pictures disagreed, so a whole class of machine silently losing its addresses was visible in seconds. §5 of how-we-build gains the general form, marked proposed. The constitution sync is deliberately NOT done — a rule the mesh enforces before a second person agreed to it is what §6 exists to prevent.
237 lines
12 KiB
Markdown
237 lines
12 KiB
Markdown
---
|
|
status: canonical
|
|
updated: 2026-08-23
|
|
derives: knowledge-base constitution page
|
|
decisions:
|
|
- 02-DECISIONS/0009-the-mesh-is-governed-by-a-constitution.md
|
|
---
|
|
|
|
# How we build
|
|
|
|
The rules that hold across the mesh. Short, and each one earned.
|
|
|
|
**This document is the source of the mesh constitution.** The governed page the mesh injects
|
|
into design sessions is *derived* from it, section for section, and carries the rules without
|
|
the reasoning. Never edit that page directly — an edit there survives until the next sync and
|
|
then vanishes, taking its reasoning with it. The sync is playbook
|
|
[`process/05-constitution-sync.md`](process/05-constitution-sync.md), and it is how the claim
|
|
"HQ is the source" is checked.
|
|
|
|
Section numbers are stable. The orchestrator and the review fragments cite them.
|
|
|
|
---
|
|
|
|
## 1. Purpose
|
|
|
|
These are the principles and guardrails every piece of work in the mesh is checked against —
|
|
design sessions, analysis gates, reviews, and agents acting on their own. A rule stated here is
|
|
non-negotiable unless amended per §6.
|
|
|
|
They exist because each was violated first. Where a rule reads as arbitrary, that is a sign the
|
|
incident behind it is not written down, and the fix is to write it down, not to relax the rule.
|
|
|
|
---
|
|
|
|
## 2. Non-negotiables
|
|
|
|
| Rule | What it means |
|
|
|---|---|
|
|
| **Never write to a production database directly** | No insert, update, delete or schema statement executed against production by hand. Schema changes go through numbered migrations; data changes go through application code or the module's own capabilities. Raw statements skip every side effect the proper path has — events, audit, cache invalidation, fan-out. |
|
|
| **Every schema change is a migration** | Numbered, in the module's own language, compiled with it. Both a baseline for a fresh installation *and* an incremental migration for installations that already exist. If code references a column, the migration creating it must exist. [ADR 0006](../02-DECISIONS/0006-schema-changes-are-numbered-migrations.md) |
|
|
| **Never bypass the pipeline** | No manual database edit, no manual restart as a workaround. Fix the cause and deploy. A workaround that works is a workaround that is never removed, and the next person cannot tell the node from its declaration. |
|
|
| **Never create a symlink** | A hand-made link caused production data loss through container volume resolution, and the judgement needed to make a safe exception is exactly the judgement unavailable at the moment it matters. Today the installer owns and reconciles the links the mesh still uses [ADR 0011](../02-DECISIONS/0011-the-installer-owns-linking.md); the intent is that the mesh creates none at all [ADR 0018](../02-DECISIONS/0018-the-mesh-creates-no-symlinks.md). Neither reading permits you to make one. |
|
|
| **Never push directly to the main branch** | Branch, push, review, merge. Every merge is a human checkpoint, without exception — **including in this repository**. A documentation repository is not a lower tier of care; a decision record lands the same way a service does. |
|
|
| **One change per pull request, and never merge your own** | Unrelated improvements bundled together cannot be reviewed or reverted separately. Self-merging removes the checkpoint that is the entire point. |
|
|
| **Never open a pull request unprompted** | A permissions list saying it is allowed is not a request. |
|
|
| **A failed step fails the job** | A sequence that continues past a failure does the next thing in the wrong place. Gate each step on the last. [ADR 0008](../02-DECISIONS/0008-a-failed-step-fails-the-job.md), and §5. |
|
|
|
|
### A failed step must stop the steps after it — how it was earned
|
|
|
|
A worktree creation failed because the branch name collided with an existing namespace. The
|
|
change into that worktree failed too. The copy, the staging and the commit that followed all
|
|
ran in the shared checkout and committed to a local main. The error was printed and scrolled
|
|
past.
|
|
|
|
This is the same shape as the faults the mesh's whole refactor exists to remove: a step
|
|
reported failure, nothing stopped, and the damage happened somewhere nobody was looking.
|
|
|
|
---
|
|
|
|
## 3. Module and infrastructure rules
|
|
|
|
### Manifests
|
|
|
|
- **Never bump a version by hand.** The builder owns versioning. A version change in a diff is
|
|
a defect; revert it.
|
|
- **Features are detected, not declared.** The installer discovers what a module carries from
|
|
what its directory contains. A declared list and the directory it describes drift, and the
|
|
directory is the one that is true.
|
|
- **Every runtime variable is declared.** A variable the module reads and the manifest does not
|
|
declare is invisible to the mesh: it will not be generated, injected, or audited.
|
|
- **Provisioned credentials arrive through declared requirements**, never hardcoded in code,
|
|
compose files or scripts. [ADR 0005](../02-DECISIONS/0005-capabilities-are-provisioned-on-declaration.md)
|
|
- **Never install a package by hand.** A package is declared in the manifest and arrives the
|
|
way every other package does. A hand-installed package is invisible to the mesh: it is not
|
|
declared, not reproduced on the next node, and not present after a rebuild — and the node
|
|
works until it doesn't.
|
|
|
|
### Placement
|
|
|
|
- **Core modules belong to the monorepo** — the runtime, delivery, provisioning, configuration,
|
|
knowledge, and the shared infrastructure the mesh provisions against.
|
|
- **Every standalone application gets its own repository**, with a manifest at its root,
|
|
registered as a build source. Creating an application directory in the monorepo is a
|
|
convention violation and reviewers reject it.
|
|
[ADR 0010](../02-DECISIONS/0010-applications-live-in-their-own-repository.md)
|
|
|
|
### Migrations
|
|
|
|
- Numbered, idempotent, and safe to re-run. Guard every statement.
|
|
- The initial migration is **frozen** once it has run anywhere. Change is a new number.
|
|
- Numbers are unique. A duplicate prefix is a defect, not a style question.
|
|
|
|
### Managed files
|
|
|
|
**A file edited on a node is a bug with a delay on it.** Everything under the mesh's managed
|
|
surface is regenerated from the mesh database; a local edit survives one synchronisation and is
|
|
then silently overwritten, bringing back whatever it fixed. Use the mesh operation that owns
|
|
the value. If unsure whether a file is managed, ask the tooling — the answer is not visible
|
|
from the file. [ADR 0004](../02-DECISIONS/0004-managed-files-are-generated-never-edited.md)
|
|
|
|
---
|
|
|
|
## 4. Naming and boundaries
|
|
|
|
### Name a context after its aggregate, not after a metaphor
|
|
|
|
A context named `agents` owns **Agent**. A *brain* — memory, thoughts, cognition — is something
|
|
an agent **has**: a concept inside the aggregate, not a module.
|
|
|
|
The cost of getting this wrong is visible today. An anatomy name points at the node runtime, so
|
|
the most evocative word in the system names infrastructure; another describes itself as "mesh
|
|
messaging" in its manifest while the anatomy documentation calls it the interactive runtime —
|
|
and it runs on no node at all.
|
|
|
|
Anatomy makes attractive names and poor boundaries. Name the thing the domain calls it.
|
|
|
|
### Group by domain, not by single function
|
|
|
|
A module is a purpose, not a piece of software. Four modules that together constitute "how a
|
|
node is reachable" and cannot be assigned, versioned or replaced as one thing are four
|
|
accidents, not four boundaries.
|
|
[ADR 0017](../02-DECISIONS/0017-modules-outside-the-core-are-grouped-by-domain.md)
|
|
|
|
### Contexts integrate through the record, never through a shared schema
|
|
|
|
Publish to the stream; do not join across a boundary. Today several domains share one
|
|
forty-five-table schema, which is why work belonging to one context keeps having to be
|
|
implemented in another.
|
|
|
|
---
|
|
|
|
## 5. Evidence and verification
|
|
|
|
### Ubiquitous language is checked, not assumed
|
|
|
|
**If a document states a rule about the mesh, it says how the rule is verified.** This
|
|
repository has a documented requirement that every capability-exposing module declare the core
|
|
runtime as a dependency. Zero modules do.
|
|
|
|
An unenforced rule is indistinguishable from a wrong one, and costs more, because people
|
|
believe it.
|
|
|
|
### Behavioural criteria require runtime evidence
|
|
|
|
A criterion of the form *"the script runs"*, *"the endpoint answers"*, or *"the migration
|
|
applied"* is satisfied only when the change has actually been exercised: a real run, a real
|
|
request, a pipeline log, a live query showing the expected result.
|
|
|
|
**Marking a runtime criterion verified from a diff is itself a violation.** A reviewer who
|
|
finds one names the evidence required and returns the work.
|
|
|
|
The reason is the mesh's most consistent failure shape: a green result proves transport, not
|
|
effect. Absence reads as success unless something looked.
|
|
|
|
### A test defends a decision
|
|
|
|
*Proposed — [ADR 0034](../02-DECISIONS/0034-a-test-defends-a-decision.md), pending review.*
|
|
|
|
The rule above applies to prose. It applies to **decisions** too: a decision record states
|
|
something that must be true, and a test asserts it. A decision with no test is one that will
|
|
quietly stop being true, and nobody will learn that from a document.
|
|
|
|
- Structure and logic — what is accepted, what is refused, how a value is derived — is tested
|
|
**first**, because the behaviour is knowable before the code.
|
|
- Behaviour against a real system is tested **alongside**, because it is discovered rather than
|
|
known.
|
|
- **Mocking the boundary is forbidden.** A test that fakes the system under integration asserts
|
|
that the fake behaves as expected.
|
|
- **The gate is blocking.** Green is the definition of done; a change that has not run its tests
|
|
is not finished, whatever the diff looks like.
|
|
|
|
Not test-driven development as a blanket rule — a test written first against undiscovered
|
|
behaviour asserts a guess. The obligation is that every decision has a defender.
|
|
|
|
### A report is read from the system, never from what asked for it
|
|
|
|
*Proposed — [ADR 0035](../02-DECISIONS/0035-a-picture-is-read-from-what-runs.md), pending
|
|
review.*
|
|
|
|
The same rule as the two above, pointed at reporting rather than at verification. **Anything
|
|
that describes the state of the mesh — a status view, an inventory, a diagram, a health
|
|
check — is assembled from the running system.** Assembling it from the intended state produces
|
|
a report that always agrees with itself and can never disagree with reality, which is not a
|
|
report.
|
|
|
|
Where the system does not natively hold a fact the report needs, **the thing that applied the
|
|
fact records it** — and:
|
|
|
|
> **A record of behaviour is written after the behaviour works, never when the resource is
|
|
> created.**
|
|
|
|
Written up front it restates the request in a new place and inherits none of the authority of
|
|
having happened. A failed run leaves its wreckage standing, and a report of that wreckage must
|
|
not describe what the wreckage was supposed to be.
|
|
|
|
This is the production form of the mesh's most expensive fault: a firewall key declared in five
|
|
manifests and read by no code
|
|
([04-ISSUES/003](../04-ISSUES/003-firewall-scope-is-read-by-no-code/00-report.md)). The
|
|
declaration was never wrong. Nothing ever asked the system.
|
|
|
|
### Search the record before forming a hypothesis
|
|
|
|
The first action on any error message, failing service or unexpected behaviour is to search the
|
|
operational memory for the literal error text — before a hypothesis, not after one fails. The
|
|
knowledge base is indexed on symptoms.
|
|
|
|
This fires hardest on *familiar* ground, where a confident trail feels like progress. Two
|
|
entries were each rediscovered from scratch over several hours in a single session because the
|
|
search was skipped. Both were already written down.
|
|
|
|
---
|
|
|
|
## 6. Amendment
|
|
|
|
This document is governed. It does not change by commit message or unilateral decision.
|
|
|
|
1. **Propose** — a change stating what rule is changing, why the current wording is
|
|
inadequate, and what reviewed it.
|
|
2. **Review** — sign-off by reviewers who are not the proposer.
|
|
3. **Record** — the change is a decision and gets a record in [`02-DECISIONS/`](../02-DECISIONS/), because a
|
|
rule the mesh enforces is architecturally significant.
|
|
4. **Sync** — playbook [`process/05-constitution-sync.md`](process/05-constitution-sync.md)
|
|
publishes the derived page. An unsynced rule is a rule the mesh does not enforce, whatever
|
|
this document says.
|
|
|
|
No drive-by edits. Every change traces to a recorded decision.
|
|
|
|
---
|
|
|
|
## 7. Overrides
|
|
|
|
A team or product may define additional constraints that **narrow or tighten** these rules.
|
|
They may never relax them.
|
|
|
|
An override says which rule it tightens, or which gap it fills, and follows the same amendment
|
|
process. Absence of an override means these rules apply unmodified.
|