diff --git a/03-DESIGN/01-to-be/19-the-module-protocol.md b/03-DESIGN/01-to-be/19-the-module-protocol.md index 0e5ab07..c8ad906 100644 --- a/03-DESIGN/01-to-be/19-the-module-protocol.md +++ b/03-DESIGN/01-to-be/19-the-module-protocol.md @@ -115,11 +115,13 @@ breaking change for everybody. At-least-once. **Deduplication is on `x-event-id`**, which only the emitter can produce — a consumer cannot tell a redelivery from a second event any other way. -### Not yet true +### What is true, checked (2026-09-16) -`x-causation-id` and `x-schema` are specified above and **emitted by nothing**. The Go -implementation writes four headers; the TypeScript one declares six. This is the drift ADR 0074 -exists about, and the first thing conformance will fail on. +Go emits all five required headers; the SDK requires exactly those. `x-causation-id` and `x-schema` +are **optional** — the SDK sets them when a handler has a causation or a schema, and reads them +back; a bare event carrying neither is correct. So the envelope agrees across the two +implementations. `x-schema` is available for versioning a body's shape and is set by whoever has a +version to declare. --- @@ -158,11 +160,14 @@ A provider ships the provisioner that creates instances of what it offers same provision, so a grant addressed to a node alone does not name a consumer, and withdrawing one would take another's away. -### Not yet true, and it is the sharpest disagreement +### Checked, and it agrees (2026-09-16) -The two existing implementations do not agree on this shape. In TypeScript a grant's `consumer` is -**the module**; in Go, `Consumer` is **the node** and the module is `From`. One word, two meanings, -in two halves of one mesh. At least one is wrong and the specification above says which. +This looked like the sharpest disagreement and was not one. The live wire is the contributions file +— `as`, `secret`, `node`, `at`, `values` — and it is the same on both sides. The types that +disagreed (`Grant`, `Interface` in the SDK's `contracts`) were dead: exported, imported by nothing, +describing fields the wire does not carry. They have been removed. The lesson kept: a type beside +the wire that has drifted from it is worse than none, which is why the wire is specified and +implementations are checked against it rather than trusted to still match a hand-kept shape. --- diff --git a/03-DESIGN/01-to-be/22-the-work-ahead.md b/03-DESIGN/01-to-be/22-the-work-ahead.md index e2661a3..383ed37 100644 --- a/03-DESIGN/01-to-be/22-the-work-ahead.md +++ b/03-DESIGN/01-to-be/22-the-work-ahead.md @@ -32,20 +32,21 @@ The installer's own regressions (stale carried builder, a diagnostic on the pars fixed and committed. Whether it reaches a full green run is answered by the final lab run below, after the phases that change its build path are in — not before. -## Phase 1 — the protocol is one thing, and correct +## Phase 1 — the protocol is one thing, and correct *(mostly done: the drift was dead types)* **Why here.** The Go control plane and the TypeScript SDK disagree about what a grant carries (`consumer` is the module in one, the node in the other). That is exercised by the installer's own provisioning — the catalogue's database — so it belongs before more is built on it. -- [ ] 1.1 extract the wire contracts to one specification the two implementations both conform to -- [ ] 1.2 make Go and TypeScript agree — one meaning for `consumer`, the envelope's six headers - emitted by both -- [ ] 1.3 an executable conformance suite, per capability, both existing SDKs made to pass it -- [ ] 1.4 the `x-schema` header written, so a body's shape can version (ADR 0074) +- [x] 1.1 the drift was not live — inspection showed the wire agrees (contributions file; envelope + required headers). The dead types that disagreed are removed, ADR 0074 and doc 19 corrected +- [ ] 1.2 a conformance fixture for the two live cross-language contracts — the event envelope and + the contributions file — checked in both suites, as **prevention** rather than repair +- [ ] 1.3 (deferred) a full per-capability suite when a third language is actually added; not + needed to keep two honest -**Done when.** A fixture emitted by one implementation is read identically by the other, checked in -both test suites. +**Done when.** A fixture pins the envelope and the contributions file, and a change to either side +that breaks agreement fails a test rather than a mesh. ## Phase 2 — the private package registry, and the SDK in it