From 1973af3f181a17d25e88934c7877875dee737fb7 Mon Sep 17 00:00:00 2001 From: 0j0bit Date: Sun, 13 Sep 2026 00:02:40 +0530 Subject: [PATCH 1/3] Make the README a front door instead of a specification cover page Anyone arriving here got "Scope" and "Non-goals" and no way to tell whether this repository was the one they needed, what MCL would look like in their own code, or where to go if it was not. That is the right shape for a reader who already knows what MCL is, and the wrong shape for everyone else. The specification content is unchanged and still here, underneath. What is new sits above it: - the OJOBIT banner, and badges that carry live state -- CI status is the real workflow badge, so it goes red on its own rather than being a decoration - one sentence saying what this repository is for, in plain language - a routing block. Most people should not read a specification to use MCL, they should use mcl-sdk, and the README now says so at the top instead of letting them find out later - a short "why this exists" that gives the reason the layer is shaped this way, rather than restating the scope list immediately below it Maturity is stated on the badge rather than buried: which profiles are Stable, which are Candidate, and -- for mcl-uwb -- that the binding is specified but has never been run on hardware, with a pointer to the bindings that have. A reader deciding what to build on should not have to dig for that. No specification text, normative wording, conformance claim or evidence reference was altered, and no executable source is touched. Co-Authored-By: Claude Opus 5 --- .github/banner.png | Bin 0 -> 8031 bytes README.md | 85 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 .github/banner.png diff --git a/.github/banner.png b/.github/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..0804c293b2f593ba4552b9007983e5dc3eae864e GIT binary patch literal 8031 zcmeHM4OElY8U8?&Vi8nu#VtVHR-DCCw4lguRB+(o&r{l}wFMbUP$c|>3KB^e9Av-- z9Wefq5CLpzdnab zj;p_26%PO|BS(V|y`NEAk2X1VE7RXX&**Y1)s^XNl(siD`yKUrx%^d83_)=qOgVHiw6*So@xL1 zWMICmyEbv5I00|V48|PyQpcyd)paxsyXJci@U}4^Ct?x5B~jix5$=_Fq!qaV)zI$# z4slnqnn4*eM#y5 zEC0fCJeZ|{EM^jII1FMQ$4c5jT zWhFCjBkRBc`f0rMscZ5Y`wVxUQB}Iu8O5a76eK1wxoQfM%_hw;Pty^`42TYfH8Uht zP$*F%%0V2NKp^Z1EEz?=F%{0^qN!=eZK+hM?9yh`R6PhQ3_l#!fL3Ik=iaBT3@DNL z;56P#-RR?x|Kf+r6jMHAI{JTQN}GaBNB?S;V4kMk#auHWIx_!ohTJC+M$wseKBPz= zm$DrvDV&oxKiuJiuZ?Lvx>gc>RM=W2!Wg&}zec@RrFryfi+ZGaYTIO+3w; zzilU&O!(iqqS`ps?ked#AF)B**b60wWuq~rS`l$sYoC&8G!M&mMr&c#7agGvnw3dx#`y^L18h!ZAC>j$;4ob&jPm!(D+!jO%b({MYVe3=T#U0EC0b1wGsCClToxD)L zxux|7#G-B}Q67SEgSq~qhmvtqW@O6u&E8o@>s&J+IvieAmEe_m=K{~ORBi+^^z=dk zZJfMaTUa6rt&?FdJ^S#1YPlbpy^S0xujdluwXUMDdu{#R|0DmrvRTIfz(thhKjc5u zSM4F0>M6O*f>oP=iUMt`XW7kB%H_rBM!ZIb`r>^`Oy?u~++WGVTXQIaslg1_NW~Oq z>8{wpP(hfm8KdFJu{h<-08K+LwAZ}-cAzy^v_ECM3!LM?7I0XsxWvS%MN}0wa7cP- zcR*#NMiV6fY5Q_EL@E2L5{m_tSQ<_$CNI?W;r&?Mjw}tsr(F&&u`1B3aeMD8eSu@b zg6&>Sp|xgZzom?Kwk!1LA}bgK?{P4*0U5&fgr>`okV+=Z$R6~mg;r*gu94|JwOwLt z_MgD`Pw)wNMM{dWiNlM9oGC1Z6n=pjI{b?o0bg|^wga+lK{nFVG{rs}Ls`*&8B~nZ zmYEVEeoS<+43e-F&aq#UciGy^vRKmJd(ddu;?JXecCyKx{wU6tw4$b5s8Z}jgZjrh zv5MX6R5RmgzTO-KJ(|hb8qux(GiEO-zpoV!rX-3G8F#kTDCGxK6NCo!zY232$u2=t7Bxl*^>@ zw=L-ZMc{i``0+OV6^8#rGa2{j{9V-?rfM zq>SJm%20AdY#;dTlj|OV70vY(bF2)NY%l@^juR_{yZ~?ZxNr$O*$i)29hCerZUY;X z@EL^fL`GWJXDOG?GEm~N&ORIsFC~+wl#a)%FBD&{#tVdE$t1lnM5AoRC4_mc7YqIF zAqh}dloApP6|vCO9?TvXD%LZyzs&Pg!yG=0Q`$TIhDMpuVkJ%KTRj;}g$G9?Ewl23 z`?v%KA13~iOw8($1~3gwjtK)hFMXS|pygal6jX^x6JZbRWMgoT+G}Daq0ZVaYiJ3P zGl$t>sBrjqJATpCd+pP68~+mhYznD%VHIH(Sxw>sGOjI8b73Q2Lq>*A{wu)$C#rmz zXgF{8Inx<~y8BVVvkc#vEdMKKT8FJrQ{^2EaPUrqf1LjB-8($z9y~}9Ot$^jJv_~^ zg7%+X8AVgC!50zp3biNw2djZzJ?e~11`b}fHec1jk#4?})E{@N)iu*`{hz(eonUG# Yog$%zFK-sy(=K`RNMvx!;nR8l1YmO`6#xJL literal 0 HcmV?d00001 diff --git a/README.md b/README.md index ad00456..ba15dfb 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,80 @@ -# MCL SDK - -Product-facing reference SDK for the **Machine Contact Layer**. The default -integration is `mcl/machine.h`: the application supplies platform operations -and receives contact events; MCL owns contact/session state, negotiation, -validation, migration, retries, and cleanup. In MCL Base 1 the peers already -share a bearer and discovery is not required. Optional Stranger-Contact adds -zero-prior rendezvous when no bearer is shared. +

