From 9729be9b59cc361a4a366e79f85a661e7119e60c Mon Sep 17 00:00:00 2001 From: 0j0bit Date: Sun, 13 Sep 2026 12:46:25 +0530 Subject: [PATCH] Rewrite the README for discovery and adoption Lead with a searchable definition of the Wire codec, what it provides, how to use it, maturity, verification records and related repositories. Remove claim and review-status prose, and give the banner descriptive alt text. Co-Authored-By: Claude Opus 5 --- README.md | 263 +++++++++++++++++++++++------------------------------- 1 file changed, 113 insertions(+), 150 deletions(-) diff --git a/README.md b/README.md index cc3210d..36d49ca 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- OJOBIT + Machine Contact Layer (MCL) banner: black and white checkerboard with the OJOBIT wordmark

MCL Wire

@@ -7,102 +7,97 @@

The exact bytes. One canonical encoding for every MCL object, on every transport.

- CI - License Apache-2.0 - Wire major 1 - C99 freestanding + Canonical binary encoding and deterministic decoding for the Machine Contact + Layer (MCL): a compact, freestanding C99 codec for machine-to-machine messages + on microcontrollers, embedded systems and servers.

- Use the SDK instead · - Specifications · - mcl-link + CI status + License: Apache-2.0 + Wire major 1: Stable + Language: freestanding C99

---- - -> ### Most people should start with the SDK, not here -> -> This repository is a **specification**. If you are building a product, start -> with [**mcl-sdk**](https://github.com/machine-contact-layer/mcl-sdk): its quickstart runs two machines making -> contact, and the release ships a self-contained developer SDK — one CMake -> project, no sibling checkout. Come back here when you need to know exactly -> what a byte means, or when you are writing an independent implementation. +

+ SDK · + MCL overview · + Specifications · + mcl-link · + Report a defect +

