Glossary, the mesh-controller/foundation vocabulary, ADR 0076, Phase 3 closed #43

Merged
jschoubben merged 32 commits from issue/047-the-other-half into main 2026-09-16 21:25:51 +00:00
Showing only changes of commit a40595fa08 - Show all commits
@@ -19,16 +19,24 @@ There is already more than one. **The contracts are expressed twice** — as Go
plane and the host, and as TypeScript types in the SDK — and nobody has felt it because both live
in one repository and one head.
**They already disagree.** Not in some future where a second language is added; today:
**A correction, made after inspecting the wire rather than the types** (2026-09-16). This record
first claimed the two implementations already disagreed — `resource` vs `Provision`, `consumer`
meaning the module in one and the node in the other, headers declared on one side and emitted by
neither. **On inspection the live wire agrees**, and the claim was wrong:
| | TypeScript | Go |
|---|---|---|
| the provision's field | `resource` | `Provision` |
| what `consumer` means | **the module** | **the node**; the module is `From` |
| event headers | six, including `x-causation-id` and `x-schema` | four — the other two are never written |
- The grant types that disagreed (`Grant`, `Interface`, `Credential` in the SDK's `contracts`)
were **dead** — exported and imported by nothing. The live provisioning wire is the contributions
file, whose shape (`as`, `secret`, `node`, `at`, `values`) is the same on both sides. Those dead
types have been removed.
- The envelope agrees too: Go emits all five required headers, and `x-causation-id`/`x-schema` are
**optional** — the SDK sets them when a handler has a causation or a schema, and a bare event
carrying neither is correct, not a drift.
So one word means two things in the two halves of one mesh, and the header that exists so a body's
shape can change without silent misreads is declared on one side and emitted by neither.
So the danger was never live disagreement. It was **dead types that contradicted the live wire**,
which read as the contract and were not — and are exactly what led this record to assert a drift
that inspection did not find. That is a sharper reason for the decision below, not a weaker one: a
type is only as good as its being the wire, and the way to guarantee that is to specify the wire and
check implementations against it, rather than to trust a hand-kept type to still describe it.
A failure of this kind does not announce itself. Two implementations that disagree about an
envelope do not fail to compile — they ignore each other's messages, and a mesh where a module
@@ -144,9 +152,10 @@ pieces, rather than believed.
with a version on the body is what lets a mesh hold a module built against an older SDK, which is
the ordinary state of any mesh that has been running for a while.
**The two current implementations will be found wrong.** They disagree, so at least one is. Fixing
that is the point rather than a cost, but it is not free: something is emitting or expecting
something it should not.
**The two current implementations agree on the live wire** — inspection showed it. What was wrong
was a set of dead types beside the wire, now removed. The suite's job here is therefore prevention:
to keep that agreement true as the wire changes, and to hold a new language's SDK to it, rather than
to repair a break that exists today.
**This does not make the mesh polyglot by itself**, and should not be reported as though it does. It
makes polyglot possible to do correctly. A Rust SDK is still a Rust SDK.