diff --git a/README.md b/README.md index 2ad8169..13fa97e 100644 --- a/README.md +++ b/README.md @@ -1,221 +1,224 @@

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

-

Machine Contact Layer

+

Machine Contact Layer (MCL)

A transport-independent layer for machines to meet, and to keep talking.

- CI - License Apache-2.0 - status - C99 freestanding - repos + Open machine-to-machine protocol and portable C99 stack for device discovery, + contact, transport negotiation and communication continuity across BLE, IP + and acoustic links. +

+ +

+ CI status + License: Apache-2.0 + Release status: Public Candidate + Language: freestanding C99

Quickstart · SDK · - What is claimed · - Report a defect + Examples · + Specifications · + Transports · + Security

--- -> ### Building something? Start with the SDK -> -> [**mcl-sdk**](https://github.com/machine-contact-layer/mcl-sdk) has the quickstart and the examples, and the release -> ships a self-contained developer SDK — one CMake project, no sibling checkout. -> This repository is the specification, governance and conformance authority — -> the thing the SDK implements. +MCL lets machines establish contact even when they were built independently, do +not start on the same network, or need to move an existing contact from one +transport to another. It runs on a microcontroller as readily as on a server — +freestanding C99, no heap, no libc — and it leaves your application protocol, +your admission policy and your security stack to you. + +> **Building something?** Start with [**mcl-sdk**](https://github.com/machine-contact-layer/mcl-sdk). +> The release ships a self-contained developer SDK: one CMake project, two +> machines in contact in a few commands. This repository holds the protocol +> specifications, registries and conformance model the SDK implements. -Two machines end up in the same place. They may have been built by different -companies and never designed to work together; or they may both be yours, and -simply have no network in common at this moment. Either way there is no shared -bus, no common credential system, and nobody around to introduce them. +## What MCL solves -**MCL gives them something they can speak first** — a common language available -when no better shared channel exists. What happens after that is yours to decide. +Machine-to-machine communication usually assumes the hard part is already done: +both devices are on the same network, speak the same protocol, and were +configured to find each other. MCL is for when that is not true, or stops being +true. + +- **First contact.** Two devices from different vendors, robots from different + fleets, or an embedded node and a phone need a common way to announce + themselves and describe what they can do. +- **Transport negotiation.** Once they hear each other, they need to agree on a + better bearer — BLE, Wi-Fi/IP — and prove it actually reaches the peer. +- **Transport migration.** A contact that starts on one link needs to continue + on another without resetting the session. +- **Deterministic refusal.** Machines that act in the physical world must reject + unknown, stale or incompatible input rather than guess at it. + +## Where MCL fits ```text -ANOTHER MACHINE - │ acoustic, BLE advertisement, Wi-Fi — whatever medium exists - ▼ -FIRST CONTACT ............ presence, capabilities, hazards - │ - │ optional: negotiate a different transport - ▼ -CONTINUING CONTACT ....... often richer or more private — or still acoustic - │ - ├─▶ STAY ON MCL ......... MCL keeps the contact: presence, capability, - │ migration and refusal. NOT your payloads - ├─▶ SECURITY PROFILE .... optional: establish who you are talking to - └─▶ HAND OFF ............ your own protocol takes over + your application or domain protocol MQTT · ROS 2 · DDS · HTTP · your own + ▲ + │ hand off — or keep the contact on MCL + │ + MACHINE CONTACT LAYER contact · negotiation · migration · refusal + │ + ┌─────────┼──────────┬───────────┐ + BLE IP acoustic UWB (experimental) ``` -Those three endings are alternatives, not stages. A deployment may take any of -them, or more than one, or stop at first contact and never migrate at all. - -MCL is infrastructure for builders. It is not a product, a fleet manager, an -autonomy stack, a credential authority, or a modem. - -## The same layer, configured differently - -A gatekeeper machine at an office entrance, a domestic assistant, and a -warehouse quadruped can all use MCL as their first interaction layer while -agreeing on almost none of their behaviour: - -| | Gatekeeper | House agent | Warehouse quadruped | -|---|---|---|---| -| **First contact** | acoustic | acoustic | acoustic or BLE | -| **Migrates transport** | yes, to verify | rarely | yes, fleet Wi-Fi | -| **Authenticates the peer** | always | for anything privileged | already known peers | -| **Hands off** | to the access system | almost never | to the fleet protocol | -| **Typical ending** | handoff | stay on MCL | handoff | - -None of that is protocol. It is configuration, and it is the deployment's to -choose — Architecture Charter §2.10.1. Differently configured peers stay -interoperable at the frame and semantic layers; they simply refuse each other at -different points, which is a policy outcome rather than an interoperability -failure. - -What you configure: - -- **Which transports** you will speak, and whether you will migrate at all -- **What may be disclosed** at each stage, and over which medium -- **Whether a security profile runs**, and what must pass before it does -- **Which cryptography, if any** — the design rule is that MCL will define the - interface a mechanism plugs into, never the mechanism: you bring your own - stack or your secure element, and MCL never holds a private key. **That - interface does not exist yet.** No `sign`, `verify`, `aead` or credential - lookup callback ships in any repository today -- **Whether you hand off**, or keep the contact on MCL. Keeping it means MCL - continues to carry contact and control objects; it does not mean MCL carries - your application data, and there is no Stable API that would - -## Three ways people use it - -All three are first-class. None is a degraded version of another. - -**Open contact, no security.** Presence, hazard broadcast and capability -discovery in a shared space. You are addressing unknown listeners on purpose, so -authenticating them is not meaningful. The real machine stays behind the MCL -boundary and only MCL talks — which is the point. - -**Machines that already know each other.** Same owner, same fleet, provisioned -at manufacture, or trusted by some means entirely outside MCL. They need a way -to meet when no network is shared, and a way to move to a better one. They do -not need MCL to authenticate anything. - -**Unrelated machines that do need to establish trust.** MCL carries an optional -security profile, so that sensitive material never has to cross the exposed -first-contact medium. Two machines can introduce themselves acoustically, agree -how to reach each other over BLE or Wi-Fi, and complete verification there. - -> Today MCL supports the first two shapes and the transport migration the third -> one needs. **The security profile itself does not exist yet** — no -> cryptography is implemented in any repository. See [`SECURITY.md`](SECURITY.md). - -> **MCL Base 1 is the v1.0 stable floor.** It covers the ordinary case of -> machines that already share a bearer, including provisioned fleets, -> manufacture-paired products and fixed deployments. Discovery, microphone/ -> speaker rendezvous and cryptography are not Base 1 requirements. -> -> **What "communication" means here.** Base 1 establishes, maintains, -> validates, refuses and migrates a contact, and the objects it exchanges are -> the Stable Tier-0 kernel: `PRESENCE`, `TRANSPORT_OFFER`, `TRANSPORT_ACCEPT`. -> It is not a general application payload channel and v1.0 does not ship one. -> An application with its own messages hands off to its own protocol; that is -> the third ending above, not a gap. -> -> **MCL Stranger-Contact 1 extends Base 1.** It provides an optional zero-prior -> ingress path when no bearer is shared. Its AP/BLE profile remains Candidate, -> with the physical evidence and caveats recorded in the release receipt. A -> contact may remain on MCL as a contact, migrate, or be handed to a richer -> protocol. - -## What makes this different from just picking a protocol - -MCL Base 1 is the v1.0 stable floor for contact between machines that already -share a bearer. Stranger-Contact 1 is an optional Candidate ingress profile for -zero-prior rendezvous; it extends Base 1 and does not redefine MCL. A contact -may remain on MCL, migrate, or be handed to a richer protocol. - -`mcl-sdk/examples/base_arranged_bearer.c` is Base 1 end to end: two machines on -a bearer that is already there, Wire major 1 inside Link major 1, no -rendezvous and no bearer to open. - -**A Stranger-Contact deployment requires no prior relationship — Base 1 does -not forbid one.** No shared network, no common PKI, no pairing step someone -performed in a factory. Machines -that already know each other are equally at home here; they just skip the parts -they do not need. - -**Meaning does not depend on the medium.** A `HAZARD` means the same thing -whether it arrived through a loudspeaker, a Bluetooth advertisement, or a UDP -datagram. Transports are bindings; they never redefine semantics. - -**It works without AI.** Every normative object can be produced and consumed by -deterministic software on a microcontroller. Learned systems may map their -internal state to and from MCL objects; they do not define what the bytes mean. - -**Reception is not permission.** MCL keeps these strictly apart: +MCL does not replace MQTT, ROS 2, DDS, HTTP, CAN or your own protocol. It +solves the layer before or alongside them: establishing contact, describing +compatible transport choices, refusing incompatible input, and preserving the +contact while the underlying bearer changes. When the machines are ready, your +protocol takes over — or they stay on MCL, which carries contact and control +objects, not your application payloads. + +## Common use cases + +**Robotics.** Two robots or autonomous machines discover each other, establish +contact, exchange presence and transport offers, and migrate onto a shared +network or hand off to a fleet or robot protocol. + +**Embedded and IoT devices.** Devices built by different vendors use the same +contact layer without a common operating system, runtime or cloud service. The +reference stack needs no OS and no dynamic allocation; a Stable `PRESENCE` is +10 bytes on the wire. + +**Provisioned fleets.** Machines that already know each other and already share +a bearer use `MCL Base 1` directly — no discovery, no pairing step, no +microphone. + +**Offline and degraded networking.** Machines establish contact where normal +infrastructure is absent — over BLE, or acoustically through the speaker and +microphone they already have — and migrate when a better bearer becomes +available. + +**Cross-transport systems.** A contact begins on one supported transport and +continues on another, with the same session and the same meaning for every +object, because transports are bindings and never redefine semantics. + +## How it works ```text -reception ≠ identity ≠ authenticity ≠ authority ≠ trust ≠ obligation +announce PRESENCE over whatever medium exists +agree a bearer TRANSPORT_OFFER / TRANSPORT_ACCEPT +prove it reaches PATH_CHALLENGE / PATH_RESPONSE on the candidate bearer +apply policy admit or refuse decided locally, never by MCL +move COMMIT / CONFIRM the contact continues there +``` + +Your application sees a small event stream: a peer was detected, a policy +decision is needed, a contact is established, a contact was lost. + +- **Meaning does not depend on the medium.** An object means the same thing + whether it arrived through a loudspeaker, a BLE characteristic or a UDP + datagram. +- **Unknown critical input fails loudly.** An unknown opcode, an incompatible + version or a reserved bit set is rejected, never guessed. +- **Reception is not permission.** Receiving a claim establishes that someone + sent it. Your policy decides what it is worth. +- **Deterministic, no AI required.** Every normative object can be produced and + consumed by plain software on a microcontroller. + +MCL has two conformance layers: + +| | What it covers | Maturity | +|---|---|---| +| **MCL Base 1** | Machines that already share a bearer: establish, maintain, validate, refuse and migrate a contact. Wire major 1 inside Link major 1. | Stable | +| **MCL Stranger-Contact 1** | Extends Base 1 with a zero-prior rendezvous path for machines that share no bearer yet. | Candidate | + +## Supported transports + +| Transport | Repository | Profile | Maturity | Run on hardware | +|---|---|---|---|---| +| **IP** (UDP over Wi-Fi/Ethernet) | [mcl-ip](https://github.com/machine-contact-layer/mcl-ip) | IP-DATAGRAM profile 1 | Stable | Windows laptop, ESP32-S3, Android 14 | +| **Bluetooth Low Energy** | [mcl-ble](https://github.com/machine-contact-layer/mcl-ble) | BLE-GATT profile 1 · BLE-ACTIVATE-1 | Stable · Candidate | Windows laptop, ESP32-S3 | +| **Acoustic** (speaker and microphone) | [mcl-ap](https://github.com/machine-contact-layer/mcl-ap) | AP-BOOTSTRAP-1 | Candidate | laptop, ESP32-S3 | +| **Ultra-Wideband** | [mcl-uwb](https://github.com/machine-contact-layer/mcl-uwb) | binding draft | Research Draft | not yet | + +Each binding is freestanding C99 and contains no network, Bluetooth or audio +stack of its own: you connect it to the one your platform already has. + +## Get started + +From the release's developer SDK — one CMake project, no sibling checkout: + +```sh +curl -LO https://github.com/machine-contact-layer/mcl-core/raw/main/releases/v1.0.0/mcl-developer-sdk.tar.gz +tar -xzf mcl-developer-sdk.tar.gz +cmake -S mcl-developer-sdk -B build +cmake --build build +./build/mcl_base_arranged_bearer ``` -A machine that receives an `AUTHORITY_CLAIM` has received a claim. Nothing in -MCL can cause that claim to become authority. Your policy decides, locally, -always. - -**Unknown critical meaning fails loudly.** An unknown opcode, a stale context, -an incompatible version, a reserved bit that should be zero — all rejected, never -guessed. For machines that move in physical space, accepting an ambiguous frame -is worse than dropping a valid one. - -## What MCL is not - -Stated plainly, because scope creep is how interoperability layers die. - -- **Not a robot ontology.** It standardizes the minimum physical-world meaning - unrelated machines need at contact, not a world model. -- **Not an authentication protocol.** MCL can be configured to *carry* one, and - is designed so that strong authentication is possible without sensitive - material crossing an exposed channel. It does not define the exchange and does - not own credential ecosystems. Authentication is a thing MCL can do, not what - MCL is for. -- **Not a mandated sequence.** MCL does not tell you when to disclose what, when - to migrate, or whether to verify anything at all. That is your design. -- **Not obliged to leave.** Handing off to your own protocol is one supported - ending. Remaining as the channel between two machines that share no other - protocol is another, and it is not a lesser one. -- **Not a modem.** MCL-AP is one binding among several. Acoustics is a - deployment-dependent rendezvous medium, not the definition of MCL. -- **Not adopted, not standardized, not stable.** See Status. - -## Start here - -### If you are a builder integrating MCL into a machine - -**Start with [`mcl-sdk/QUICKSTART.md`](https://github.com/machine-contact-layer/mcl-sdk/blob/main/QUICKSTART.md)**, -which goes from a clone to two machines in contact in eight steps. The -integration surface is `mcl/machine.h`: you supply a clock, randomness, a way to -move bytes, a way to open a bearer and a policy answer, and MCL keeps PRESENCE, -contention, OFFER/ACCEPT, activation, path validation and migration. One named -deployment profile, `MCL-REFERENCE-DEPLOYMENT-1`, so nobody has to choose among -equivalent combinations before seeing it work. - -**Then [`mcl-sdk/BUILDER_GUIDE.md`](https://github.com/machine-contact-layer/mcl-sdk/blob/main/BUILDER_GUIDE.md).** -It answers the ten questions in order — install, attach a transport, announce, -hear a peer, migrate, authenticate, trust roots, capabilities, conformance, and -what will change under you — and says plainly where the answer today is "MCL -does not do that yet". - -Then [`spec/core-v0.md`](spec/core-v0.md) for what MCL can say, and -[`../mcl-sdk`](https://github.com/machine-contact-layer/mcl-sdk) for the -developer API. The integration model that matters: +That runs two machines on a bearer they already share: they detect each other, +admit each other by local policy, establish contact, exchange a Stable +`PRESENCE`, and refuse an object the Stable major does not carry. + +To use it from your own CMake project: + +```cmake +find_package(mcl_sdk REQUIRED) +target_link_libraries(my_machine PRIVATE mcl::mcl_sdk) +``` + +## Example + +The integration surface is [`mcl/machine.h`](https://github.com/machine-contact-layer/mcl-sdk/blob/main/include/mcl/machine.h): +you supply a clock and a way to send bytes, feed in what arrives, and poll for +events. MCL keeps the protocol choreography. + +```c +#include "mcl/machine.h" + +/* Your platform: a monotonic clock and a way to put bytes on your bearer. */ +static uint32_t my_clock_ms(void *user); +static int32_t my_send(void *user, uint8_t transport_id, + const uint8_t *data, size_t size); + +void run_contact(void) +{ + mcl_machine_t machine; + mcl_machine_config_t cfg; + mcl_platform_t platform = {0}; + mcl_machine_event_t ev; + + platform.clock_ms = my_clock_ms; + platform.transport_send = my_send; /* 0 sent, <0 not sent, >0 unknown */ + + /* MCL Base 1: two machines that already share a bearer. No discovery. */ + mcl_machine_config_deployment(&cfg, MCL_DEPLOYMENT_BASE_ARRANGED_1, + 0xA1A1A1A1u, MCL_CONTACT_ROLE_INITIATOR); + mcl_machine_init(&machine, &cfg, &platform); + mcl_machine_start(&machine); + + for (;;) { /* call from your main loop or a ~10 ms timer */ + /* Bytes that arrive on your socket, UART or BLE characteristic: + mcl_machine_receive(&machine, transport_id, data, size); */ + + if (mcl_machine_poll(&machine, &ev) != MCL_MACHINE_OK) { + break; + } + if (ev.kind == MCL_MACHINE_EVENT_POLICY_REQUIRED) { + mcl_machine_admit(&machine); /* your policy decides, never MCL */ + } else if (ev.kind == MCL_MACHINE_EVENT_CONTACT_ESTABLISHED) { + /* ev.peer_ref is reachable: stay on MCL, or hand off */ + } + } +} +``` + +- **Full quickstart** → [`mcl-sdk/QUICKSTART.md`](https://github.com/machine-contact-layer/mcl-sdk/blob/main/QUICKSTART.md) +- **Builder guide** → [`mcl-sdk/BUILDER_GUIDE.md`](https://github.com/machine-contact-layer/mcl-sdk/blob/main/BUILDER_GUIDE.md) — transports, migration, capabilities, conformance, what changes under you +- **Examples** → [`mcl-sdk/examples/`](https://github.com/machine-contact-layer/mcl-sdk/tree/main/examples) — Base 1 on a shared bearer, stranger first contact, resource report +- **Porting** → [`mcl-sdk/PORTING.md`](https://github.com/machine-contact-layer/mcl-sdk/blob/main/PORTING.md) + +## Architecture ```text ┌──────────────── YOUR MACHINE ────────────────┐ @@ -227,166 +230,115 @@ developer API. The integration model that matters: │ └─────▲─────┘ │ │ ┌──────────┴──────────┐ │ │ │ MCL boundary │ │ -│ │ contact · security │ │ -│ │ transport · policy │ │ +│ │ contact · transport │ │ │ └───┬──────┬──────┬───┘ │ │ AP BLE IP │ └─────────────┼──────┼──────┼──────────────────┘ └──────┴──────┘ - unknown machines + other machines ``` A peer talks to MCL. It does not talk to your actuators, your CAN bus, your -filesystem, or your fleet credentials — and that holds whether the peer is a -stranger or a machine you own. MCL is a quarantine boundary as much as a -protocol, and in a deployment that never authenticates anyone, the boundary is -doing all of the work. The specification recommends this isolation and deliberately does -not mandate an MPU, TEE, or separate MCU — hardware neutrality outlives any -current hardware. - -### If you are a developer implementing MCL - -The reference stack is **portable freestanding C99**: no OS, no heap, no libc at -runtime, no threads, no hidden globals. The weaker of two peers sets the floor, -and if the reference implementation needed an operating system, MCL would stop -being deployable exactly where contact matters most. - -- [`governance/IMPLEMENTATION_CONTRACT.md`](governance/IMPLEMENTATION_CONTRACT.md) - — the runtime constraints and validation gates that bind reference code -- [`conformance/CONFORMANCE_MODEL.md`](conformance/CONFORMANCE_MODEL.md) - — C0–C6 test classes; there is deliberately no vague "MCL compatible" claim -- [`registries/semantic-codes-v0.2.json`](registries/semantic-codes-v0.2.json) - — machine-readable assigned values - -You do not need our code. You need the specification, the registries, and the -conformance vectors. That is the point — see -[`CONTRIBUTING.md`](CONTRIBUTING.md) for how the reference implementation is -subordinate to the spec. - -### If you are a scientist or researcher - -Two ladders, kept rigorously separate. Conformance (C0–C6) measures whether an -implementation obeys the specification. Evidence (E0–E6) measures how physically -real a result is. **A passing test suite never raises an evidence level, and a -successful over-air trial never raises a conformance level.** +filesystem or your fleet credentials. Everything a deployment chooses is +configuration, not protocol: -```text -E0 analytical E1 simulation E2 recorded replay -E3 controlled over-air E4 multi-device over-air -E5 operational environment E6 independent interoperability -``` - -Every experiment retains raw captures and digests, including the runs that -failed and the ones where our own instruments produced misleading numbers. See -[`../mcl-ap/research/EVIDENCE_LEDGER.md`](https://github.com/machine-contact-layer/mcl-ap) -and the `evidence/` directories in the binding repositories. +- which transports it speaks, and whether it migrates at all +- what it discloses at each stage, and over which medium +- whether it admits a peer, and on what local policy +- whether it hands off to its own protocol or keeps the contact on MCL -## Status - -**MCL v1.0 Release Candidate.** The Stable surface is frozen: Wire major 1, Link major 1, -three Stable Tier-0 objects, two Stable transport profiles with assigned -identifiers, nine Stable Link classes. What v1.0 does and does not cover is -decided in [`governance/V1_SCOPE.md`](governance/V1_SCOPE.md), and the release -gate is [`governance/RELEASE_GATE_V1.md`](governance/RELEASE_GATE_V1.md). -Stable `v1.0.0` promotion awaits the required public external review; public -visibility and disclosure decisions are separate owner-controlled gates. - -| Layer | Implementation | Physical evidence | -|---|---|---| -| Core — semantics | Registries, 2 validators | — | -| Wire — canonical bytes | C99, 7 test targets | — | -| Link — contact and framing | C99, 9 test targets | — | -| SDK — developer API | C99, 5 test targets | **E4** — one contact across 104 changes of medium | -| AP — acoustic | C99 + experiments | **E4** — and the stack itself runs on an ESP32-S3 | -| IP — network | C99, host tool | **E4** — 2.4 GHz UDP, two machines | -| BLE — Bluetooth LE | C99, host tool | **E4** — GATT fragmentation, two machines | -| UWB — ultra-wideband | C99 | none — software binding only | - -Test counts are read from `ctest -N`, not remembered. A count written from -memory has been wrong twice in this project's history, in both directions. - -Two rows deserve a sentence. The SDK row exercised migration between two -machines with **both media live on both peers at once**, which is the only -arrangement in which a contact can actually change medium. The AP row is newer: -`mcl-ap/experiments/008-embedded-node/` runs `mcl-wire`, `mcl-link` and the -acoustic modem **on the microcontroller**, so a frame emitted by a laptop is -acquired, demodulated, verified and decoded to field values by the board itself, -with no host in the loop. - -### What this release claims, and what it does not - -This is the part most likely to be read too generously, so it is stated -plainly. `V1_SCOPE.md` §5.9 is the normative version. - -**Claimed:** - -- Two implementations that share **no code, no language and no build system** - cross-decode in both directions, including matching refusals — the clean-room - implementation in [`conformance/independent/`](conformance/independent/), - C4 803 checks and C5 108 checks on the assigned profile bytes. -- Over-air carriage between physically distinct devices, both directions, on - IP, BLE and acoustic. -- The same source compiled by a **different toolchain for a different - architecture**, running on an embedded target with no heap and no libc, - interoperating over a physical channel with the host. - -**Not claimed:** - -```text -NOT claimed: two ORGANISATIONS have interoperated -NOT claimed: anyone outside this project has implemented these specifications -NOT claimed: anyone outside this project has reviewed them -NOT claimed: the specifications are free of defects a fresh reader would find -``` - -The clean-room implementation is independent *of the reference code* and was -written by the same author. It found three real specification-reading defects, -which is exactly why the last line is written the way it is: a reader who is not -the author will find more. That is what the errata process is for — -[`REPORTING.md`](REPORTING.md). Public external review is required before the -Stable `v1.0.0` tag; later implementation reports may inform v1.1. - -**MCL provides no confidentiality, no cryptographic authenticity, and no peer -authentication.** The two shapes that do not need them — open contact, and -machines that already know each other — are usable today. A deployment that -needs the security profile is waiting on work that has not been done. See -[`SECURITY.md`](SECURITY.md) before assuming otherwise. - -## Repositories - -| | | -|---|---| -| **mcl-core** | semantics, registries, governance, conformance model | -| `mcl-wire` | canonical bytes, deterministic rejection, context and delta | -| `mcl-link` | contact lifecycle, the Link frame, sessions, handoff | -| `mcl-ap` | acoustic binding — the medium that needs no prior network | -| `mcl-ip` | IP binding — datagram and stream carriage | -| `mcl-ble` | BLE binding — fragmentation is the whole problem | -| `mcl-uwb` | UWB binding — ranging as evidence, never as proof | -| `mcl-sdk` | developer API over Core, Wire, Link and the bindings | +Differently configured machines stay interoperable at the frame and semantic +layers; they simply refuse each other at different points. Dependencies run one way: `core → wire → link → bindings → sdk`. A lower layer never redefines a higher layer's meaning. -## Governance - -- [`governance/ARCHITECTURE_CHARTER.md`](governance/ARCHITECTURE_CHARTER.md) — the invariants no future specification may casually violate -- [`governance/IMPLEMENTATION_CONTRACT.md`](governance/IMPLEMENTATION_CONTRACT.md) — runtime constraints binding on reference implementations -- [`governance/SPECIFICATION_PROCESS.md`](governance/SPECIFICATION_PROCESS.md) — maturity, change classes, errata -- [`governance/REGISTRY_POLICY.md`](governance/REGISTRY_POLICY.md) — assigned-number policy -- [`governance/ORGANIZATION_MODEL.md`](governance/ORGANIZATION_MODEL.md) — the multi-party model this is heading toward -- [`governance/PUBLICATION_POLICY.md`](governance/PUBLICATION_POLICY.md) — immutable releases -- [`governance/IPR_PRINCIPLES.md`](governance/IPR_PRINCIPLES.md) — royalty-free implementation direction +## Repository map -The governing rule for all of it: - -> **Freeze only what future implementers must agree on.** +| Repository | What it contains | +|---|---| +| **[mcl-core](https://github.com/machine-contact-layer/mcl-core)** | Machine semantics, protocol specifications, registries, conformance model, governance | +| **[mcl-wire](https://github.com/machine-contact-layer/mcl-wire)** | Canonical binary encoding and deterministic decoding for every MCL object | +| **[mcl-link](https://github.com/machine-contact-layer/mcl-link)** | Machine contact lifecycle, framing, sessions and transport migration | +| **[mcl-sdk](https://github.com/machine-contact-layer/mcl-sdk)** | Portable C99 SDK, examples, porting guide and the developer SDK package | +| **[mcl-ip](https://github.com/machine-contact-layer/mcl-ip)** | IP transport binding: MCL over UDP and other datagram carriers | +| **[mcl-ble](https://github.com/machine-contact-layer/mcl-ble)** | Bluetooth Low Energy transport binding: GATT carriage and role derivation | +| **[mcl-ap](https://github.com/machine-contact-layer/mcl-ap)** | Acoustic transport binding: first contact through a speaker and microphone | +| **[mcl-uwb](https://github.com/machine-contact-layer/mcl-uwb)** | Experimental Ultra-Wideband transport binding | -## Licence +## Compatibility and maturity -Apache-2.0. See [`LICENSE`](LICENSE). +**Public Candidate.** The Stable surface is frozen; the `v1.0.0` tag has not +been cut yet. -The project succeeds when independent builders can implement MCL without copying -our code, exchange the same semantic objects, reject incompatible input -deterministically, and extend it through published processes without -fragmenting the ecosystem. +| Maturity | What it covers | +|---|---| +| **Stable** | Wire major 1 · Link major 1 and its nine frame classes · `PRESENCE`, `TRANSPORT_OFFER`, `TRANSPORT_ACCEPT` · IP-DATAGRAM profile 1 (transport 2) · BLE-GATT profile 1 (transport 3) · `MCL Base 1` · SDK API at source compatibility | +| **Candidate** | `MCL Stranger-Contact 1` · AP-BOOTSTRAP-1 · BLE-ACTIVATE-1 · `HAZARD`, `REQUEST`, `AUTHORITY_CLAIM`, `DEGRADED_STATE` (Wire major 0 only) | +| **Research Draft / Experimental** | UWB binding · the wider IP and BLE binding drafts · profile identifier 192 | + +Two things worth knowing before you integrate: + +- The pre-existing encode calls still emit major 0 for source compatibility. + Use the `_at_major` calls, or the `MCL_DEPLOYMENT_BASE_ARRANGED_1` deployment, + to emit the Stable pair. +- Source compatibility is promised within v1; binary ABI stability is not. + +The per-document status and the full compatibility matrix are in +[`SPECIFICATION_INDEX.md`](SPECIFICATION_INDEX.md). + +## Security model + +**MCL v1.0 provides no confidentiality, no peer authentication, no +cryptographic integrity and no replay protection.** Every byte is in the clear +on every binding, and a completed contact establishes reachability and +correlation — not identity. + +- `frame_check` is a CRC-32. It detects accidental corruption, not tampering. +- A BLE connection or an IP socket says nothing about who the peer is. +- `source_ref` and `session_ref` are correlation references, never identities. + +MCL is cryptography-agnostic: you bring your own security stack, and MCL never +holds a private key. If you need to know who you are talking to, run MCL inside +something that authenticates — DTLS on IP, LE Secure Connections beneath BLE, +a controlled network — or hand off to a protocol that does. v1.0 ships no +security profile of its own. [`SECURITY.md`](SECURITY.md) is specific about +each property and how to report a vulnerability. + +## Specifications and conformance + +- [`SPECIFICATION_INDEX.md`](SPECIFICATION_INDEX.md) — every specification and its maturity +- [`spec/conformance-profiles-v1.md`](spec/conformance-profiles-v1.md) — what `MCL Base 1` and `MCL Stranger-Contact 1` require +- [`deployments/`](deployments/) — the named deployment profiles the SDK implements +- [`conformance/CONFORMANCE_MODEL.md`](conformance/CONFORMANCE_MODEL.md) — test classes C0–C6 +- [`conformance/ICS.md`](conformance/ICS.md) — the implementation conformance statement +- [`registries/`](registries/) — machine-readable assigned values +- [`governance/IMPLEMENTATION_CONTRACT.md`](governance/IMPLEMENTATION_CONTRACT.md) — the runtime constraints on reference code + +You do not need our code to implement MCL: the specifications, registries and +conformance vectors are the contract, and the reference implementation is +subordinate to them. + +**Verification resources.** Conformance (C0–C6) and physical evidence (E0–E6) +are tracked separately. The hardware runs behind the transport table above keep +their raw captures, logs and digests: + +- IP over 2.4 GHz UDP between a laptop and an ESP32-S3, and with an Android 14 handset at Wire and Link major 1 — [`mcl-ip/evidence/`](https://github.com/machine-contact-layer/mcl-ip/tree/main/evidence) +- BLE GATT with fragmentation at the minimum MTU of 23 — [`mcl-ble/evidence/`](https://github.com/machine-contact-layer/mcl-ble/tree/main/evidence) +- One contact carried across 104 BLE/IP changes of medium with both radios live — [`mcl-sdk/evidence/`](https://github.com/machine-contact-layer/mcl-sdk/tree/main/evidence) +- The Wire, Link and acoustic stack decoding over the air on an ESP32-S3 — [`mcl-ap/experiments/`](https://github.com/machine-contact-layer/mcl-ap/tree/main/experiments) +- A second implementation, in a different language, cross-checking the reference C — [`conformance/independent/`](conformance/independent/) +- Every empirical record bound to a path and digest — [`releases/v1.0.0/EVIDENCE_INDEX.json`](releases/v1.0.0/EVIDENCE_INDEX.json) + +## Contributing + +- [`CONTRIBUTING.md`](CONTRIBUTING.md) — how changes are made, and the rules reference code follows +- [`REPORTING.md`](REPORTING.md) — report a defect or a specification error; published corrections are in [`errata/`](errata/) +- [`SECURITY.md`](SECURITY.md) — report a vulnerability +- [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) +- [`governance/`](governance/) — the architecture charter, specification process and registry policy + +## License + +Apache-2.0. See [`LICENSE`](LICENSE), [`NOTICE`](NOTICE) and +[`LICENSING.md`](LICENSING.md). diff --git a/governance/RELEASE_GATE_V1.md b/governance/RELEASE_GATE_V1.md index 8a7db2a..1b10b1c 100644 --- a/governance/RELEASE_GATE_V1.md +++ b/governance/RELEASE_GATE_V1.md @@ -93,9 +93,9 @@ NOT claimed: anyone outside this project has reviewed them NOT claimed: the specifications are free of defects a fresh reader would find ``` -Those four lines appear in `README.md`, `ICS.md`, `V1_SCOPE.md` §5.9 and the -release manifest, in the same words, so a reader cannot find a weaker version by -looking somewhere else. `check-publication-readiness.sh` fails if any of them +Those four lines appear in `ICS.md`, `V1_SCOPE.md` §5.9 and the release +manifest, in the same words, so a reader cannot find a weaker version by looking +somewhere else. `check-publication-readiness.sh` fails if any of them loses the statement. The clean-room implementation is independent *of the reference code* — no shared diff --git a/governance/V1_SCOPE.md b/governance/V1_SCOPE.md index 81fb45b..7b26a8e 100644 --- a/governance/V1_SCOPE.md +++ b/governance/V1_SCOPE.md @@ -692,9 +692,9 @@ Stable v1.0.0 tag; later implementation reports may be tracked as v1.1 errata. One thing: an implementation built by someone else, interoperating. When that happens it is recorded as evidence and the claim widens. Until then the release -says so in `ICS.md`, in `mcl-core/README.md`, and in the release manifest — in -the same words, so a reader cannot find a weaker version of the statement by -looking somewhere else. +says so in `ICS.md`, in this section, and in the release manifest — in the same +words, so a reader cannot find a weaker version of the statement by looking +somewhere else. ### 5.10 The builder-interoperability floor diff --git a/releases/v1.0.0/SHA256SUMS.txt b/releases/v1.0.0/SHA256SUMS.txt index b2ef403..ef6d635 100644 --- a/releases/v1.0.0/SHA256SUMS.txt +++ b/releases/v1.0.0/SHA256SUMS.txt @@ -5,8 +5,8 @@ 98f7edfdb87642f0970f8052d80391188d6d9a6e146e8c9f0636f04c2563adaa *mcl-core/governance/PUBLISHING.md 207eed90edb52ea1b81bafdae5a7c9e7a0a319a63939dd821888e54fb8fb4ec0 *mcl-core/LICENSING.md b2ed5e4adcaa336400cc8cb9c2ee18358682a26a58ca0ff012ed3f637ea8d40f *mcl-core/CONTRIBUTING.md -dfe844e21b6db6673139254355a9ec3c41e2f412a4df1a79578b046ef45b3deb *mcl-core/governance/V1_SCOPE.md -413e26e48b5bfa2fce9a2c587b4c7969fb3a2d443a389dc87d60547c54401624 *mcl-core/governance/RELEASE_GATE_V1.md +331144bea72ed2058cec7e88e3142b43b595983edad147bdb817f12ca8a82f71 *mcl-core/governance/V1_SCOPE.md +6ecd0fbc51e22d54a3ffb780b272c2e42d3fb2ecbe5461a3df8c90e9c46ec073 *mcl-core/governance/RELEASE_GATE_V1.md 24e4369b13bf3b2c635f352cf2fb4ee7dd0270dfe6e475b12feb8ca680d70897 *mcl-core/governance/GOVERNANCE.md 696369d8bc76c3f1b00f3e66622f0e5b404641e008fde80c9bad8635413e0ee2 *mcl-core/governance/ARCHITECTURE_CHARTER.md 3cf85cb41a1efe1e7c75c65a420653cdb0bad0a10324b368604e26db3163b396 *mcl-core/governance/REGISTRY_POLICY.md diff --git a/releases/v1.0.0/manifest.txt b/releases/v1.0.0/manifest.txt index 2cebe65..69f6251 100644 --- a/releases/v1.0.0/manifest.txt +++ b/releases/v1.0.0/manifest.txt @@ -47,9 +47,9 @@ WHAT THIS RELEASE CONTAINS WHAT THIS RELEASE DOES NOT CLAIM - Stated here in the same words as mcl-core/README.md, - conformance/ICS.md and governance/V1_SCOPE.md section 5.9, so that - a reader cannot find a weaker version by looking somewhere else. + Stated here in the same words as conformance/ICS.md and + governance/V1_SCOPE.md section 5.9, so that a reader cannot find + a weaker version by looking somewhere else. NOT claimed: two ORGANISATIONS have interoperated NOT claimed: anyone outside this project has implemented these diff --git a/tools/build-release-bundle.sh b/tools/build-release-bundle.sh index 9b29bdb..b47b36b 100644 --- a/tools/build-release-bundle.sh +++ b/tools/build-release-bundle.sh @@ -485,9 +485,9 @@ printf 'mcl-core/releases/%s/REPRODUCIBILITY.md echo echo "WHAT THIS RELEASE DOES NOT CLAIM" echo - echo " Stated here in the same words as mcl-core/README.md," - echo " conformance/ICS.md and governance/V1_SCOPE.md section 5.9, so that" - echo " a reader cannot find a weaker version by looking somewhere else." + echo " Stated here in the same words as conformance/ICS.md and" + echo " governance/V1_SCOPE.md section 5.9, so that a reader cannot find" + echo " a weaker version by looking somewhere else." echo echo " NOT claimed: two ORGANISATIONS have interoperated" echo " NOT claimed: anyone outside this project has implemented these" diff --git a/tools/check-publication-readiness.sh b/tools/check-publication-readiness.sh index e798e22..0974e67 100644 --- a/tools/check-publication-readiness.sh +++ b/tools/check-publication-readiness.sh @@ -143,9 +143,12 @@ else fi # ----------------------------------------------- 6. the claim boundary is said +# +# The claim boundary lives in the normative and release authorities. README.md +# is the adoption surface and is deliberately not required to carry it. echo -echo "-- the release states what it does NOT claim, in every place a reader looks" -for f in "mcl-core/README.md" "mcl-core/conformance/ICS.md" \ +echo "-- the normative release authorities preserve the claim boundary" +for f in "mcl-core/conformance/ICS.md" \ "mcl-core/governance/V1_SCOPE.md" \ "mcl-core/releases/v1.0.0/manifest.txt"; do if grep -q "NOT claim" "$ROOT/$f" 2>/dev/null; then