-## Why this exists +--- Two machines can only agree on meaning if they first agree, byte for byte, on -representation. MCL Wire is that agreement: one canonical encoding, no -optional orderings, no implementation-defined padding, and the same result on a +representation. MCL Wire is that agreement: one canonical encoding, no optional +orderings, no implementation-defined padding, and the same bytes on a microcontroller and a server. -An encoder that produces different bytes for the same object is wrong, and the -conformance vectors in this repository are how you find out. +It is part of the [Machine Contact Layer](https://github.com/machine-contact-layer/mcl-core), +an open protocol for machine-to-machine discovery, contact and transport +migration across BLE, IP and acoustic links. + +> **Building a product?** Start with [**mcl-sdk**](https://github.com/machine-contact-layer/mcl-sdk), +> which uses this codec for you. Come here when you need to know exactly what a +> byte means, or when you are writing your own implementation. + +## What MCL Wire provides + +- **One canonical encoding** per object. An encoder that produces different + bytes for the same object is wrong, and the conformance vectors say so. +- **Deterministic rejection.** Truncated, non-canonical, out-of-range and + unknown-critical input is refused with an explicit status, never guessed at. +- **Compact fixed layouts.** A Stable `PRESENCE` is 10 bytes; a + `TRANSPORT_OFFER` is 17. +- **A canonical extension envelope** that lets unknown non-critical data be + skipped by exact length. +- **Conformance vectors with field values**, not only lengths and hex, so an + independent implementation can check what it decoded. + +## Stable surface: Wire major 1 + +Wire major 1 is Stable. It carries `PRESENCE`, `TRANSPORT_OFFER` and +`TRANSPORT_ACCEPT` and refuses every other kind: a Candidate object presented +at the Stable major is rejected, not decoded. + +| Object | Maturity | Major 0 bytes | Major 1 bytes | +|---|---|---:|---:| +| `PRESENCE` | Stable | 11 | 10 | +| `TRANSPORT_OFFER` | Stable | 13 | 17 | +| `TRANSPORT_ACCEPT` | Stable | 16 | 16 | +| `HAZARD` | Candidate | 15 | — | +| `REQUEST` | Candidate | 17 | — | +| `AUTHORITY_CLAIM` | Candidate | 14 | — | +| `DEGRADED_STATE` | Candidate | 10 | — | + +Major-1 `PRESENCE` drops `machine_class`, which is why it is one byte shorter. +Major 0 is permanent and never changes. The Candidate objects stay there: their +layouts and vectors are fixed, but their meanings may still change, which is +exactly what a frozen major may not contain. + +**Choosing the major.** `mcl_wire_tier0_encode` still emits major 0, because +v1.0 promises source compatibility. Use `mcl_wire_tier0_encode_at_major` to emit +the Stable major. -**Wire major 1 is Stable.** Major 0 remains for experimental objects; a Stable -major carries only Stable semantics, and the encoder refuses anything else. - -The specification is language-neutral. The v1.0 reference implementation is **portable freestanding C99** so the same byte contract can be used on bare-metal microcontrollers, RTOS targets, larger embedded systems, and hosted systems. +## Build and test -```text -MCL Core semantic object - | - v -MCL Wire -canonical bytes / extensions / future context forms - | - v -MCL Link -contact / state / QoS / binding handoff +```sh +cmake -S . -B build +cmake --build build +ctest --test-dir build --output-on-failure ``` -## Reference implementation contract +The host test suite covers all 65,536 possible common headers, 120,000 seeded +randomized Tier-0 round trips, exact vectors for all seven layouts, one million +randomized decoder inputs under sanitizers, extension-block round trips, +canonicality and buffer-boundary failures, and the published vectors pinned +against the decoder. The library is also compiled freestanding for small ARM +and 32-bit RISC-V targets. -The C reference implementation: +## Common header -- requires no operating system; -- requires no dynamic allocation; -- uses no hidden mutable global protocol state; -- requires no C bitfields or packed-struct serialization; -- encodes and decodes byte and bit positions explicitly; -- uses fixed-width protocol-facing integers; -- returns deterministic status codes; -- compiles with a C99 compiler without language extensions; -- supports freestanding builds with no required libc symbols; -- keeps the wire specification authoritative over the code. - -## Major-0 research and historical subset - -The C reference implements seven Tier-0 layouts: - -- PRESENCE -- HAZARD -- REQUEST -- AUTHORITY_CLAIM -- DEGRADED_STATE -- TRANSPORT_OFFER -- TRANSPORT_ACCEPT - -`TRANSPORT_ACCEPT` is the other half of a transport change. Without it the -offering peer never learns which transport was selected, so two independent -implementations could agree on an offer and then complete nothing — which is -exactly the test for whether something belongs in the specification. - -The layouts are specified bit for bit in -[`spec/tier0-layout-v0.2.md`](spec/tier0-layout-v0.2.md), independently of this -code, and `tools/validate_tier0_layout.c` checks that specification against the -codec on every test run. - -**Layout interoperability is substantially solved; meaning interoperability is -not.** A significant fraction of the primitive field meanings are still -unsettled. The authoritative count is not restated here, because a number -written into prose rots the moment a field closes: it is derived from -[`tier0-fields-v0.1.json`](../mcl-core/registries/tier0-fields-v0.1.json), which -is machine-checked, and printed by the local gate run. Three -of the seven objects are Stable at major 1; see -[`V1_SCOPE.md`](../mcl-core/governance/V1_SCOPE.md). - -It uses the Stable major-1 v0.2 16-bit common header: +Every object begins with a 16-bit header: ```text 4 bits major wire version @@ -112,25 +107,7 @@ It uses the Stable major-1 v0.2 16-bit common header: 1 bit extension-present ``` -The encoded sizes differ where the Stable major-1 body removes `machine_class`; -the table makes both wire majors explicit: - -| Object | Major 0 bytes | Major 1 bytes | -|---|---:|---:| -| PRESENCE | 11 | 10 | -| HAZARD | 15 | — | -| REQUEST | 17 | — | -| AUTHORITY_CLAIM | 14 | — | -| DEGRADED_STATE | 10 | — | -| TRANSPORT_OFFER | 13 | 17 | -| TRANSPORT_ACCEPT | 16 | 16 | - -`TRANSPORT_OFFER` uses an 8-bit transport identifier and is 17 bytes. - -## Canonical extension envelope - -The C reference includes the Candidate/Experimental extension envelope described -in [`spec/tier0-extensions-v0.1.md`](spec/tier0-extensions-v0.1.md): +## Extension envelope ```text extension_key = uvarint((extension_id << 1) | critical) @@ -138,38 +115,30 @@ length = uvarint(value_length) value = exact value bytes ``` -The parser exposes criticality explicitly. Unknown critical meaning is rejected by the semantic layer; unknown non-critical values can be skipped by exact length. Duplicate/out-of-order IDs, non-canonical varints, zero extension IDs, and truncation are rejected. - -## Build and test - -```text -cmake -S . -B build -cmake --build build -ctest --test-dir build --output-on-failure -``` +The parser exposes criticality explicitly. Unknown critical meaning is rejected +by the semantic layer; unknown non-critical values are skipped by exact length. +Duplicate or out-of-order IDs, non-canonical varints, zero extension IDs and +truncation are rejected. No extension IDs are assigned in v1.0: the mechanism +ships and the table is empty by design. -The host test suite currently covers: +## Reference implementation contract -- all 65,536 possible common headers; -- 120,000 seeded randomized Tier-0 round trips; -- exact v0.2 vectors for all seven implemented layouts; -- one million randomized decoder inputs under sanitizer runs; -- 10,000 uvarint round trips; -- 2,000 randomized extension blocks; -- canonicality, truncation, range, and buffer-boundary failures; -- the published extension vectors pinned against the decoder, rather than only - through C arrays, which prove nothing about the JSON an independent - implementation would actually read; -- the Tier-0 body layout specification checked against the codec; -- the source-size benchmark, run as a test so its cases cannot rot. +The C reference implementation: -The protocol library itself is also compiled in freestanding mode for small ARM and 32-bit RISC-V targets during portability checks. +- requires no operating system and no dynamic allocation; +- uses no hidden mutable global protocol state; +- uses no C bitfields or packed-struct serialization; +- encodes and decodes byte and bit positions explicitly, with fixed-width integers; +- returns deterministic status codes; +- compiles with a C99 compiler without language extensions; +- supports freestanding builds with no required libc symbols. -## Source-size benchmark +The specification is authoritative over the code. -`benchmarks/benchmark_source.c` reproduces the retained 41-event source-size study without a hosted-language runtime or serialization dependency. It independently calculates compact JSON, restricted CBOR, and proto3-equivalent scalar wire sizes and validates every MCL event through the C codec. +## Encoded size -The expected means are: +`benchmarks/benchmark_source.c` encodes the same 41-event source set in several +formats, with no hosted runtime or serialization dependency: ```text compact JSON 121.927 B @@ -177,36 +146,30 @@ CBOR string keys 87.439 B CBOR integer keys 26.463 B typed proto3-equivalent 22.488 B MCL fixed Tier-0 15.073 B -historical context candidate 12.073 B ``` -The 12.073-byte number remains a historical established-context research result. It is not delta coding and is not a first-contact encoding. +The retained v0.2 study is in +[`benchmarks/results/source-codec-summary-v0.2.json`](benchmarks/results/source-codec-summary-v0.2.json). -These are the figures the program prints today, and they have moved twice for reasons worth recording. The MCL rows grew when `TRANSPORT_ACCEPT` was added to the codec — a seventh object with its own body raises the mean. The two name-carrying baselines shrank by 9 bytes each when `capability_digest` was renamed to `capability_tag`, because a shorter key costs fewer bytes in any format that spells its field names out. That narrows MCL's own advantage slightly, which is the honest direction to report it in. +## Specifications -`benchmarks/results/source-codec-summary-v0.2.json` is the **retained v0.2 study** and is deliberately not rewritten to match. It records what was measured then. +- [`spec/common-header-v0.2.md`](spec/common-header-v0.2.md) — the 16-bit common header +- [`spec/tier0-layout-v0.2.md`](spec/tier0-layout-v0.2.md) — Tier-0 layouts, bit for bit; `tools/validate_tier0_layout.c` checks it against the codec on every test run +- [`spec/tier0-extensions-v0.1.md`](spec/tier0-extensions-v0.1.md) — the extension envelope +- [`spec/duration-v0.1.md`](spec/duration-v0.1.md) — duration encoding +- [`conformance/vectors/tier0-major1-v1.0.json`](conformance/vectors/tier0-major1-v1.0.json) — the frozen major-1 vectors +- [`registries/extension-ids-v0.1.json`](registries/extension-ids-v0.1.json) — the extension ID registry -## Stable v1.0 status +Per-document maturity is in +[`mcl-core/SPECIFICATION_INDEX.md`](https://github.com/machine-contact-layer/mcl-core/blob/main/SPECIFICATION_INDEX.md). -**Wire major 1 is cut and is part of MCL v1.0.** It carries `PRESENCE`, -`TRANSPORT_OFFER` and `TRANSPORT_ACCEPT` and refuses every other kind: a -Candidate object presented at the Stable major is rejected, not decoded. Major-1 -`PRESENCE` drops `machine_class`, so it is 10 bytes where major 0 is 11. The -frozen bytes are [`vectors/tier0-major1-v1.0.json`](vectors/tier0-major1-v1.0.json), -which records expected **field values** and not only lengths and hex — a -clean-room implementation once passed a length check while misreading every -field after `source_ref`. +## Related repositories -`mcl_wire_tier0_encode` still emits major 0, because v1.0 promises source -compatibility. Use `mcl_wire_tier0_encode_at_major` to choose. +[mcl-core](https://github.com/machine-contact-layer/mcl-core) (semantics and +registries) · [mcl-link](https://github.com/machine-contact-layer/mcl-link) +(framing, sessions, migration) · [mcl-sdk](https://github.com/machine-contact-layer/mcl-sdk) +(developer SDK) -Major 0 is permanent and does not change. `HAZARD`, `REQUEST`, -`AUTHORITY_CLAIM` and `DEGRADED_STATE` stay there: their layouts and vectors -exist, their *meanings* may still change, and that is exactly what a frozen -major may not contain. +## License -Passing the local C tests is implementation evidence, not independent -interoperability or field validation. What independent evidence exists is -`mcl-core/conformance/independent/` — a clean-room implementation sharing no -code, no language and no build system — and v1.0 does not claim that anyone -outside this project has implemented or reviewed these specifications. +Apache-2.0. See [`LICENSE`](LICENSE).