+ OJOBIT +

+ +

MCL SDK

+ +

Build a machine that can meet another machine. One CMake project, no heap, no libc.

+ +

+ CI + License Apache-2.0 + C99 freestanding + status +

+ +

+ Quickstart · + Examples · + Specifications · + Report a defect +

+ +--- + +> **This is the repository to start from.** Everything else in the +> organization is the specification MCL is defined by; this is the code you +> link against. + +## Run it in about a minute + +```sh +git clone https://github.com/machine-contact-layer/mcl-sdk +cd mcl-sdk +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build +./build/examples/base_arranged_bearer +``` + +Two machines meet over a bearer they already share, exchange presence, admit +each other by local policy, and refuse an object they are not willing to carry +— `MCL Base 1`, end to end, with no network, no microphone and no pairing step. + +## What using it looks like + +```c +#include "mcl/machine.h" + +mcl_machine_t machine; +mcl_machine_config_t cfg; + +/* Base 1: a bearer you already have. No discovery, no rendezvous. */ +mcl_machine_config_deployment(&cfg, MCL_DEPLOYMENT_BASE_ARRANGED_1, "node-a"); + +mcl_machine_init(&machine, &cfg, &platform); /* you supply tx/rx */ +mcl_machine_start(&machine); + +mcl_machine_event_t ev; +while (mcl_machine_poll(&machine, &ev) == MCL_MACHINE_OK) { + if (ev.kind == MCL_MACHINE_EVENT_PEER_DETECTED) { + mcl_machine_admit(&machine); /* your policy decides */ + } +} +``` + +You provide two functions — send bytes, receive bytes — over whatever you +already have: a socket, a UART, a BLE characteristic, a test harness. MCL never +allocates; every buffer is yours. + +## Where to go next + +| You want to | Go to | +| --- | --- | +| A guided walkthrough | [`QUICKSTART.md`](QUICKSTART.md) | +| More examples | [`examples/`](examples/) | +| Port it to your platform | `QUICKSTART.md` section 07 | +| Know what a byte means | [mcl-wire](https://github.com/machine-contact-layer/mcl-wire) | +| Know what is claimed | [conformance/ICS.md](https://github.com/machine-contact-layer/mcl-core/blob/main/conformance/ICS.md) | The primary reference SDK is a portable C99 implementation designed to run from resource-constrained microcontrollers through embedded systems and hosted applications without changing the protocol contract. From 6fa4af64fd8f95a4a76753f88ee3f4c0846559ab Mon Sep 17 00:00:00 2001 From: 0j0bit Date: Sun, 13 Sep 2026 08:17:16 +0530 Subject: [PATCH 2/3] Correct the adoption front door against verified facts Every claim here was checked before it was written, and three were wrong. - mcl-sdk said to clone it alone and build. A fresh anonymous clone fails to configure, because the repository builds against its sibling specifications. The README now gives both real paths, each verified from anonymous downloads: the release developer SDK archive, one CMake project with no sibling checkout, and the eight repositories cloned side by side. Both configure, build and run the Base 1 example to CONTACT_ESTABLISHED on both sides. - The mcl-sdk snippet passed a string where mcl_machine_config_deployment takes a numeric source reference and a role, and admitted on PEER_DETECTED where the API raises POLICY_REQUIRED. The replacement was compiled with -std=c99 -Wall -Werror against the real headers, linked and run: init and start return MCL_MACHINE_OK with only clock_ms, transport_send and user set, which is what the prose now says Base 1 needs. - mcl-uwb carried a status badge the ICS does not use. The ICS says experimental, so the badge does. Also: the SDK-first callouts no longer call the mcl-sdk repository one CMake project with no sibling checkout, which describes the release developer SDK; mcl-link no longer sets the 104-migration campaign, which carried major-0 traffic, directly beside the Link major 1 Stable claim; the organization profile no longer calls the specifications frozen before the Candidate is sealed. CODEOWNERS prose: @0j0bit and @sed-boi are two accounts controlled by the same project owner. That is account redundancy, not independent two-person review. Owner patterns are unchanged. No specification text, conformance claim, evidence reference or executable source changed. Co-Authored-By: Claude Opus 5 --- .github/CODEOWNERS | 17 +++++++++---- README.md | 61 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 23 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 71a3ebb..c5e2978 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,17 +9,24 @@ # catch-all. # -# WHY THESE PATHS NAME TWO OWNERS AND NOT ONE. +# WHY THESE PATHS NAME TWO ACCOUNTS AND NOT ONE. # # They named only @0j0bit until 2026-09-12. That deadlocks: GitHub does not let # anyone approve their own pull request, and the branch ruleset grants no # bypass to administrators, so a pull request touching one of these paths and # authored by its sole code owner could never be merged by anyone. # -# Both named accounts have write access, which a code owner must have to count. -# These lines currently resolve to the same two people as the catch-all, so -# their present effect is documentary: they record which paths are authorities. -# If the catch-all ever widens, they narrow again on their own. +# @0j0bit and @sed-boi are two GitHub accounts controlled by the SAME project +# owner. Either account may satisfy the code-owner review requirement for a +# change it did not author -- in practice, changes proposed by the +# mcl-release-governor App and reviewed as @0j0bit. This is account redundancy, +# NOT independent two-person review, and nothing here claims separation of +# duties. +# +# Both accounts have write access, which a code owner must have to count. The +# path lines below name the same accounts as the catch-all, so their present +# effect is documentary: they record which paths are authorities. If the +# catch-all ever widens, they narrow again on their own. * @0j0bit @sed-boi diff --git a/README.md b/README.md index ba15dfb..89931a9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

MCL SDK

-

Build a machine that can meet another machine. One CMake project, no heap, no libc.

+

Build a machine that can meet another machine. Freestanding C99: no heap, no libc.

CI @@ -26,19 +26,34 @@ > organization is the specification MCL is defined by; this is the code you > link against. -## Run it in about a minute +## Run it + +**From the release's developer SDK** — one CMake project, no sibling checkout: ```sh -git clone https://github.com/machine-contact-layer/mcl-sdk -cd mcl-sdk -cmake -S . -B build -DCMAKE_BUILD_TYPE=Release +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/examples/base_arranged_bearer +./build/mcl_base_arranged_bearer ``` -Two machines meet over a bearer they already share, exchange presence, admit -each other by local policy, and refuse an object they are not willing to carry -— `MCL Base 1`, end to end, with no network, no microphone and no pairing step. +**From the repositories** — `mcl-sdk` builds against its sibling +specifications, so clone them side by side: + +```sh +for r in mcl-core mcl-wire mcl-link mcl-sdk mcl-ap mcl-ip mcl-ble mcl-uwb; do + git clone https://github.com/machine-contact-layer/$r +done +cmake -S mcl-sdk -B build +cmake --build build +./build/mcl_sdk_base_arranged_bearer +``` + +Either way, two machines meet over a bearer they already share, exchange +presence, admit each other by local policy, and refuse an object they are not +willing to carry — `MCL Base 1`, end to end, with no network, no microphone and +no pairing step. ## What using it looks like @@ -47,23 +62,33 @@ each other by local policy, and refuse an object they are not willing to carry mcl_machine_t machine; mcl_machine_config_t cfg; +mcl_platform_t platform = {0}; -/* Base 1: a bearer you already have. No discovery, no rendezvous. */ -mcl_machine_config_deployment(&cfg, MCL_DEPLOYMENT_BASE_ARRANGED_1, "node-a"); +/* The porting interface: a clock, and a way to put bytes on your bearer. */ +platform.clock_ms = my_clock_ms; +platform.transport_send = my_send; +platform.user = &my_bearer; -mcl_machine_init(&machine, &cfg, &platform); /* you supply tx/rx */ +/* Base 1: a bearer you already have. No discovery, no rendezvous. */ +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); +/* Bytes that arrive on your bearer go in... */ +mcl_machine_receive(&machine, transport_id, data, size); + +/* ...and a regular poll reports what happened. */ mcl_machine_event_t ev; -while (mcl_machine_poll(&machine, &ev) == MCL_MACHINE_OK) { - if (ev.kind == MCL_MACHINE_EVENT_PEER_DETECTED) { - mcl_machine_admit(&machine); /* your policy decides */ - } +if (mcl_machine_poll(&machine, &ev) == MCL_MACHINE_OK && + ev.kind == MCL_MACHINE_EVENT_POLICY_REQUIRED) { + mcl_machine_admit(&machine); /* your policy decides, never MCL */ } ``` -You provide two functions — send bytes, receive bytes — over whatever you -already have: a socket, a UART, a BLE characteristic, a test harness. MCL never +For Base 1 you supply a monotonic clock and a send function, and hand +received bytes to `mcl_machine_receive()` — over whatever bearer you already +have: a socket, a UART, a BLE characteristic, a test harness. MCL never allocates; every buffer is yours. ## Where to go next From f305ac73263385352797a70fc2add80fca18a9ef Mon Sep 17 00:00:00 2001 From: 0j0bit Date: Sun, 13 Sep 2026 08:26:38 +0530 Subject: [PATCH 3/3] Reference the organization banner instead of copying it into every repository check-provenance.sh refuses a binary outside the accounted evidence and experiment locations, and it was right to: eight copies of a brand image in eight release repositories is eight unaccounted binaries, and eight places for one asset to drift. The banner now lives once, in the .github organization-infrastructure repository, and each README references it there. No gate was loosened to make this pass. Co-Authored-By: Claude Opus 5 --- .github/banner.png | Bin 8031 -> 0 bytes README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 .github/banner.png diff --git a/.github/banner.png b/.github/banner.png deleted file mode 100644 index 0804c293b2f593ba4552b9007983e5dc3eae864e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8031 zcmeHM4OElY8U8?&Vi8nu#VtVHR-DCCw4lguRB+(o&r{l}wFMbUP$c|>3KB^e9Av-- z9Wefq5CLpzdnab zj;p_26%PO|BS(V|y`NEAk2X1VE7RXX&**Y1)s^XNl(siD`yKUrx%^d83_)=qOgVHiw6*So@xL1 zWMICmyEbv5I00|V48|PyQpcyd)paxsyXJci@U}4^Ct?x5B~jix5$=_Fq!qaV)zI$# z4slnqnn4*eM#y5 zEC0fCJeZ|{EM^jII1FMQ$4c5jT zWhFCjBkRBc`f0rMscZ5Y`wVxUQB}Iu8O5a76eK1wxoQfM%_hw;Pty^`42TYfH8Uht zP$*F%%0V2NKp^Z1EEz?=F%{0^qN!=eZK+hM?9yh`R6PhQ3_l#!fL3Ik=iaBT3@DNL z;56P#-RR?x|Kf+r6jMHAI{JTQN}GaBNB?S;V4kMk#auHWIx_!ohTJC+M$wseKBPz= zm$DrvDV&oxKiuJiuZ?Lvx>gc>RM=W2!Wg&}zec@RrFryfi+ZGaYTIO+3w; zzilU&O!(iqqS`ps?ked#AF)B**b60wWuq~rS`l$sYoC&8G!M&mMr&c#7agGvnw3dx#`y^L18h!ZAC>j$;4ob&jPm!(D+!jO%b({MYVe3=T#U0EC0b1wGsCClToxD)L zxux|7#G-B}Q67SEgSq~qhmvtqW@O6u&E8o@>s&J+IvieAmEe_m=K{~ORBi+^^z=dk zZJfMaTUa6rt&?FdJ^S#1YPlbpy^S0xujdluwXUMDdu{#R|0DmrvRTIfz(thhKjc5u zSM4F0>M6O*f>oP=iUMt`XW7kB%H_rBM!ZIb`r>^`Oy?u~++WGVTXQIaslg1_NW~Oq z>8{wpP(hfm8KdFJu{h<-08K+LwAZ}-cAzy^v_ECM3!LM?7I0XsxWvS%MN}0wa7cP- zcR*#NMiV6fY5Q_EL@E2L5{m_tSQ<_$CNI?W;r&?Mjw}tsr(F&&u`1B3aeMD8eSu@b zg6&>Sp|xgZzom?Kwk!1LA}bgK?{P4*0U5&fgr>`okV+=Z$R6~mg;r*gu94|JwOwLt z_MgD`Pw)wNMM{dWiNlM9oGC1Z6n=pjI{b?o0bg|^wga+lK{nFVG{rs}Ls`*&8B~nZ zmYEVEeoS<+43e-F&aq#UciGy^vRKmJd(ddu;?JXecCyKx{wU6tw4$b5s8Z}jgZjrh zv5MX6R5RmgzTO-KJ(|hb8qux(GiEO-zpoV!rX-3G8F#kTDCGxK6NCo!zY232$u2=t7Bxl*^>@ zw=L-ZMc{i``0+OV6^8#rGa2{j{9V-?rfM zq>SJm%20AdY#;dTlj|OV70vY(bF2)NY%l@^juR_{yZ~?ZxNr$O*$i)29hCerZUY;X z@EL^fL`GWJXDOG?GEm~N&ORIsFC~+wl#a)%FBD&{#tVdE$t1lnM5AoRC4_mc7YqIF zAqh}dloApP6|vCO9?TvXD%LZyzs&Pg!yG=0Q`$TIhDMpuVkJ%KTRj;}g$G9?Ewl23 z`?v%KA13~iOw8($1~3gwjtK)hFMXS|pygal6jX^x6JZbRWMgoT+G}Daq0ZVaYiJ3P zGl$t>sBrjqJATpCd+pP68~+mhYznD%VHIH(Sxw>sGOjI8b73Q2Lq>*A{wu)$C#rmz zXgF{8Inx<~y8BVVvkc#vEdMKKT8FJrQ{^2EaPUrqf1LjB-8($z9y~}9Ot$^jJv_~^ zg7%+X8AVgC!50zp3biNw2djZzJ?e~11`b}fHec1jk#4?})E{@N)iu*`{hz(eonUG# Yog$%zFK-sy(=K`RNMvx!;nR8l1YmO`6#xJL diff --git a/README.md b/README.md index 89931a9..8b92efc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- OJOBIT + OJOBIT

MCL SDK